854 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright (c) 2016 Masaki Ota <masaki.ota@jp.alps.com>4 */5 6#include <linux/kernel.h>7#include <linux/hid.h>8#include <linux/input.h>9#include <linux/input/mt.h>10#include <linux/module.h>11#include <linux/unaligned.h>12#include "hid-ids.h"13 14/* ALPS Device Product ID */15#define HID_PRODUCT_ID_T3_BTNLESS 0xD0C016#define HID_PRODUCT_ID_COSMO 0x120217#define HID_PRODUCT_ID_U1_PTP_1 0x120718#define HID_PRODUCT_ID_U1 0x120919#define HID_PRODUCT_ID_U1_PTP_2 0x120A20#define HID_PRODUCT_ID_U1_DUAL 0x120B21#define HID_PRODUCT_ID_T4_BTNLESS 0x120C22 23#define DEV_SINGLEPOINT 0x0124#define DEV_DUALPOINT 0x0225 26#define U1_MOUSE_REPORT_ID 0x01 /* Mouse data ReportID */27#define U1_ABSOLUTE_REPORT_ID 0x03 /* Absolute data ReportID */28#define U1_ABSOLUTE_REPORT_ID_SECD 0x02 /* FW-PTP Absolute data ReportID */29#define U1_FEATURE_REPORT_ID 0x05 /* Feature ReportID */30#define U1_SP_ABSOLUTE_REPORT_ID 0x06 /* Feature ReportID */31 32#define U1_FEATURE_REPORT_LEN 0x08 /* Feature Report Length */33#define U1_FEATURE_REPORT_LEN_ALL 0x0A34#define U1_CMD_REGISTER_READ 0xD135#define U1_CMD_REGISTER_WRITE 0xD236 37#define U1_DEVTYPE_SP_SUPPORT 0x10 /* SP Support */38#define U1_DISABLE_DEV 0x0139#define U1_TP_ABS_MODE 0x0240#define U1_SP_ABS_MODE 0x8041 42#define ADDRESS_U1_DEV_CTRL_1 0x0080004043#define ADDRESS_U1_DEVICE_TYP 0x0080004344#define ADDRESS_U1_NUM_SENS_X 0x0080004745#define ADDRESS_U1_NUM_SENS_Y 0x0080004846#define ADDRESS_U1_PITCH_SENS_X 0x0080004947#define ADDRESS_U1_PITCH_SENS_Y 0x0080004A48#define ADDRESS_U1_RESO_DWN_ABS 0x0080004E49#define ADDRESS_U1_PAD_BTN 0x0080005250#define ADDRESS_U1_SP_BTN 0x0080009F51 52#define T4_INPUT_REPORT_LEN sizeof(struct t4_input_report)53#define T4_FEATURE_REPORT_LEN T4_INPUT_REPORT_LEN54#define T4_FEATURE_REPORT_ID 755#define T4_CMD_REGISTER_READ 0x0856#define T4_CMD_REGISTER_WRITE 0x0757 58#define T4_ADDRESS_BASE 0xC2C059#define PRM_SYS_CONFIG_1 (T4_ADDRESS_BASE + 0x0002)60#define T4_PRM_FEED_CONFIG_1 (T4_ADDRESS_BASE + 0x0004)61#define T4_PRM_FEED_CONFIG_4 (T4_ADDRESS_BASE + 0x001A)62#define T4_PRM_ID_CONFIG_3 (T4_ADDRESS_BASE + 0x00B0)63 64 65#define T4_FEEDCFG4_ADVANCED_ABS_ENABLE 0x0166#define T4_I2C_ABS 0x7867 68#define T4_COUNT_PER_ELECTRODE 25669#define MAX_TOUCHES 570 71enum dev_num {72 U1,73 T4,74 UNKNOWN,75};76/**77 * struct alps_dev78 *79 * @input: pointer to the kernel input device80 * @input2: pointer to the kernel input2 device81 * @hdev: pointer to the struct hid_device82 *83 * @dev_type: device type84 * @max_fingers: total number of fingers85 * @has_sp: boolean of sp existense86 * @sp_btn_info: button information87 * @x_active_len_mm: active area length of X (mm)88 * @y_active_len_mm: active area length of Y (mm)89 * @x_max: maximum x coordinate value90 * @y_max: maximum y coordinate value91 * @x_min: minimum x coordinate value92 * @y_min: minimum y coordinate value93 * @btn_cnt: number of buttons94 * @sp_btn_cnt: number of stick buttons95 */96struct alps_dev {97 struct input_dev *input;98 struct input_dev *input2;99 struct hid_device *hdev;100 101 enum dev_num dev_type;102 u8 max_fingers;103 u8 has_sp;104 u8 sp_btn_info;105 u32 x_active_len_mm;106 u32 y_active_len_mm;107 u32 x_max;108 u32 y_max;109 u32 x_min;110 u32 y_min;111 u32 btn_cnt;112 u32 sp_btn_cnt;113};114 115struct t4_contact_data {116 u8 palm;117 u8 x_lo;118 u8 x_hi;119 u8 y_lo;120 u8 y_hi;121};122 123struct t4_input_report {124 u8 reportID;125 u8 numContacts;126 struct t4_contact_data contact[5];127 u8 button;128 u8 track[5];129 u8 zx[5], zy[5];130 u8 palmTime[5];131 u8 kilroy;132 u16 timeStamp;133};134 135static u16 t4_calc_check_sum(u8 *buffer,136 unsigned long offset, unsigned long length)137{138 u16 sum1 = 0xFF, sum2 = 0xFF;139 unsigned long i = 0;140 141 if (offset + length >= 50)142 return 0;143 144 while (length > 0) {145 u32 tlen = length > 20 ? 20 : length;146 147 length -= tlen;148 149 do {150 sum1 += buffer[offset + i];151 sum2 += sum1;152 i++;153 } while (--tlen > 0);154 155 sum1 = (sum1 & 0xFF) + (sum1 >> 8);156 sum2 = (sum2 & 0xFF) + (sum2 >> 8);157 }158 159 sum1 = (sum1 & 0xFF) + (sum1 >> 8);160 sum2 = (sum2 & 0xFF) + (sum2 >> 8);161 162 return(sum2 << 8 | sum1);163}164 165static int t4_read_write_register(struct hid_device *hdev, u32 address,166 u8 *read_val, u8 write_val, bool read_flag)167{168 int ret;169 u16 check_sum;170 u8 *input;171 u8 *readbuf = NULL;172 173 input = kzalloc(T4_FEATURE_REPORT_LEN, GFP_KERNEL);174 if (!input)175 return -ENOMEM;176 177 input[0] = T4_FEATURE_REPORT_ID;178 if (read_flag) {179 input[1] = T4_CMD_REGISTER_READ;180 input[8] = 0x00;181 } else {182 input[1] = T4_CMD_REGISTER_WRITE;183 input[8] = write_val;184 }185 put_unaligned_le32(address, input + 2);186 input[6] = 1;187 input[7] = 0;188 189 /* Calculate the checksum */190 check_sum = t4_calc_check_sum(input, 1, 8);191 input[9] = (u8)check_sum;192 input[10] = (u8)(check_sum >> 8);193 input[11] = 0;194 195 ret = hid_hw_raw_request(hdev, T4_FEATURE_REPORT_ID, input,196 T4_FEATURE_REPORT_LEN,197 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);198 199 if (ret < 0) {200 dev_err(&hdev->dev, "failed to read command (%d)\n", ret);201 goto exit;202 }203 204 if (read_flag) {205 readbuf = kzalloc(T4_FEATURE_REPORT_LEN, GFP_KERNEL);206 if (!readbuf) {207 ret = -ENOMEM;208 goto exit;209 }210 211 ret = hid_hw_raw_request(hdev, T4_FEATURE_REPORT_ID, readbuf,212 T4_FEATURE_REPORT_LEN,213 HID_FEATURE_REPORT, HID_REQ_GET_REPORT);214 if (ret < 0) {215 dev_err(&hdev->dev, "failed read register (%d)\n", ret);216 goto exit_readbuf;217 }218 219 ret = -EINVAL;220 221 if (*(u32 *)&readbuf[6] != address) {222 dev_err(&hdev->dev, "read register address error (%x,%x)\n",223 *(u32 *)&readbuf[6], address);224 goto exit_readbuf;225 }226 227 if (*(u16 *)&readbuf[10] != 1) {228 dev_err(&hdev->dev, "read register size error (%x)\n",229 *(u16 *)&readbuf[10]);230 goto exit_readbuf;231 }232 233 check_sum = t4_calc_check_sum(readbuf, 6, 7);234 if (*(u16 *)&readbuf[13] != check_sum) {235 dev_err(&hdev->dev, "read register checksum error (%x,%x)\n",236 *(u16 *)&readbuf[13], check_sum);237 goto exit_readbuf;238 }239 240 *read_val = readbuf[12];241 }242 243 ret = 0;244 245exit_readbuf:246 kfree(readbuf);247exit:248 kfree(input);249 return ret;250}251 252static int u1_read_write_register(struct hid_device *hdev, u32 address,253 u8 *read_val, u8 write_val, bool read_flag)254{255 int ret, i;256 u8 check_sum;257 u8 *input;258 u8 *readbuf;259 260 input = kzalloc(U1_FEATURE_REPORT_LEN, GFP_KERNEL);261 if (!input)262 return -ENOMEM;263 264 input[0] = U1_FEATURE_REPORT_ID;265 if (read_flag) {266 input[1] = U1_CMD_REGISTER_READ;267 input[6] = 0x00;268 } else {269 input[1] = U1_CMD_REGISTER_WRITE;270 input[6] = write_val;271 }272 273 put_unaligned_le32(address, input + 2);274 275 /* Calculate the checksum */276 check_sum = U1_FEATURE_REPORT_LEN_ALL;277 for (i = 0; i < U1_FEATURE_REPORT_LEN - 1; i++)278 check_sum += input[i];279 280 input[7] = check_sum;281 ret = hid_hw_raw_request(hdev, U1_FEATURE_REPORT_ID, input,282 U1_FEATURE_REPORT_LEN,283 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);284 285 if (ret < 0) {286 dev_err(&hdev->dev, "failed to read command (%d)\n", ret);287 goto exit;288 }289 290 if (read_flag) {291 readbuf = kzalloc(U1_FEATURE_REPORT_LEN, GFP_KERNEL);292 if (!readbuf) {293 ret = -ENOMEM;294 goto exit;295 }296 297 ret = hid_hw_raw_request(hdev, U1_FEATURE_REPORT_ID, readbuf,298 U1_FEATURE_REPORT_LEN,299 HID_FEATURE_REPORT, HID_REQ_GET_REPORT);300 301 if (ret < 0) {302 dev_err(&hdev->dev, "failed read register (%d)\n", ret);303 kfree(readbuf);304 goto exit;305 }306 307 *read_val = readbuf[6];308 309 kfree(readbuf);310 }311 312 ret = 0;313 314exit:315 kfree(input);316 return ret;317}318 319static int t4_raw_event(struct alps_dev *hdata, u8 *data, int size)320{321 unsigned int x, y, z;322 int i;323 struct t4_input_report *p_report = (struct t4_input_report *)data;324 325 if (!data)326 return 0;327 for (i = 0; i < hdata->max_fingers; i++) {328 x = p_report->contact[i].x_hi << 8 | p_report->contact[i].x_lo;329 y = p_report->contact[i].y_hi << 8 | p_report->contact[i].y_lo;330 y = hdata->y_max - y + hdata->y_min;331 z = (p_report->contact[i].palm < 0x80 &&332 p_report->contact[i].palm > 0) * 62;333 if (x == 0xffff) {334 x = 0;335 y = 0;336 z = 0;337 }338 input_mt_slot(hdata->input, i);339 340 input_mt_report_slot_state(hdata->input,341 MT_TOOL_FINGER, z != 0);342 343 if (!z)344 continue;345 346 input_report_abs(hdata->input, ABS_MT_POSITION_X, x);347 input_report_abs(hdata->input, ABS_MT_POSITION_Y, y);348 input_report_abs(hdata->input, ABS_MT_PRESSURE, z);349 }350 input_mt_sync_frame(hdata->input);351 352 input_report_key(hdata->input, BTN_LEFT, p_report->button);353 354 input_sync(hdata->input);355 return 1;356}357 358static int u1_raw_event(struct alps_dev *hdata, u8 *data, int size)359{360 unsigned int x, y, z;361 int i;362 short sp_x, sp_y;363 364 if (!data)365 return 0;366 switch (data[0]) {367 case U1_MOUSE_REPORT_ID:368 break;369 case U1_FEATURE_REPORT_ID:370 break;371 case U1_ABSOLUTE_REPORT_ID:372 case U1_ABSOLUTE_REPORT_ID_SECD:373 for (i = 0; i < hdata->max_fingers; i++) {374 u8 *contact = &data[i * 5];375 376 x = get_unaligned_le16(contact + 3);377 y = get_unaligned_le16(contact + 5);378 z = contact[7] & 0x7F;379 380 input_mt_slot(hdata->input, i);381 382 if (z != 0) {383 input_mt_report_slot_state(hdata->input,384 MT_TOOL_FINGER, 1);385 input_report_abs(hdata->input,386 ABS_MT_POSITION_X, x);387 input_report_abs(hdata->input,388 ABS_MT_POSITION_Y, y);389 input_report_abs(hdata->input,390 ABS_MT_PRESSURE, z);391 } else {392 input_mt_report_slot_inactive(hdata->input);393 }394 }395 396 input_mt_sync_frame(hdata->input);397 398 input_report_key(hdata->input, BTN_LEFT,399 data[1] & 0x1);400 input_report_key(hdata->input, BTN_RIGHT,401 (data[1] & 0x2));402 input_report_key(hdata->input, BTN_MIDDLE,403 (data[1] & 0x4));404 405 input_sync(hdata->input);406 407 return 1;408 409 case U1_SP_ABSOLUTE_REPORT_ID:410 sp_x = get_unaligned_le16(data+2);411 sp_y = get_unaligned_le16(data+4);412 413 sp_x = sp_x / 8;414 sp_y = sp_y / 8;415 416 input_report_rel(hdata->input2, REL_X, sp_x);417 input_report_rel(hdata->input2, REL_Y, sp_y);418 419 input_report_key(hdata->input2, BTN_LEFT,420 data[1] & 0x1);421 input_report_key(hdata->input2, BTN_RIGHT,422 (data[1] & 0x2));423 input_report_key(hdata->input2, BTN_MIDDLE,424 (data[1] & 0x4));425 426 input_sync(hdata->input2);427 428 return 1;429 }430 431 return 0;432}433 434static int alps_raw_event(struct hid_device *hdev,435 struct hid_report *report, u8 *data, int size)436{437 int ret = 0;438 struct alps_dev *hdata = hid_get_drvdata(hdev);439 440 switch (hdev->product) {441 case HID_PRODUCT_ID_T4_BTNLESS:442 ret = t4_raw_event(hdata, data, size);443 break;444 default:445 ret = u1_raw_event(hdata, data, size);446 break;447 }448 return ret;449}450 451static int __maybe_unused alps_post_reset(struct hid_device *hdev)452{453 int ret = -1;454 struct alps_dev *data = hid_get_drvdata(hdev);455 456 switch (data->dev_type) {457 case T4:458 ret = t4_read_write_register(hdev, T4_PRM_FEED_CONFIG_1,459 NULL, T4_I2C_ABS, false);460 if (ret < 0) {461 dev_err(&hdev->dev, "failed T4_PRM_FEED_CONFIG_1 (%d)\n",462 ret);463 goto exit;464 }465 466 ret = t4_read_write_register(hdev, T4_PRM_FEED_CONFIG_4,467 NULL, T4_FEEDCFG4_ADVANCED_ABS_ENABLE, false);468 if (ret < 0) {469 dev_err(&hdev->dev, "failed T4_PRM_FEED_CONFIG_4 (%d)\n",470 ret);471 goto exit;472 }473 break;474 case U1:475 ret = u1_read_write_register(hdev,476 ADDRESS_U1_DEV_CTRL_1, NULL,477 U1_TP_ABS_MODE | U1_SP_ABS_MODE, false);478 if (ret < 0) {479 dev_err(&hdev->dev, "failed to change TP mode (%d)\n",480 ret);481 goto exit;482 }483 break;484 default:485 break;486 }487 488exit:489 return ret;490}491 492static int __maybe_unused alps_post_resume(struct hid_device *hdev)493{494 return alps_post_reset(hdev);495}496 497static int u1_init(struct hid_device *hdev, struct alps_dev *pri_data)498{499 int ret;500 u8 tmp, dev_ctrl, sen_line_num_x, sen_line_num_y;501 u8 pitch_x, pitch_y, resolution;502 503 /* Device initialization */504 ret = u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1,505 &dev_ctrl, 0, true);506 if (ret < 0) {507 dev_err(&hdev->dev, "failed U1_DEV_CTRL_1 (%d)\n", ret);508 goto exit;509 }510 511 dev_ctrl &= ~U1_DISABLE_DEV;512 dev_ctrl |= U1_TP_ABS_MODE;513 ret = u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1,514 NULL, dev_ctrl, false);515 if (ret < 0) {516 dev_err(&hdev->dev, "failed to change TP mode (%d)\n", ret);517 goto exit;518 }519 520 ret = u1_read_write_register(hdev, ADDRESS_U1_NUM_SENS_X,521 &sen_line_num_x, 0, true);522 if (ret < 0) {523 dev_err(&hdev->dev, "failed U1_NUM_SENS_X (%d)\n", ret);524 goto exit;525 }526 527 ret = u1_read_write_register(hdev, ADDRESS_U1_NUM_SENS_Y,528 &sen_line_num_y, 0, true);529 if (ret < 0) {530 dev_err(&hdev->dev, "failed U1_NUM_SENS_Y (%d)\n", ret);531 goto exit;532 }533 534 ret = u1_read_write_register(hdev, ADDRESS_U1_PITCH_SENS_X,535 &pitch_x, 0, true);536 if (ret < 0) {537 dev_err(&hdev->dev, "failed U1_PITCH_SENS_X (%d)\n", ret);538 goto exit;539 }540 541 ret = u1_read_write_register(hdev, ADDRESS_U1_PITCH_SENS_Y,542 &pitch_y, 0, true);543 if (ret < 0) {544 dev_err(&hdev->dev, "failed U1_PITCH_SENS_Y (%d)\n", ret);545 goto exit;546 }547 548 ret = u1_read_write_register(hdev, ADDRESS_U1_RESO_DWN_ABS,549 &resolution, 0, true);550 if (ret < 0) {551 dev_err(&hdev->dev, "failed U1_RESO_DWN_ABS (%d)\n", ret);552 goto exit;553 }554 pri_data->x_active_len_mm =555 (pitch_x * (sen_line_num_x - 1)) / 10;556 pri_data->y_active_len_mm =557 (pitch_y * (sen_line_num_y - 1)) / 10;558 559 pri_data->x_max =560 (resolution << 2) * (sen_line_num_x - 1);561 pri_data->x_min = 1;562 pri_data->y_max =563 (resolution << 2) * (sen_line_num_y - 1);564 pri_data->y_min = 1;565 566 ret = u1_read_write_register(hdev, ADDRESS_U1_PAD_BTN,567 &tmp, 0, true);568 if (ret < 0) {569 dev_err(&hdev->dev, "failed U1_PAD_BTN (%d)\n", ret);570 goto exit;571 }572 if ((tmp & 0x0F) == (tmp & 0xF0) >> 4) {573 pri_data->btn_cnt = (tmp & 0x0F);574 } else {575 /* Button pad */576 pri_data->btn_cnt = 1;577 }578 579 pri_data->has_sp = 0;580 /* Check StickPointer device */581 ret = u1_read_write_register(hdev, ADDRESS_U1_DEVICE_TYP,582 &tmp, 0, true);583 if (ret < 0) {584 dev_err(&hdev->dev, "failed U1_DEVICE_TYP (%d)\n", ret);585 goto exit;586 }587 if (tmp & U1_DEVTYPE_SP_SUPPORT) {588 dev_ctrl |= U1_SP_ABS_MODE;589 ret = u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1,590 NULL, dev_ctrl, false);591 if (ret < 0) {592 dev_err(&hdev->dev, "failed SP mode (%d)\n", ret);593 goto exit;594 }595 596 ret = u1_read_write_register(hdev, ADDRESS_U1_SP_BTN,597 &pri_data->sp_btn_info, 0, true);598 if (ret < 0) {599 dev_err(&hdev->dev, "failed U1_SP_BTN (%d)\n", ret);600 goto exit;601 }602 pri_data->has_sp = 1;603 }604 pri_data->max_fingers = 5;605exit:606 return ret;607}608 609static int T4_init(struct hid_device *hdev, struct alps_dev *pri_data)610{611 int ret;612 u8 tmp, sen_line_num_x, sen_line_num_y;613 614 ret = t4_read_write_register(hdev, T4_PRM_ID_CONFIG_3, &tmp, 0, true);615 if (ret < 0) {616 dev_err(&hdev->dev, "failed T4_PRM_ID_CONFIG_3 (%d)\n", ret);617 goto exit;618 }619 sen_line_num_x = 16 + ((tmp & 0x0F) | (tmp & 0x08 ? 0xF0 : 0));620 sen_line_num_y = 12 + (((tmp & 0xF0) >> 4) | (tmp & 0x80 ? 0xF0 : 0));621 622 pri_data->x_max = sen_line_num_x * T4_COUNT_PER_ELECTRODE;623 pri_data->x_min = T4_COUNT_PER_ELECTRODE;624 pri_data->y_max = sen_line_num_y * T4_COUNT_PER_ELECTRODE;625 pri_data->y_min = T4_COUNT_PER_ELECTRODE;626 pri_data->x_active_len_mm = pri_data->y_active_len_mm = 0;627 pri_data->btn_cnt = 1;628 629 ret = t4_read_write_register(hdev, PRM_SYS_CONFIG_1, &tmp, 0, true);630 if (ret < 0) {631 dev_err(&hdev->dev, "failed PRM_SYS_CONFIG_1 (%d)\n", ret);632 goto exit;633 }634 tmp |= 0x02;635 ret = t4_read_write_register(hdev, PRM_SYS_CONFIG_1, NULL, tmp, false);636 if (ret < 0) {637 dev_err(&hdev->dev, "failed PRM_SYS_CONFIG_1 (%d)\n", ret);638 goto exit;639 }640 641 ret = t4_read_write_register(hdev, T4_PRM_FEED_CONFIG_1,642 NULL, T4_I2C_ABS, false);643 if (ret < 0) {644 dev_err(&hdev->dev, "failed T4_PRM_FEED_CONFIG_1 (%d)\n", ret);645 goto exit;646 }647 648 ret = t4_read_write_register(hdev, T4_PRM_FEED_CONFIG_4, NULL,649 T4_FEEDCFG4_ADVANCED_ABS_ENABLE, false);650 if (ret < 0) {651 dev_err(&hdev->dev, "failed T4_PRM_FEED_CONFIG_4 (%d)\n", ret);652 goto exit;653 }654 pri_data->max_fingers = 5;655 pri_data->has_sp = 0;656exit:657 return ret;658}659 660static int alps_sp_open(struct input_dev *dev)661{662 struct hid_device *hid = input_get_drvdata(dev);663 664 return hid_hw_open(hid);665}666 667static void alps_sp_close(struct input_dev *dev)668{669 struct hid_device *hid = input_get_drvdata(dev);670 671 hid_hw_close(hid);672}673 674static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi)675{676 struct alps_dev *data = hid_get_drvdata(hdev);677 struct input_dev *input = hi->input, *input2;678 int ret;679 int res_x, res_y, i;680 681 data->input = input;682 683 hid_dbg(hdev, "Opening low level driver\n");684 ret = hid_hw_open(hdev);685 if (ret)686 return ret;687 688 /* Allow incoming hid reports */689 hid_device_io_start(hdev);690 switch (data->dev_type) {691 case T4:692 ret = T4_init(hdev, data);693 break;694 case U1:695 ret = u1_init(hdev, data);696 break;697 default:698 break;699 }700 701 if (ret)702 goto exit;703 704 __set_bit(EV_ABS, input->evbit);705 input_set_abs_params(input, ABS_MT_POSITION_X,706 data->x_min, data->x_max, 0, 0);707 input_set_abs_params(input, ABS_MT_POSITION_Y,708 data->y_min, data->y_max, 0, 0);709 710 if (data->x_active_len_mm && data->y_active_len_mm) {711 res_x = (data->x_max - 1) / data->x_active_len_mm;712 res_y = (data->y_max - 1) / data->y_active_len_mm;713 714 input_abs_set_res(input, ABS_MT_POSITION_X, res_x);715 input_abs_set_res(input, ABS_MT_POSITION_Y, res_y);716 }717 718 input_set_abs_params(input, ABS_MT_PRESSURE, 0, 64, 0, 0);719 720 input_mt_init_slots(input, data->max_fingers, INPUT_MT_POINTER);721 722 __set_bit(EV_KEY, input->evbit);723 724 if (data->btn_cnt == 1)725 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);726 727 for (i = 0; i < data->btn_cnt; i++)728 __set_bit(BTN_LEFT + i, input->keybit);729 730 /* Stick device initialization */731 if (data->has_sp) {732 input2 = input_allocate_device();733 if (!input2) {734 ret = -ENOMEM;735 goto exit;736 }737 738 data->input2 = input2;739 input2->phys = input->phys;740 input2->name = "DualPoint Stick";741 input2->id.bustype = BUS_I2C;742 input2->id.vendor = input->id.vendor;743 input2->id.product = input->id.product;744 input2->id.version = input->id.version;745 input2->dev.parent = input->dev.parent;746 747 input_set_drvdata(input2, hdev);748 input2->open = alps_sp_open;749 input2->close = alps_sp_close;750 751 __set_bit(EV_KEY, input2->evbit);752 data->sp_btn_cnt = (data->sp_btn_info & 0x0F);753 for (i = 0; i < data->sp_btn_cnt; i++)754 __set_bit(BTN_LEFT + i, input2->keybit);755 756 __set_bit(EV_REL, input2->evbit);757 __set_bit(REL_X, input2->relbit);758 __set_bit(REL_Y, input2->relbit);759 __set_bit(INPUT_PROP_POINTER, input2->propbit);760 __set_bit(INPUT_PROP_POINTING_STICK, input2->propbit);761 762 if (input_register_device(data->input2)) {763 input_free_device(input2);764 ret = -ENOENT;765 goto exit;766 }767 }768 769exit:770 hid_device_io_stop(hdev);771 hid_hw_close(hdev);772 return ret;773}774 775static int alps_input_mapping(struct hid_device *hdev,776 struct hid_input *hi, struct hid_field *field,777 struct hid_usage *usage, unsigned long **bit, int *max)778{779 return -1;780}781 782static int alps_probe(struct hid_device *hdev, const struct hid_device_id *id)783{784 struct alps_dev *data = NULL;785 int ret;786 data = devm_kzalloc(&hdev->dev, sizeof(struct alps_dev), GFP_KERNEL);787 if (!data)788 return -ENOMEM;789 790 data->hdev = hdev;791 hid_set_drvdata(hdev, data);792 793 hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS;794 795 ret = hid_parse(hdev);796 if (ret) {797 hid_err(hdev, "parse failed\n");798 return ret;799 }800 801 switch (hdev->product) {802 case HID_DEVICE_ID_ALPS_T4_BTNLESS:803 data->dev_type = T4;804 break;805 case HID_DEVICE_ID_ALPS_U1_DUAL:806 case HID_DEVICE_ID_ALPS_U1:807 case HID_DEVICE_ID_ALPS_U1_UNICORN_LEGACY:808 data->dev_type = U1;809 break;810 default:811 data->dev_type = UNKNOWN;812 }813 814 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);815 if (ret) {816 hid_err(hdev, "hw start failed\n");817 return ret;818 }819 820 return 0;821}822 823static const struct hid_device_id alps_id[] = {824 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY,825 USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL) },826 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY,827 USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1) },828 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY,829 USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_UNICORN_LEGACY) },830 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY,831 USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_T4_BTNLESS) },832 { }833};834MODULE_DEVICE_TABLE(hid, alps_id);835 836static struct hid_driver alps_driver = {837 .name = "hid-alps",838 .id_table = alps_id,839 .probe = alps_probe,840 .raw_event = alps_raw_event,841 .input_mapping = alps_input_mapping,842 .input_configured = alps_input_configured,843#ifdef CONFIG_PM844 .resume = alps_post_resume,845 .reset_resume = alps_post_reset,846#endif847};848 849module_hid_driver(alps_driver);850 851MODULE_AUTHOR("Masaki Ota <masaki.ota@jp.alps.com>");852MODULE_DESCRIPTION("ALPS HID driver");853MODULE_LICENSE("GPL");854