^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2009 Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/backlight.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/rfkill.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct cmpc_accel {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) int sensitivity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) int g_select;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) int inputdev_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define CMPC_ACCEL_DEV_STATE_CLOSED 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define CMPC_ACCEL_DEV_STATE_OPEN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define CMPC_ACCEL_SENSITIVITY_DEFAULT 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define CMPC_ACCEL_G_SELECT_DEFAULT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define CMPC_ACCEL_HID "ACCE0000"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define CMPC_ACCEL_HID_V4 "ACCE0001"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define CMPC_TABLET_HID "TBLT0000"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define CMPC_IPML_HID "IPML200"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define CMPC_KEYS_HID "FNBT0000"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * Generic input device code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) typedef void (*input_device_init)(struct input_dev *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static int cmpc_add_acpi_notify_device(struct acpi_device *acpi, char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) input_device_init idev_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct input_dev *inputdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) inputdev = input_allocate_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (!inputdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) inputdev->name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) inputdev->dev.parent = &acpi->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) idev_init(inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) error = input_register_device(inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) input_free_device(inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) dev_set_drvdata(&acpi->dev, inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static int cmpc_remove_acpi_notify_device(struct acpi_device *acpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct input_dev *inputdev = dev_get_drvdata(&acpi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) input_unregister_device(inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * Accelerometer code for Classmate V4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static acpi_status cmpc_start_accel_v4(acpi_handle handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) union acpi_object param[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct acpi_object_list input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) param[0].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) param[0].integer.value = 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) param[1].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) param[1].integer.value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) param[2].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) param[2].integer.value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) param[3].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) param[3].integer.value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) input.count = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) input.pointer = param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) status = acpi_evaluate_object(handle, "ACMD", &input, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static acpi_status cmpc_stop_accel_v4(acpi_handle handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) union acpi_object param[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct acpi_object_list input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) param[0].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) param[0].integer.value = 0x4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) param[1].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) param[1].integer.value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) param[2].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) param[2].integer.value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) param[3].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) param[3].integer.value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) input.count = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) input.pointer = param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) status = acpi_evaluate_object(handle, "ACMD", &input, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static acpi_status cmpc_accel_set_sensitivity_v4(acpi_handle handle, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) union acpi_object param[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct acpi_object_list input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) param[0].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) param[0].integer.value = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) param[1].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) param[1].integer.value = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) param[2].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) param[2].integer.value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) param[3].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) param[3].integer.value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) input.count = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) input.pointer = param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return acpi_evaluate_object(handle, "ACMD", &input, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static acpi_status cmpc_accel_set_g_select_v4(acpi_handle handle, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) union acpi_object param[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct acpi_object_list input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) param[0].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) param[0].integer.value = 0x05;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) param[1].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) param[1].integer.value = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) param[2].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) param[2].integer.value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) param[3].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) param[3].integer.value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) input.count = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) input.pointer = param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return acpi_evaluate_object(handle, "ACMD", &input, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static acpi_status cmpc_get_accel_v4(acpi_handle handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) int16_t *x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) int16_t *y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) int16_t *z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) union acpi_object param[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct acpi_object_list input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int16_t *locs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) param[0].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) param[0].integer.value = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) param[1].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) param[1].integer.value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) param[2].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) param[2].integer.value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) param[3].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) param[3].integer.value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) input.count = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) input.pointer = param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) status = acpi_evaluate_object(handle, "ACMD", &input, &output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (ACPI_SUCCESS(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) union acpi_object *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) obj = output.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) locs = (int16_t *) obj->buffer.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) *x = locs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) *y = locs[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) *z = locs[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) kfree(output.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static void cmpc_accel_handler_v4(struct acpi_device *dev, u32 event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (event == 0x81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) int16_t x, y, z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) status = cmpc_get_accel_v4(dev->handle, &x, &y, &z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (ACPI_SUCCESS(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct input_dev *inputdev = dev_get_drvdata(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) input_report_abs(inputdev, ABS_X, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) input_report_abs(inputdev, ABS_Y, y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) input_report_abs(inputdev, ABS_Z, z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) input_sync(inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static ssize_t cmpc_accel_sensitivity_show_v4(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct acpi_device *acpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) struct input_dev *inputdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct cmpc_accel *accel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) acpi = to_acpi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) inputdev = dev_get_drvdata(&acpi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) accel = dev_get_drvdata(&inputdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return sprintf(buf, "%d\n", accel->sensitivity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static ssize_t cmpc_accel_sensitivity_store_v4(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct acpi_device *acpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct input_dev *inputdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct cmpc_accel *accel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) unsigned long sensitivity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) acpi = to_acpi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) inputdev = dev_get_drvdata(&acpi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) accel = dev_get_drvdata(&inputdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) r = kstrtoul(buf, 0, &sensitivity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /* sensitivity must be between 1 and 127 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (sensitivity < 1 || sensitivity > 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) accel->sensitivity = sensitivity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) cmpc_accel_set_sensitivity_v4(acpi->handle, sensitivity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return strnlen(buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static struct device_attribute cmpc_accel_sensitivity_attr_v4 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .attr = { .name = "sensitivity", .mode = 0660 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .show = cmpc_accel_sensitivity_show_v4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .store = cmpc_accel_sensitivity_store_v4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static ssize_t cmpc_accel_g_select_show_v4(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct acpi_device *acpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct input_dev *inputdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) struct cmpc_accel *accel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) acpi = to_acpi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) inputdev = dev_get_drvdata(&acpi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) accel = dev_get_drvdata(&inputdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return sprintf(buf, "%d\n", accel->g_select);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static ssize_t cmpc_accel_g_select_store_v4(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct acpi_device *acpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct input_dev *inputdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct cmpc_accel *accel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) unsigned long g_select;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) acpi = to_acpi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) inputdev = dev_get_drvdata(&acpi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) accel = dev_get_drvdata(&inputdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) r = kstrtoul(buf, 0, &g_select);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /* 0 means 1.5g, 1 means 6g, everything else is wrong */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (g_select != 0 && g_select != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) accel->g_select = g_select;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) cmpc_accel_set_g_select_v4(acpi->handle, g_select);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return strnlen(buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static struct device_attribute cmpc_accel_g_select_attr_v4 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) .attr = { .name = "g_select", .mode = 0660 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) .show = cmpc_accel_g_select_show_v4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) .store = cmpc_accel_g_select_store_v4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static int cmpc_accel_open_v4(struct input_dev *input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct acpi_device *acpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct cmpc_accel *accel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) acpi = to_acpi_device(input->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) accel = dev_get_drvdata(&input->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) cmpc_accel_set_sensitivity_v4(acpi->handle, accel->sensitivity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) cmpc_accel_set_g_select_v4(acpi->handle, accel->g_select);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (ACPI_SUCCESS(cmpc_start_accel_v4(acpi->handle))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) accel->inputdev_state = CMPC_ACCEL_DEV_STATE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static void cmpc_accel_close_v4(struct input_dev *input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct acpi_device *acpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct cmpc_accel *accel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) acpi = to_acpi_device(input->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) accel = dev_get_drvdata(&input->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) cmpc_stop_accel_v4(acpi->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) accel->inputdev_state = CMPC_ACCEL_DEV_STATE_CLOSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static void cmpc_accel_idev_init_v4(struct input_dev *inputdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) set_bit(EV_ABS, inputdev->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) input_set_abs_params(inputdev, ABS_X, -255, 255, 16, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) input_set_abs_params(inputdev, ABS_Y, -255, 255, 16, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) input_set_abs_params(inputdev, ABS_Z, -255, 255, 16, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) inputdev->open = cmpc_accel_open_v4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) inputdev->close = cmpc_accel_close_v4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static int cmpc_accel_suspend_v4(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) struct input_dev *inputdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) struct cmpc_accel *accel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) inputdev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) accel = dev_get_drvdata(&inputdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (accel->inputdev_state == CMPC_ACCEL_DEV_STATE_OPEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return cmpc_stop_accel_v4(to_acpi_device(dev)->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static int cmpc_accel_resume_v4(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct input_dev *inputdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct cmpc_accel *accel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) inputdev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) accel = dev_get_drvdata(&inputdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (accel->inputdev_state == CMPC_ACCEL_DEV_STATE_OPEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) cmpc_accel_set_sensitivity_v4(to_acpi_device(dev)->handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) accel->sensitivity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) cmpc_accel_set_g_select_v4(to_acpi_device(dev)->handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) accel->g_select);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (ACPI_FAILURE(cmpc_start_accel_v4(to_acpi_device(dev)->handle)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) static int cmpc_accel_add_v4(struct acpi_device *acpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) struct input_dev *inputdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct cmpc_accel *accel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) accel = kmalloc(sizeof(*accel), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (!accel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) accel->inputdev_state = CMPC_ACCEL_DEV_STATE_CLOSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) accel->sensitivity = CMPC_ACCEL_SENSITIVITY_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) cmpc_accel_set_sensitivity_v4(acpi->handle, accel->sensitivity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) error = device_create_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) goto failed_sensitivity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) accel->g_select = CMPC_ACCEL_G_SELECT_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) cmpc_accel_set_g_select_v4(acpi->handle, accel->g_select);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) error = device_create_file(&acpi->dev, &cmpc_accel_g_select_attr_v4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) goto failed_g_select;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) error = cmpc_add_acpi_notify_device(acpi, "cmpc_accel_v4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) cmpc_accel_idev_init_v4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) goto failed_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) inputdev = dev_get_drvdata(&acpi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) dev_set_drvdata(&inputdev->dev, accel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) failed_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) device_remove_file(&acpi->dev, &cmpc_accel_g_select_attr_v4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) failed_g_select:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) failed_sensitivity:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) kfree(accel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static int cmpc_accel_remove_v4(struct acpi_device *acpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) device_remove_file(&acpi->dev, &cmpc_accel_g_select_attr_v4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return cmpc_remove_acpi_notify_device(acpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) static SIMPLE_DEV_PM_OPS(cmpc_accel_pm, cmpc_accel_suspend_v4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) cmpc_accel_resume_v4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) static const struct acpi_device_id cmpc_accel_device_ids_v4[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {CMPC_ACCEL_HID_V4, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {"", 0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static struct acpi_driver cmpc_accel_acpi_driver_v4 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) .name = "cmpc_accel_v4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) .class = "cmpc_accel_v4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) .ids = cmpc_accel_device_ids_v4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) .ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) .add = cmpc_accel_add_v4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) .remove = cmpc_accel_remove_v4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) .notify = cmpc_accel_handler_v4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) .drv.pm = &cmpc_accel_pm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * Accelerometer code for Classmate versions prior to V4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static acpi_status cmpc_start_accel(acpi_handle handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) union acpi_object param[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) struct acpi_object_list input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) param[0].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) param[0].integer.value = 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) param[1].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) input.count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) input.pointer = param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) status = acpi_evaluate_object(handle, "ACMD", &input, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static acpi_status cmpc_stop_accel(acpi_handle handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) union acpi_object param[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct acpi_object_list input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) param[0].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) param[0].integer.value = 0x4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) param[1].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) input.count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) input.pointer = param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) status = acpi_evaluate_object(handle, "ACMD", &input, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) static acpi_status cmpc_accel_set_sensitivity(acpi_handle handle, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) union acpi_object param[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct acpi_object_list input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) param[0].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) param[0].integer.value = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) param[1].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) param[1].integer.value = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) input.count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) input.pointer = param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return acpi_evaluate_object(handle, "ACMD", &input, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) static acpi_status cmpc_get_accel(acpi_handle handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) unsigned char *x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) unsigned char *y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) unsigned char *z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) union acpi_object param[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) struct acpi_object_list input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) unsigned char *locs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) param[0].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) param[0].integer.value = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) param[1].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) input.count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) input.pointer = param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) status = acpi_evaluate_object(handle, "ACMD", &input, &output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (ACPI_SUCCESS(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) union acpi_object *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) obj = output.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) locs = obj->buffer.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) *x = locs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) *y = locs[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) *z = locs[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) kfree(output.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static void cmpc_accel_handler(struct acpi_device *dev, u32 event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (event == 0x81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) unsigned char x, y, z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) status = cmpc_get_accel(dev->handle, &x, &y, &z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (ACPI_SUCCESS(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct input_dev *inputdev = dev_get_drvdata(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) input_report_abs(inputdev, ABS_X, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) input_report_abs(inputdev, ABS_Y, y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) input_report_abs(inputdev, ABS_Z, z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) input_sync(inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) static ssize_t cmpc_accel_sensitivity_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) struct acpi_device *acpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct input_dev *inputdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) struct cmpc_accel *accel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) acpi = to_acpi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) inputdev = dev_get_drvdata(&acpi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) accel = dev_get_drvdata(&inputdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return sprintf(buf, "%d\n", accel->sensitivity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) static ssize_t cmpc_accel_sensitivity_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct acpi_device *acpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) struct input_dev *inputdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct cmpc_accel *accel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) unsigned long sensitivity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) acpi = to_acpi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) inputdev = dev_get_drvdata(&acpi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) accel = dev_get_drvdata(&inputdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) r = kstrtoul(buf, 0, &sensitivity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) accel->sensitivity = sensitivity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) cmpc_accel_set_sensitivity(acpi->handle, sensitivity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) return strnlen(buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) static struct device_attribute cmpc_accel_sensitivity_attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) .attr = { .name = "sensitivity", .mode = 0660 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) .show = cmpc_accel_sensitivity_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) .store = cmpc_accel_sensitivity_store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) static int cmpc_accel_open(struct input_dev *input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct acpi_device *acpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) acpi = to_acpi_device(input->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (ACPI_SUCCESS(cmpc_start_accel(acpi->handle)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) static void cmpc_accel_close(struct input_dev *input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) struct acpi_device *acpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) acpi = to_acpi_device(input->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) cmpc_stop_accel(acpi->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) static void cmpc_accel_idev_init(struct input_dev *inputdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) set_bit(EV_ABS, inputdev->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) input_set_abs_params(inputdev, ABS_X, 0, 255, 8, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) input_set_abs_params(inputdev, ABS_Y, 0, 255, 8, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) input_set_abs_params(inputdev, ABS_Z, 0, 255, 8, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) inputdev->open = cmpc_accel_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) inputdev->close = cmpc_accel_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) static int cmpc_accel_add(struct acpi_device *acpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) struct input_dev *inputdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) struct cmpc_accel *accel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) accel = kmalloc(sizeof(*accel), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (!accel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) accel->sensitivity = CMPC_ACCEL_SENSITIVITY_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) cmpc_accel_set_sensitivity(acpi->handle, accel->sensitivity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) error = device_create_file(&acpi->dev, &cmpc_accel_sensitivity_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) goto failed_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) error = cmpc_add_acpi_notify_device(acpi, "cmpc_accel",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) cmpc_accel_idev_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) goto failed_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) inputdev = dev_get_drvdata(&acpi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) dev_set_drvdata(&inputdev->dev, accel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) failed_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) failed_file:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) kfree(accel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) static int cmpc_accel_remove(struct acpi_device *acpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) return cmpc_remove_acpi_notify_device(acpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static const struct acpi_device_id cmpc_accel_device_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {CMPC_ACCEL_HID, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) {"", 0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) static struct acpi_driver cmpc_accel_acpi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) .name = "cmpc_accel",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) .class = "cmpc_accel",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) .ids = cmpc_accel_device_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) .ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) .add = cmpc_accel_add,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) .remove = cmpc_accel_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) .notify = cmpc_accel_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) * Tablet mode code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static acpi_status cmpc_get_tablet(acpi_handle handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) unsigned long long *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) union acpi_object param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) struct acpi_object_list input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) unsigned long long output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) param.type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) param.integer.value = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) input.count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) input.pointer = ¶m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) status = acpi_evaluate_integer(handle, "TCMD", &input, &output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (ACPI_SUCCESS(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) *value = output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) static void cmpc_tablet_handler(struct acpi_device *dev, u32 event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) unsigned long long val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) struct input_dev *inputdev = dev_get_drvdata(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (event == 0x81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (ACPI_SUCCESS(cmpc_get_tablet(dev->handle, &val))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) input_report_switch(inputdev, SW_TABLET_MODE, !val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) input_sync(inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) static void cmpc_tablet_idev_init(struct input_dev *inputdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) unsigned long long val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) struct acpi_device *acpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) set_bit(EV_SW, inputdev->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) set_bit(SW_TABLET_MODE, inputdev->swbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) acpi = to_acpi_device(inputdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (ACPI_SUCCESS(cmpc_get_tablet(acpi->handle, &val))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) input_report_switch(inputdev, SW_TABLET_MODE, !val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) input_sync(inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) static int cmpc_tablet_add(struct acpi_device *acpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) return cmpc_add_acpi_notify_device(acpi, "cmpc_tablet",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) cmpc_tablet_idev_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) static int cmpc_tablet_remove(struct acpi_device *acpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return cmpc_remove_acpi_notify_device(acpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) static int cmpc_tablet_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) struct input_dev *inputdev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) unsigned long long val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (ACPI_SUCCESS(cmpc_get_tablet(to_acpi_device(dev)->handle, &val))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) input_report_switch(inputdev, SW_TABLET_MODE, !val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) input_sync(inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) static SIMPLE_DEV_PM_OPS(cmpc_tablet_pm, NULL, cmpc_tablet_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) static const struct acpi_device_id cmpc_tablet_device_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) {CMPC_TABLET_HID, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) {"", 0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) static struct acpi_driver cmpc_tablet_acpi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) .name = "cmpc_tablet",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) .class = "cmpc_tablet",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) .ids = cmpc_tablet_device_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) .ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) .add = cmpc_tablet_add,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) .remove = cmpc_tablet_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) .notify = cmpc_tablet_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) .drv.pm = &cmpc_tablet_pm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * Backlight code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) static acpi_status cmpc_get_brightness(acpi_handle handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) unsigned long long *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) union acpi_object param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) struct acpi_object_list input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) unsigned long long output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) param.type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) param.integer.value = 0xC0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) input.count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) input.pointer = ¶m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) status = acpi_evaluate_integer(handle, "GRDI", &input, &output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (ACPI_SUCCESS(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) *value = output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) static acpi_status cmpc_set_brightness(acpi_handle handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) unsigned long long value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) union acpi_object param[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) struct acpi_object_list input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) unsigned long long output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) param[0].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) param[0].integer.value = 0xC0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) param[1].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) param[1].integer.value = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) input.count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) input.pointer = param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) status = acpi_evaluate_integer(handle, "GWRI", &input, &output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) static int cmpc_bl_get_brightness(struct backlight_device *bd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) acpi_handle handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) unsigned long long brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) handle = bl_get_data(bd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) status = cmpc_get_brightness(handle, &brightness);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (ACPI_SUCCESS(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) return brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) static int cmpc_bl_update_status(struct backlight_device *bd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) acpi_handle handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) handle = bl_get_data(bd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) status = cmpc_set_brightness(handle, bd->props.brightness);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (ACPI_SUCCESS(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) static const struct backlight_ops cmpc_bl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) .get_brightness = cmpc_bl_get_brightness,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) .update_status = cmpc_bl_update_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) * RFKILL code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) static acpi_status cmpc_get_rfkill_wlan(acpi_handle handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) unsigned long long *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) union acpi_object param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) struct acpi_object_list input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) unsigned long long output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) param.type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) param.integer.value = 0xC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) input.count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) input.pointer = ¶m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) status = acpi_evaluate_integer(handle, "GRDI", &input, &output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (ACPI_SUCCESS(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) *value = output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) static acpi_status cmpc_set_rfkill_wlan(acpi_handle handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) unsigned long long value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) union acpi_object param[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) struct acpi_object_list input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) unsigned long long output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) param[0].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) param[0].integer.value = 0xC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) param[1].type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) param[1].integer.value = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) input.count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) input.pointer = param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) status = acpi_evaluate_integer(handle, "GWRI", &input, &output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) static void cmpc_rfkill_query(struct rfkill *rfkill, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) acpi_handle handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) unsigned long long state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) bool blocked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) handle = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) status = cmpc_get_rfkill_wlan(handle, &state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (ACPI_SUCCESS(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) blocked = state & 1 ? false : true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) rfkill_set_sw_state(rfkill, blocked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) static int cmpc_rfkill_block(void *data, bool blocked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) acpi_handle handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) unsigned long long state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) bool is_blocked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) handle = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) status = cmpc_get_rfkill_wlan(handle, &state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) /* Check if we really need to call cmpc_set_rfkill_wlan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) is_blocked = state & 1 ? false : true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) if (is_blocked != blocked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) state = blocked ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) status = cmpc_set_rfkill_wlan(handle, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) static const struct rfkill_ops cmpc_rfkill_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) .query = cmpc_rfkill_query,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) .set_block = cmpc_rfkill_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * Common backlight and rfkill code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) struct ipml200_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) struct backlight_device *bd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) struct rfkill *rf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) static int cmpc_ipml_add(struct acpi_device *acpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) struct ipml200_dev *ipml;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) struct backlight_properties props;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) ipml = kmalloc(sizeof(*ipml), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (ipml == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) memset(&props, 0, sizeof(struct backlight_properties));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) props.type = BACKLIGHT_PLATFORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) props.max_brightness = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) ipml->bd = backlight_device_register("cmpc_bl", &acpi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) acpi->handle, &cmpc_bl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) &props);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (IS_ERR(ipml->bd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) retval = PTR_ERR(ipml->bd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) goto out_bd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) ipml->rf = rfkill_alloc("cmpc_rfkill", &acpi->dev, RFKILL_TYPE_WLAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) &cmpc_rfkill_ops, acpi->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) * If RFKILL is disabled, rfkill_alloc will return ERR_PTR(-ENODEV).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) * This is OK, however, since all other uses of the device will not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) * derefence it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (ipml->rf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) retval = rfkill_register(ipml->rf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) rfkill_destroy(ipml->rf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) ipml->rf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) dev_set_drvdata(&acpi->dev, ipml);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) out_bd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) kfree(ipml);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) static int cmpc_ipml_remove(struct acpi_device *acpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) struct ipml200_dev *ipml;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) ipml = dev_get_drvdata(&acpi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) backlight_device_unregister(ipml->bd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) if (ipml->rf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) rfkill_unregister(ipml->rf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) rfkill_destroy(ipml->rf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) kfree(ipml);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) static const struct acpi_device_id cmpc_ipml_device_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) {CMPC_IPML_HID, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) {"", 0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) static struct acpi_driver cmpc_ipml_acpi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) .name = "cmpc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) .class = "cmpc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) .ids = cmpc_ipml_device_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) .ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) .add = cmpc_ipml_add,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) .remove = cmpc_ipml_remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) * Extra keys code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) static int cmpc_keys_codes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) KEY_UNKNOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) KEY_WLAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) KEY_SWITCHVIDEOMODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) KEY_BRIGHTNESSDOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) KEY_BRIGHTNESSUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) KEY_VENDOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) KEY_UNKNOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) KEY_CAMERA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) KEY_BACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) KEY_FORWARD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) KEY_MAX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static void cmpc_keys_handler(struct acpi_device *dev, u32 event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) struct input_dev *inputdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) int code = KEY_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if ((event & 0x0F) < ARRAY_SIZE(cmpc_keys_codes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) code = cmpc_keys_codes[event & 0x0F];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) inputdev = dev_get_drvdata(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) input_report_key(inputdev, code, !(event & 0x10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) input_sync(inputdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) static void cmpc_keys_idev_init(struct input_dev *inputdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) set_bit(EV_KEY, inputdev->evbit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) for (i = 0; cmpc_keys_codes[i] != KEY_MAX; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) set_bit(cmpc_keys_codes[i], inputdev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) static int cmpc_keys_add(struct acpi_device *acpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) return cmpc_add_acpi_notify_device(acpi, "cmpc_keys",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) cmpc_keys_idev_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) static int cmpc_keys_remove(struct acpi_device *acpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) return cmpc_remove_acpi_notify_device(acpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) static const struct acpi_device_id cmpc_keys_device_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) {CMPC_KEYS_HID, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) {"", 0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) static struct acpi_driver cmpc_keys_acpi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) .name = "cmpc_keys",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) .class = "cmpc_keys",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) .ids = cmpc_keys_device_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) .ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) .add = cmpc_keys_add,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) .remove = cmpc_keys_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) .notify = cmpc_keys_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) * General init/exit code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) static int cmpc_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) r = acpi_bus_register_driver(&cmpc_keys_acpi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) goto failed_keys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) r = acpi_bus_register_driver(&cmpc_ipml_acpi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) goto failed_bl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) r = acpi_bus_register_driver(&cmpc_tablet_acpi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) goto failed_tablet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) r = acpi_bus_register_driver(&cmpc_accel_acpi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) goto failed_accel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) r = acpi_bus_register_driver(&cmpc_accel_acpi_driver_v4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) goto failed_accel_v4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) failed_accel_v4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) acpi_bus_unregister_driver(&cmpc_accel_acpi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) failed_accel:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) failed_tablet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) acpi_bus_unregister_driver(&cmpc_ipml_acpi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) failed_bl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) acpi_bus_unregister_driver(&cmpc_keys_acpi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) failed_keys:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) static void cmpc_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) acpi_bus_unregister_driver(&cmpc_accel_acpi_driver_v4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) acpi_bus_unregister_driver(&cmpc_accel_acpi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) acpi_bus_unregister_driver(&cmpc_tablet_acpi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) acpi_bus_unregister_driver(&cmpc_ipml_acpi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) acpi_bus_unregister_driver(&cmpc_keys_acpi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) module_init(cmpc_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) module_exit(cmpc_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) static const struct acpi_device_id cmpc_device_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) {CMPC_ACCEL_HID, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) {CMPC_ACCEL_HID_V4, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) {CMPC_TABLET_HID, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) {CMPC_IPML_HID, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) {CMPC_KEYS_HID, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) {"", 0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) MODULE_DEVICE_TABLE(acpi, cmpc_device_ids);