Blame view

drivers/hid/hid-alps.c 19.9 KB
2874c5fd2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
2562756dd   Masaki Ota   HID: add Alps I2C...
2
3
  /*
   *  Copyright (c) 2016 Masaki Ota <masaki.ota@jp.alps.com>
2562756dd   Masaki Ota   HID: add Alps I2C...
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
   */
  
  #include <linux/kernel.h>
  #include <linux/hid.h>
  #include <linux/input.h>
  #include <linux/input/mt.h>
  #include <linux/module.h>
  #include <asm/unaligned.h>
  #include "hid-ids.h"
  
  /* ALPS Device Product ID */
  #define HID_PRODUCT_ID_T3_BTNLESS	0xD0C0
  #define HID_PRODUCT_ID_COSMO		0x1202
  #define HID_PRODUCT_ID_U1_PTP_1		0x1207
  #define HID_PRODUCT_ID_U1			0x1209
  #define HID_PRODUCT_ID_U1_PTP_2		0x120A
  #define HID_PRODUCT_ID_U1_DUAL		0x120B
  #define HID_PRODUCT_ID_T4_BTNLESS	0x120C
  
  #define DEV_SINGLEPOINT				0x01
  #define DEV_DUALPOINT				0x02
  
  #define U1_MOUSE_REPORT_ID			0x01 /* Mouse data ReportID */
  #define U1_ABSOLUTE_REPORT_ID		0x03 /* Absolute data ReportID */
aa3c439c1   Caiyuan Xie   HID: alps: suppor...
28
  #define U1_ABSOLUTE_REPORT_ID_SECD  0x02 /* FW-PTP Absolute data ReportID */
2562756dd   Masaki Ota   HID: add Alps I2C...
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
  #define U1_FEATURE_REPORT_ID		0x05 /* Feature ReportID */
  #define U1_SP_ABSOLUTE_REPORT_ID	0x06 /* Feature ReportID */
  
  #define U1_FEATURE_REPORT_LEN		0x08 /* Feature Report Length */
  #define U1_FEATURE_REPORT_LEN_ALL	0x0A
  #define U1_CMD_REGISTER_READ		0xD1
  #define U1_CMD_REGISTER_WRITE		0xD2
  
  #define	U1_DEVTYPE_SP_SUPPORT		0x10 /* SP Support */
  #define	U1_DISABLE_DEV				0x01
  #define U1_TP_ABS_MODE				0x02
  #define	U1_SP_ABS_MODE				0x80
  
  #define ADDRESS_U1_DEV_CTRL_1	0x00800040
  #define ADDRESS_U1_DEVICE_TYP	0x00800043
  #define ADDRESS_U1_NUM_SENS_X	0x00800047
  #define ADDRESS_U1_NUM_SENS_Y	0x00800048
  #define ADDRESS_U1_PITCH_SENS_X	0x00800049
  #define ADDRESS_U1_PITCH_SENS_Y	0x0080004A
  #define ADDRESS_U1_RESO_DWN_ABS 0x0080004E
  #define ADDRESS_U1_PAD_BTN		0x00800052
  #define ADDRESS_U1_SP_BTN		0x0080009F
73196ebe1   Masaki Ota   HID: alps: add su...
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
  #define T4_INPUT_REPORT_LEN			sizeof(struct t4_input_report)
  #define T4_FEATURE_REPORT_LEN		T4_INPUT_REPORT_LEN
  #define T4_FEATURE_REPORT_ID		7
  #define T4_CMD_REGISTER_READ			0x08
  #define T4_CMD_REGISTER_WRITE			0x07
  
  #define T4_ADDRESS_BASE				0xC2C0
  #define PRM_SYS_CONFIG_1			(T4_ADDRESS_BASE + 0x0002)
  #define T4_PRM_FEED_CONFIG_1		(T4_ADDRESS_BASE + 0x0004)
  #define T4_PRM_FEED_CONFIG_4		(T4_ADDRESS_BASE + 0x001A)
  #define T4_PRM_ID_CONFIG_3			(T4_ADDRESS_BASE + 0x00B0)
  
  
  #define T4_FEEDCFG4_ADVANCED_ABS_ENABLE			0x01
  #define T4_I2C_ABS	0x78
  
  #define T4_COUNT_PER_ELECTRODE		256
2562756dd   Masaki Ota   HID: add Alps I2C...
68
  #define MAX_TOUCHES	5
73196ebe1   Masaki Ota   HID: alps: add su...
69
70
71
72
73
  enum dev_num {
  	U1,
  	T4,
  	UNKNOWN,
  };
2562756dd   Masaki Ota   HID: add Alps I2C...
74
75
76
77
78
79
80
  /**
   * struct u1_data
   *
   * @input: pointer to the kernel input device
   * @input2: pointer to the kernel input2 device
   * @hdev: pointer to the struct hid_device
   *
2562756dd   Masaki Ota   HID: add Alps I2C...
81
   * @dev_type: device type
5992262d5   Masaki Ota   HID: alps: remove...
82
83
84
   * @max_fingers: total number of fingers
   * @has_sp: boolean of sp existense
   * @sp_btn_info: button information
2562756dd   Masaki Ota   HID: add Alps I2C...
85
86
87
88
   * @x_active_len_mm: active area length of X (mm)
   * @y_active_len_mm: active area length of Y (mm)
   * @x_max: maximum x coordinate value
   * @y_max: maximum y coordinate value
c7083d3f5   Masaki Ota   HID: alps: proper...
89
90
   * @x_min: minimum x coordinate value
   * @y_min: minimum y coordinate value
2562756dd   Masaki Ota   HID: add Alps I2C...
91
92
93
   * @btn_cnt: number of buttons
   * @sp_btn_cnt: number of stick buttons
   */
73196ebe1   Masaki Ota   HID: alps: add su...
94
  struct alps_dev {
2562756dd   Masaki Ota   HID: add Alps I2C...
95
96
97
  	struct input_dev *input;
  	struct input_dev *input2;
  	struct hid_device *hdev;
73196ebe1   Masaki Ota   HID: alps: add su...
98
  	enum dev_num dev_type;
5992262d5   Masaki Ota   HID: alps: remove...
99
100
  	u8  max_fingers;
  	u8  has_sp;
2562756dd   Masaki Ota   HID: add Alps I2C...
101
102
103
104
105
  	u8	sp_btn_info;
  	u32	x_active_len_mm;
  	u32	y_active_len_mm;
  	u32	x_max;
  	u32	y_max;
c7083d3f5   Masaki Ota   HID: alps: proper...
106
107
  	u32	x_min;
  	u32	y_min;
2562756dd   Masaki Ota   HID: add Alps I2C...
108
109
110
  	u32	btn_cnt;
  	u32	sp_btn_cnt;
  };
73196ebe1   Masaki Ota   HID: alps: add su...
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
  struct t4_contact_data {
  	u8  palm;
  	u8	x_lo;
  	u8	x_hi;
  	u8	y_lo;
  	u8	y_hi;
  };
  
  struct t4_input_report {
  	u8  reportID;
  	u8  numContacts;
  	struct t4_contact_data contact[5];
  	u8  button;
  	u8  track[5];
  	u8  zx[5], zy[5];
  	u8  palmTime[5];
  	u8  kilroy;
  	u16 timeStamp;
  };
  
  static u16 t4_calc_check_sum(u8 *buffer,
  		unsigned long offset, unsigned long length)
  {
  	u16 sum1 = 0xFF, sum2 = 0xFF;
  	unsigned long i = 0;
  
  	if (offset + length >= 50)
  		return 0;
  
  	while (length > 0) {
  		u32 tlen = length > 20 ? 20 : length;
  
  		length -= tlen;
  
  		do {
  			sum1 += buffer[offset + i];
  			sum2 += sum1;
  			i++;
  		} while (--tlen > 0);
  
  		sum1 = (sum1 & 0xFF) + (sum1 >> 8);
  		sum2 = (sum2 & 0xFF) + (sum2 >> 8);
  	}
  
  	sum1 = (sum1 & 0xFF) + (sum1 >> 8);
  	sum2 = (sum2 & 0xFF) + (sum2 >> 8);
  
  	return(sum2 << 8 | sum1);
  }
  
  static int t4_read_write_register(struct hid_device *hdev, u32 address,
  	u8 *read_val, u8 write_val, bool read_flag)
  {
  	int ret;
  	u16 check_sum;
  	u8 *input;
edb6cb3d7   Christophe JAILLET   HID: alps: Save a...
167
  	u8 *readbuf = NULL;
73196ebe1   Masaki Ota   HID: alps: add su...
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
  
  	input = kzalloc(T4_FEATURE_REPORT_LEN, GFP_KERNEL);
  	if (!input)
  		return -ENOMEM;
  
  	input[0] = T4_FEATURE_REPORT_ID;
  	if (read_flag) {
  		input[1] = T4_CMD_REGISTER_READ;
  		input[8] = 0x00;
  	} else {
  		input[1] = T4_CMD_REGISTER_WRITE;
  		input[8] = write_val;
  	}
  	put_unaligned_le32(address, input + 2);
  	input[6] = 1;
  	input[7] = 0;
  
  	/* Calculate the checksum */
  	check_sum = t4_calc_check_sum(input, 1, 8);
  	input[9] = (u8)check_sum;
  	input[10] = (u8)(check_sum >> 8);
  	input[11] = 0;
  
  	ret = hid_hw_raw_request(hdev, T4_FEATURE_REPORT_ID, input,
  			T4_FEATURE_REPORT_LEN,
  			HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
  
  	if (ret < 0) {
  		dev_err(&hdev->dev, "failed to read command (%d)
  ", ret);
  		goto exit;
  	}
73196ebe1   Masaki Ota   HID: alps: add su...
200
  	if (read_flag) {
edb6cb3d7   Christophe JAILLET   HID: alps: Save a...
201
  		readbuf = kzalloc(T4_FEATURE_REPORT_LEN, GFP_KERNEL);
73196ebe1   Masaki Ota   HID: alps: add su...
202
203
204
205
206
207
208
209
210
211
212
213
214
  		if (!readbuf) {
  			ret = -ENOMEM;
  			goto exit;
  		}
  
  		ret = hid_hw_raw_request(hdev, T4_FEATURE_REPORT_ID, readbuf,
  				T4_FEATURE_REPORT_LEN,
  				HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
  		if (ret < 0) {
  			dev_err(&hdev->dev, "failed read register (%d)
  ", ret);
  			goto exit_readbuf;
  		}
605f07729   Christophe JAILLET   HID: alps: Report...
215
  		ret = -EINVAL;
73196ebe1   Masaki Ota   HID: alps: add su...
216
217
218
  		if (*(u32 *)&readbuf[6] != address) {
  			dev_err(&hdev->dev, "read register address error (%x,%x)
  ",
a317e5595   Christophe JAILLET   HID: alps: Fix so...
219
  				*(u32 *)&readbuf[6], address);
73196ebe1   Masaki Ota   HID: alps: add su...
220
221
222
223
224
225
  			goto exit_readbuf;
  		}
  
  		if (*(u16 *)&readbuf[10] != 1) {
  			dev_err(&hdev->dev, "read register size error (%x)
  ",
a317e5595   Christophe JAILLET   HID: alps: Fix so...
226
  				*(u16 *)&readbuf[10]);
73196ebe1   Masaki Ota   HID: alps: add su...
227
228
229
230
231
232
233
  			goto exit_readbuf;
  		}
  
  		check_sum = t4_calc_check_sum(readbuf, 6, 7);
  		if (*(u16 *)&readbuf[13] != check_sum) {
  			dev_err(&hdev->dev, "read register checksum error (%x,%x)
  ",
a317e5595   Christophe JAILLET   HID: alps: Fix so...
234
  				*(u16 *)&readbuf[13], check_sum);
73196ebe1   Masaki Ota   HID: alps: add su...
235
236
237
238
239
240
241
242
243
244
245
246
247
248
  			goto exit_readbuf;
  		}
  
  		*read_val = readbuf[12];
  	}
  
  	ret = 0;
  
  exit_readbuf:
  	kfree(readbuf);
  exit:
  	kfree(input);
  	return ret;
  }
2562756dd   Masaki Ota   HID: add Alps I2C...
249
250
251
252
253
254
255
  static int u1_read_write_register(struct hid_device *hdev, u32 address,
  	u8 *read_val, u8 write_val, bool read_flag)
  {
  	int ret, i;
  	u8 check_sum;
  	u8 *input;
  	u8 *readbuf;
819d64e51   Masaki Ota   HID: alps: a few ...
256
  	input = kzalloc(U1_FEATURE_REPORT_LEN, GFP_KERNEL);
2562756dd   Masaki Ota   HID: add Alps I2C...
257
258
  	if (!input)
  		return -ENOMEM;
2562756dd   Masaki Ota   HID: add Alps I2C...
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
  	input[0] = U1_FEATURE_REPORT_ID;
  	if (read_flag) {
  		input[1] = U1_CMD_REGISTER_READ;
  		input[6] = 0x00;
  	} else {
  		input[1] = U1_CMD_REGISTER_WRITE;
  		input[6] = write_val;
  	}
  
  	put_unaligned_le32(address, input + 2);
  
  	/* Calculate the checksum */
  	check_sum = U1_FEATURE_REPORT_LEN_ALL;
  	for (i = 0; i < U1_FEATURE_REPORT_LEN - 1; i++)
  		check_sum += input[i];
  
  	input[7] = check_sum;
  	ret = hid_hw_raw_request(hdev, U1_FEATURE_REPORT_ID, input,
819d64e51   Masaki Ota   HID: alps: a few ...
277
278
  			U1_FEATURE_REPORT_LEN,
  			HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
2562756dd   Masaki Ota   HID: add Alps I2C...
279
280
281
282
283
284
285
286
  
  	if (ret < 0) {
  		dev_err(&hdev->dev, "failed to read command (%d)
  ", ret);
  		goto exit;
  	}
  
  	if (read_flag) {
819d64e51   Masaki Ota   HID: alps: a few ...
287
288
  		readbuf = kzalloc(U1_FEATURE_REPORT_LEN, GFP_KERNEL);
  		if (!readbuf) {
7ee2eaa36   Axel Lin   HID: alps: Fix me...
289
290
  			ret = -ENOMEM;
  			goto exit;
819d64e51   Masaki Ota   HID: alps: a few ...
291
  		}
2562756dd   Masaki Ota   HID: add Alps I2C...
292
  		ret = hid_hw_raw_request(hdev, U1_FEATURE_REPORT_ID, readbuf,
819d64e51   Masaki Ota   HID: alps: a few ...
293
  				U1_FEATURE_REPORT_LEN,
63b3a7d0f   Jiri Kosina   HID: alps: pass c...
294
  				HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
2562756dd   Masaki Ota   HID: add Alps I2C...
295
296
297
298
  
  		if (ret < 0) {
  			dev_err(&hdev->dev, "failed read register (%d)
  ", ret);
7ee2eaa36   Axel Lin   HID: alps: Fix me...
299
  			kfree(readbuf);
2562756dd   Masaki Ota   HID: add Alps I2C...
300
301
302
303
  			goto exit;
  		}
  
  		*read_val = readbuf[6];
819d64e51   Masaki Ota   HID: alps: a few ...
304
305
  
  		kfree(readbuf);
2562756dd   Masaki Ota   HID: add Alps I2C...
306
  	}
819d64e51   Masaki Ota   HID: alps: a few ...
307
  	ret = 0;
2562756dd   Masaki Ota   HID: add Alps I2C...
308
309
310
  
  exit:
  	kfree(input);
2562756dd   Masaki Ota   HID: add Alps I2C...
311
312
  	return ret;
  }
73196ebe1   Masaki Ota   HID: alps: add su...
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
  static int t4_raw_event(struct alps_dev *hdata, u8 *data, int size)
  {
  	unsigned int x, y, z;
  	int i;
  	struct t4_input_report *p_report = (struct t4_input_report *)data;
  
  	if (!data)
  		return 0;
  	for (i = 0; i < hdata->max_fingers; i++) {
  		x = p_report->contact[i].x_hi << 8 | p_report->contact[i].x_lo;
  		y = p_report->contact[i].y_hi << 8 | p_report->contact[i].y_lo;
  		y = hdata->y_max - y + hdata->y_min;
  		z = (p_report->contact[i].palm < 0x80 &&
  			p_report->contact[i].palm > 0) * 62;
  		if (x == 0xffff) {
  			x = 0;
  			y = 0;
  			z = 0;
  		}
  		input_mt_slot(hdata->input, i);
  
  		input_mt_report_slot_state(hdata->input,
  			MT_TOOL_FINGER, z != 0);
  
  		if (!z)
  			continue;
  
  		input_report_abs(hdata->input, ABS_MT_POSITION_X, x);
  		input_report_abs(hdata->input, ABS_MT_POSITION_Y, y);
  		input_report_abs(hdata->input, ABS_MT_PRESSURE, z);
  	}
  	input_mt_sync_frame(hdata->input);
  
  	input_report_key(hdata->input, BTN_LEFT, p_report->button);
  
  	input_sync(hdata->input);
  	return 1;
  }
  
  static int u1_raw_event(struct alps_dev *hdata, u8 *data, int size)
2562756dd   Masaki Ota   HID: add Alps I2C...
353
  {
819d64e51   Masaki Ota   HID: alps: a few ...
354
355
356
  	unsigned int x, y, z;
  	int i;
  	short sp_x, sp_y;
2562756dd   Masaki Ota   HID: add Alps I2C...
357

73196ebe1   Masaki Ota   HID: alps: add su...
358
359
  	if (!data)
  		return 0;
2562756dd   Masaki Ota   HID: add Alps I2C...
360
361
362
363
364
365
  	switch (data[0]) {
  	case U1_MOUSE_REPORT_ID:
  		break;
  	case U1_FEATURE_REPORT_ID:
  		break;
  	case U1_ABSOLUTE_REPORT_ID:
aa3c439c1   Caiyuan Xie   HID: alps: suppor...
366
  	case U1_ABSOLUTE_REPORT_ID_SECD:
73196ebe1   Masaki Ota   HID: alps: add su...
367
  		for (i = 0; i < hdata->max_fingers; i++) {
819d64e51   Masaki Ota   HID: alps: a few ...
368
369
370
371
372
  			u8 *contact = &data[i * 5];
  
  			x = get_unaligned_le16(contact + 3);
  			y = get_unaligned_le16(contact + 5);
  			z = contact[7] & 0x7F;
2562756dd   Masaki Ota   HID: add Alps I2C...
373
374
  
  			input_mt_slot(hdata->input, i);
819d64e51   Masaki Ota   HID: alps: a few ...
375
  			if (z != 0) {
2562756dd   Masaki Ota   HID: add Alps I2C...
376
377
  				input_mt_report_slot_state(hdata->input,
  					MT_TOOL_FINGER, 1);
9a54cf462   Masaki Ota   HID: alps: fix mu...
378
379
380
381
382
383
  				input_report_abs(hdata->input,
  					ABS_MT_POSITION_X, x);
  				input_report_abs(hdata->input,
  					ABS_MT_POSITION_Y, y);
  				input_report_abs(hdata->input,
  					ABS_MT_PRESSURE, z);
2562756dd   Masaki Ota   HID: add Alps I2C...
384
  			} else {
5fc70e350   Jiada Wang   Input: introduce ...
385
  				input_mt_report_slot_inactive(hdata->input);
2562756dd   Masaki Ota   HID: add Alps I2C...
386
  			}
2562756dd   Masaki Ota   HID: add Alps I2C...
387
388
389
  		}
  
  		input_mt_sync_frame(hdata->input);
2562756dd   Masaki Ota   HID: add Alps I2C...
390

819d64e51   Masaki Ota   HID: alps: a few ...
391
392
393
394
395
396
397
398
  		input_report_key(hdata->input, BTN_LEFT,
  			data[1] & 0x1);
  		input_report_key(hdata->input, BTN_RIGHT,
  			(data[1] & 0x2));
  		input_report_key(hdata->input, BTN_MIDDLE,
  			(data[1] & 0x4));
  
  		input_sync(hdata->input);
2562756dd   Masaki Ota   HID: add Alps I2C...
399
400
401
402
  
  		return 1;
  
  	case U1_SP_ABSOLUTE_REPORT_ID:
819d64e51   Masaki Ota   HID: alps: a few ...
403
404
  		sp_x = get_unaligned_le16(data+2);
  		sp_y = get_unaligned_le16(data+4);
2562756dd   Masaki Ota   HID: add Alps I2C...
405
406
407
  
  		sp_x = sp_x / 8;
  		sp_y = sp_y / 8;
819d64e51   Masaki Ota   HID: alps: a few ...
408
409
  		input_report_rel(hdata->input2, REL_X, sp_x);
  		input_report_rel(hdata->input2, REL_Y, sp_y);
2562756dd   Masaki Ota   HID: add Alps I2C...
410

819d64e51   Masaki Ota   HID: alps: a few ...
411
412
413
414
415
416
  		input_report_key(hdata->input2, BTN_LEFT,
  			data[1] & 0x1);
  		input_report_key(hdata->input2, BTN_RIGHT,
  			(data[1] & 0x2));
  		input_report_key(hdata->input2, BTN_MIDDLE,
  			(data[1] & 0x4));
2562756dd   Masaki Ota   HID: add Alps I2C...
417

819d64e51   Masaki Ota   HID: alps: a few ...
418
  		input_sync(hdata->input2);
2562756dd   Masaki Ota   HID: add Alps I2C...
419
420
421
422
423
424
  
  		return 1;
  	}
  
  	return 0;
  }
73196ebe1   Masaki Ota   HID: alps: add su...
425
426
  static int alps_raw_event(struct hid_device *hdev,
  		struct hid_report *report, u8 *data, int size)
2562756dd   Masaki Ota   HID: add Alps I2C...
427
  {
73196ebe1   Masaki Ota   HID: alps: add su...
428
429
430
431
432
433
434
435
436
437
438
439
  	int ret = 0;
  	struct alps_dev *hdata = hid_get_drvdata(hdev);
  
  	switch (hdev->product) {
  	case HID_PRODUCT_ID_T4_BTNLESS:
  		ret = t4_raw_event(hdata, data, size);
  		break;
  	default:
  		ret = u1_raw_event(hdata, data, size);
  		break;
  	}
  	return ret;
2562756dd   Masaki Ota   HID: add Alps I2C...
440
  }
73196ebe1   Masaki Ota   HID: alps: add su...
441
  static int __maybe_unused alps_post_reset(struct hid_device *hdev)
2562756dd   Masaki Ota   HID: add Alps I2C...
442
  {
73196ebe1   Masaki Ota   HID: alps: add su...
443
444
445
446
447
448
449
  	int ret = -1;
  	struct alps_dev *data = hid_get_drvdata(hdev);
  
  	switch (data->dev_type) {
  	case T4:
  		ret = t4_read_write_register(hdev, T4_PRM_FEED_CONFIG_1,
  			NULL, T4_I2C_ABS, false);
69934012f   Christophe JAILLET   HID: alps: Check ...
450
451
452
453
454
455
  		if (ret < 0) {
  			dev_err(&hdev->dev, "failed T4_PRM_FEED_CONFIG_1 (%d)
  ",
  				ret);
  			goto exit;
  		}
73196ebe1   Masaki Ota   HID: alps: add su...
456
457
  		ret = t4_read_write_register(hdev, T4_PRM_FEED_CONFIG_4,
  			NULL, T4_FEEDCFG4_ADVANCED_ABS_ENABLE, false);
69934012f   Christophe JAILLET   HID: alps: Check ...
458
459
460
461
462
463
  		if (ret < 0) {
  			dev_err(&hdev->dev, "failed T4_PRM_FEED_CONFIG_4 (%d)
  ",
  				ret);
  			goto exit;
  		}
73196ebe1   Masaki Ota   HID: alps: add su...
464
465
466
467
468
  		break;
  	case U1:
  		ret = u1_read_write_register(hdev,
  			ADDRESS_U1_DEV_CTRL_1, NULL,
  			U1_TP_ABS_MODE | U1_SP_ABS_MODE, false);
69934012f   Christophe JAILLET   HID: alps: Check ...
469
470
471
472
473
474
  		if (ret < 0) {
  			dev_err(&hdev->dev, "failed to change TP mode (%d)
  ",
  				ret);
  			goto exit;
  		}
73196ebe1   Masaki Ota   HID: alps: add su...
475
476
477
478
  		break;
  	default:
  		break;
  	}
69934012f   Christophe JAILLET   HID: alps: Check ...
479
480
  
  exit:
73196ebe1   Masaki Ota   HID: alps: add su...
481
482
483
484
485
486
  	return ret;
  }
  
  static int __maybe_unused alps_post_resume(struct hid_device *hdev)
  {
  	return alps_post_reset(hdev);
2562756dd   Masaki Ota   HID: add Alps I2C...
487
  }
2562756dd   Masaki Ota   HID: add Alps I2C...
488

73196ebe1   Masaki Ota   HID: alps: add su...
489
  static int u1_init(struct hid_device *hdev, struct alps_dev *pri_data)
2562756dd   Masaki Ota   HID: add Alps I2C...
490
  {
2562756dd   Masaki Ota   HID: add Alps I2C...
491
  	int ret;
5992262d5   Masaki Ota   HID: alps: remove...
492
493
  	u8 tmp, dev_ctrl, sen_line_num_x, sen_line_num_y;
  	u8 pitch_x, pitch_y, resolution;
2562756dd   Masaki Ota   HID: add Alps I2C...
494
495
496
  
  	/* Device initialization */
  	ret = u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1,
5992262d5   Masaki Ota   HID: alps: remove...
497
  			&dev_ctrl, 0, true);
2562756dd   Masaki Ota   HID: add Alps I2C...
498
499
500
501
502
  	if (ret < 0) {
  		dev_err(&hdev->dev, "failed U1_DEV_CTRL_1 (%d)
  ", ret);
  		goto exit;
  	}
5992262d5   Masaki Ota   HID: alps: remove...
503
504
  	dev_ctrl &= ~U1_DISABLE_DEV;
  	dev_ctrl |= U1_TP_ABS_MODE;
2562756dd   Masaki Ota   HID: add Alps I2C...
505
  	ret = u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1,
5992262d5   Masaki Ota   HID: alps: remove...
506
  			NULL, dev_ctrl, false);
2562756dd   Masaki Ota   HID: add Alps I2C...
507
508
509
510
511
512
513
  	if (ret < 0) {
  		dev_err(&hdev->dev, "failed to change TP mode (%d)
  ", ret);
  		goto exit;
  	}
  
  	ret = u1_read_write_register(hdev, ADDRESS_U1_NUM_SENS_X,
5992262d5   Masaki Ota   HID: alps: remove...
514
  			&sen_line_num_x, 0, true);
2562756dd   Masaki Ota   HID: add Alps I2C...
515
516
517
518
519
520
521
  	if (ret < 0) {
  		dev_err(&hdev->dev, "failed U1_NUM_SENS_X (%d)
  ", ret);
  		goto exit;
  	}
  
  	ret = u1_read_write_register(hdev, ADDRESS_U1_NUM_SENS_Y,
5992262d5   Masaki Ota   HID: alps: remove...
522
  			&sen_line_num_y, 0, true);
2c3468893   Colin Ian King   HID: alps: clean ...
523
  	if (ret < 0) {
2562756dd   Masaki Ota   HID: add Alps I2C...
524
525
526
527
528
529
  		dev_err(&hdev->dev, "failed U1_NUM_SENS_Y (%d)
  ", ret);
  		goto exit;
  	}
  
  	ret = u1_read_write_register(hdev, ADDRESS_U1_PITCH_SENS_X,
5992262d5   Masaki Ota   HID: alps: remove...
530
  			&pitch_x, 0, true);
2562756dd   Masaki Ota   HID: add Alps I2C...
531
532
533
534
535
536
537
  	if (ret < 0) {
  		dev_err(&hdev->dev, "failed U1_PITCH_SENS_X (%d)
  ", ret);
  		goto exit;
  	}
  
  	ret = u1_read_write_register(hdev, ADDRESS_U1_PITCH_SENS_Y,
5992262d5   Masaki Ota   HID: alps: remove...
538
  			&pitch_y, 0, true);
2562756dd   Masaki Ota   HID: add Alps I2C...
539
540
541
542
543
544
545
  	if (ret < 0) {
  		dev_err(&hdev->dev, "failed U1_PITCH_SENS_Y (%d)
  ", ret);
  		goto exit;
  	}
  
  	ret = u1_read_write_register(hdev, ADDRESS_U1_RESO_DWN_ABS,
5992262d5   Masaki Ota   HID: alps: remove...
546
  		&resolution, 0, true);
2562756dd   Masaki Ota   HID: add Alps I2C...
547
548
549
550
551
  	if (ret < 0) {
  		dev_err(&hdev->dev, "failed U1_RESO_DWN_ABS (%d)
  ", ret);
  		goto exit;
  	}
5d8c720d3   Masaki Ota   HID: alps: Separa...
552
  	pri_data->x_active_len_mm =
5992262d5   Masaki Ota   HID: alps: remove...
553
  		(pitch_x * (sen_line_num_x - 1)) / 10;
5d8c720d3   Masaki Ota   HID: alps: Separa...
554
  	pri_data->y_active_len_mm =
5992262d5   Masaki Ota   HID: alps: remove...
555
  		(pitch_y * (sen_line_num_y - 1)) / 10;
5d8c720d3   Masaki Ota   HID: alps: Separa...
556
557
  
  	pri_data->x_max =
5992262d5   Masaki Ota   HID: alps: remove...
558
  		(resolution << 2) * (sen_line_num_x - 1);
c7083d3f5   Masaki Ota   HID: alps: proper...
559
  	pri_data->x_min = 1;
5d8c720d3   Masaki Ota   HID: alps: Separa...
560
  	pri_data->y_max =
5992262d5   Masaki Ota   HID: alps: remove...
561
  		(resolution << 2) * (sen_line_num_y - 1);
c7083d3f5   Masaki Ota   HID: alps: proper...
562
  	pri_data->y_min = 1;
2562756dd   Masaki Ota   HID: add Alps I2C...
563
564
  
  	ret = u1_read_write_register(hdev, ADDRESS_U1_PAD_BTN,
5992262d5   Masaki Ota   HID: alps: remove...
565
  			&tmp, 0, true);
2562756dd   Masaki Ota   HID: add Alps I2C...
566
567
568
569
570
  	if (ret < 0) {
  		dev_err(&hdev->dev, "failed U1_PAD_BTN (%d)
  ", ret);
  		goto exit;
  	}
5992262d5   Masaki Ota   HID: alps: remove...
571
572
  	if ((tmp & 0x0F) == (tmp & 0xF0) >> 4) {
  		pri_data->btn_cnt = (tmp & 0x0F);
c7083d3f5   Masaki Ota   HID: alps: proper...
573
574
575
576
  	} else {
  		/* Button pad */
  		pri_data->btn_cnt = 1;
  	}
2562756dd   Masaki Ota   HID: add Alps I2C...
577

5d8c720d3   Masaki Ota   HID: alps: Separa...
578
  	pri_data->has_sp = 0;
2562756dd   Masaki Ota   HID: add Alps I2C...
579
580
  	/* Check StickPointer device */
  	ret = u1_read_write_register(hdev, ADDRESS_U1_DEVICE_TYP,
5992262d5   Masaki Ota   HID: alps: remove...
581
  			&tmp, 0, true);
2562756dd   Masaki Ota   HID: add Alps I2C...
582
583
584
585
586
  	if (ret < 0) {
  		dev_err(&hdev->dev, "failed U1_DEVICE_TYP (%d)
  ", ret);
  		goto exit;
  	}
5992262d5   Masaki Ota   HID: alps: remove...
587
588
  	if (tmp & U1_DEVTYPE_SP_SUPPORT) {
  		dev_ctrl |= U1_SP_ABS_MODE;
5d8c720d3   Masaki Ota   HID: alps: Separa...
589
  		ret = u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1,
5992262d5   Masaki Ota   HID: alps: remove...
590
  			NULL, dev_ctrl, false);
5d8c720d3   Masaki Ota   HID: alps: Separa...
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
  		if (ret < 0) {
  			dev_err(&hdev->dev, "failed SP mode (%d)
  ", ret);
  			goto exit;
  		}
  
  		ret = u1_read_write_register(hdev, ADDRESS_U1_SP_BTN,
  			&pri_data->sp_btn_info, 0, true);
  		if (ret < 0) {
  			dev_err(&hdev->dev, "failed U1_SP_BTN (%d)
  ", ret);
  			goto exit;
  		}
  		pri_data->has_sp = 1;
  	}
c7083d3f5   Masaki Ota   HID: alps: proper...
606
  	pri_data->max_fingers = 5;
5d8c720d3   Masaki Ota   HID: alps: Separa...
607
608
609
  exit:
  	return ret;
  }
73196ebe1   Masaki Ota   HID: alps: add su...
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
  static int T4_init(struct hid_device *hdev, struct alps_dev *pri_data)
  {
  	int ret;
  	u8 tmp, sen_line_num_x, sen_line_num_y;
  
  	ret = t4_read_write_register(hdev, T4_PRM_ID_CONFIG_3, &tmp, 0, true);
  	if (ret < 0) {
  		dev_err(&hdev->dev, "failed T4_PRM_ID_CONFIG_3 (%d)
  ", ret);
  		goto exit;
  	}
  	sen_line_num_x = 16 + ((tmp & 0x0F)  | (tmp & 0x08 ? 0xF0 : 0));
  	sen_line_num_y = 12 + (((tmp & 0xF0) >> 4)  | (tmp & 0x80 ? 0xF0 : 0));
  
  	pri_data->x_max = sen_line_num_x * T4_COUNT_PER_ELECTRODE;
  	pri_data->x_min = T4_COUNT_PER_ELECTRODE;
  	pri_data->y_max = sen_line_num_y * T4_COUNT_PER_ELECTRODE;
  	pri_data->y_min = T4_COUNT_PER_ELECTRODE;
  	pri_data->x_active_len_mm = pri_data->y_active_len_mm = 0;
  	pri_data->btn_cnt = 1;
  
  	ret = t4_read_write_register(hdev, PRM_SYS_CONFIG_1, &tmp, 0, true);
  	if (ret < 0) {
  		dev_err(&hdev->dev, "failed PRM_SYS_CONFIG_1 (%d)
  ", ret);
  		goto exit;
  	}
  	tmp |= 0x02;
  	ret = t4_read_write_register(hdev, PRM_SYS_CONFIG_1, NULL, tmp, false);
  	if (ret < 0) {
  		dev_err(&hdev->dev, "failed PRM_SYS_CONFIG_1 (%d)
  ", ret);
  		goto exit;
  	}
  
  	ret = t4_read_write_register(hdev, T4_PRM_FEED_CONFIG_1,
  					NULL, T4_I2C_ABS, false);
  	if (ret < 0) {
  		dev_err(&hdev->dev, "failed T4_PRM_FEED_CONFIG_1 (%d)
  ", ret);
  		goto exit;
  	}
  
  	ret = t4_read_write_register(hdev, T4_PRM_FEED_CONFIG_4, NULL,
  				T4_FEEDCFG4_ADVANCED_ABS_ENABLE, false);
  	if (ret < 0) {
  		dev_err(&hdev->dev, "failed T4_PRM_FEED_CONFIG_4 (%d)
  ", ret);
  		goto exit;
  	}
  	pri_data->max_fingers = 5;
  	pri_data->has_sp = 0;
  exit:
  	return ret;
  }
7dd8db689   Benjamin Tissoires   HID: alps: allow ...
665
666
667
668
669
670
671
672
673
674
675
676
677
  static int alps_sp_open(struct input_dev *dev)
  {
  	struct hid_device *hid = input_get_drvdata(dev);
  
  	return hid_hw_open(hid);
  }
  
  static void alps_sp_close(struct input_dev *dev)
  {
  	struct hid_device *hid = input_get_drvdata(dev);
  
  	hid_hw_close(hid);
  }
5d8c720d3   Masaki Ota   HID: alps: Separa...
678
679
  static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi)
  {
73196ebe1   Masaki Ota   HID: alps: add su...
680
  	struct alps_dev *data = hid_get_drvdata(hdev);
5d8c720d3   Masaki Ota   HID: alps: Separa...
681
682
683
684
685
686
687
688
689
690
691
692
693
694
  	struct input_dev *input = hi->input, *input2;
  	int ret;
  	int res_x, res_y, i;
  
  	data->input = input;
  
  	hid_dbg(hdev, "Opening low level driver
  ");
  	ret = hid_hw_open(hdev);
  	if (ret)
  		return ret;
  
  	/* Allow incoming hid reports */
  	hid_device_io_start(hdev);
73196ebe1   Masaki Ota   HID: alps: add su...
695
696
697
698
699
700
701
702
703
704
  	switch (data->dev_type) {
  	case T4:
  		ret = T4_init(hdev, data);
  		break;
  	case U1:
  		ret = u1_init(hdev, data);
  		break;
  	default:
  		break;
  	}
5d8c720d3   Masaki Ota   HID: alps: Separa...
705
706
707
  
  	if (ret)
  		goto exit;
2562756dd   Masaki Ota   HID: add Alps I2C...
708
709
  
  	__set_bit(EV_ABS, input->evbit);
c7083d3f5   Masaki Ota   HID: alps: proper...
710
711
712
713
  	input_set_abs_params(input, ABS_MT_POSITION_X,
  						data->x_min, data->x_max, 0, 0);
  	input_set_abs_params(input, ABS_MT_POSITION_Y,
  						data->y_min, data->y_max, 0, 0);
2562756dd   Masaki Ota   HID: add Alps I2C...
714

ce6abcf83   Masaki Ota   HID: alps: delete...
715
716
717
  	if (data->x_active_len_mm && data->y_active_len_mm) {
  		res_x = (data->x_max - 1) / data->x_active_len_mm;
  		res_y = (data->y_max - 1) / data->y_active_len_mm;
2562756dd   Masaki Ota   HID: add Alps I2C...
718
719
720
721
722
723
  
  		input_abs_set_res(input, ABS_MT_POSITION_X, res_x);
  		input_abs_set_res(input, ABS_MT_POSITION_Y, res_y);
  	}
  
  	input_set_abs_params(input, ABS_MT_PRESSURE, 0, 64, 0, 0);
c7083d3f5   Masaki Ota   HID: alps: proper...
724
  	input_mt_init_slots(input, data->max_fingers, INPUT_MT_POINTER);
2562756dd   Masaki Ota   HID: add Alps I2C...
725
726
  
  	__set_bit(EV_KEY, input->evbit);
c7083d3f5   Masaki Ota   HID: alps: proper...
727
728
  
  	if (data->btn_cnt == 1)
2562756dd   Masaki Ota   HID: add Alps I2C...
729
  		__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
2562756dd   Masaki Ota   HID: add Alps I2C...
730

ce6abcf83   Masaki Ota   HID: alps: delete...
731
  	for (i = 0; i < data->btn_cnt; i++)
2562756dd   Masaki Ota   HID: add Alps I2C...
732
  		__set_bit(BTN_LEFT + i, input->keybit);
2562756dd   Masaki Ota   HID: add Alps I2C...
733
  	/* Stick device initialization */
5d8c720d3   Masaki Ota   HID: alps: Separa...
734
  	if (data->has_sp) {
2562756dd   Masaki Ota   HID: add Alps I2C...
735
736
  		input2 = input_allocate_device();
  		if (!input2) {
8d2e77b39   Christophe JAILLET   HID: alps: Fix an...
737
  			ret = -ENOMEM;
2562756dd   Masaki Ota   HID: add Alps I2C...
738
739
  			goto exit;
  		}
819d64e51   Masaki Ota   HID: alps: a few ...
740
  		data->input2 = input2;
2562756dd   Masaki Ota   HID: add Alps I2C...
741
742
743
744
745
746
747
  		input2->phys = input->phys;
  		input2->name = "DualPoint Stick";
  		input2->id.bustype = BUS_I2C;
  		input2->id.vendor  = input->id.vendor;
  		input2->id.product = input->id.product;
  		input2->id.version = input->id.version;
  		input2->dev.parent = input->dev.parent;
7dd8db689   Benjamin Tissoires   HID: alps: allow ...
748
749
750
  		input_set_drvdata(input2, hdev);
  		input2->open = alps_sp_open;
  		input2->close = alps_sp_close;
2562756dd   Masaki Ota   HID: add Alps I2C...
751
  		__set_bit(EV_KEY, input2->evbit);
ce6abcf83   Masaki Ota   HID: alps: delete...
752
753
  		data->sp_btn_cnt = (data->sp_btn_info & 0x0F);
  		for (i = 0; i < data->sp_btn_cnt; i++)
2562756dd   Masaki Ota   HID: add Alps I2C...
754
755
756
757
758
759
760
  			__set_bit(BTN_LEFT + i, input2->keybit);
  
  		__set_bit(EV_REL, input2->evbit);
  		__set_bit(REL_X, input2->relbit);
  		__set_bit(REL_Y, input2->relbit);
  		__set_bit(INPUT_PROP_POINTER, input2->propbit);
  		__set_bit(INPUT_PROP_POINTING_STICK, input2->propbit);
c7083d3f5   Masaki Ota   HID: alps: proper...
761
  		if (input_register_device(data->input2)) {
2562756dd   Masaki Ota   HID: add Alps I2C...
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
  			input_free_device(input2);
  			goto exit;
  		}
  	}
  
  exit:
  	hid_device_io_stop(hdev);
  	hid_hw_close(hdev);
  	return ret;
  }
  
  static int alps_input_mapping(struct hid_device *hdev,
  		struct hid_input *hi, struct hid_field *field,
  		struct hid_usage *usage, unsigned long **bit, int *max)
  {
  	return -1;
  }
  
  static int alps_probe(struct hid_device *hdev, const struct hid_device_id *id)
  {
73196ebe1   Masaki Ota   HID: alps: add su...
782
  	struct alps_dev *data = NULL;
2562756dd   Masaki Ota   HID: add Alps I2C...
783
  	int ret;
73196ebe1   Masaki Ota   HID: alps: add su...
784
  	data = devm_kzalloc(&hdev->dev, sizeof(struct alps_dev), GFP_KERNEL);
2562756dd   Masaki Ota   HID: add Alps I2C...
785
786
787
788
789
790
791
792
793
794
795
796
797
798
  	if (!data)
  		return -ENOMEM;
  
  	data->hdev = hdev;
  	hid_set_drvdata(hdev, data);
  
  	hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS;
  
  	ret = hid_parse(hdev);
  	if (ret) {
  		hid_err(hdev, "parse failed
  ");
  		return ret;
  	}
73196ebe1   Masaki Ota   HID: alps: add su...
799
800
801
802
803
  	switch (hdev->product) {
  	case HID_DEVICE_ID_ALPS_T4_BTNLESS:
  		data->dev_type = T4;
  		break;
  	case HID_DEVICE_ID_ALPS_U1_DUAL:
287b8e119   Masaki Ota   HID: alps: add ne...
804
  	case HID_DEVICE_ID_ALPS_U1:
185af3e77   Jiri Kosina   HID: alps: ALPS_1...
805
  	case HID_DEVICE_ID_ALPS_U1_UNICORN_LEGACY:
73196ebe1   Masaki Ota   HID: alps: add su...
806
807
808
809
810
  		data->dev_type = U1;
  		break;
  	default:
  		data->dev_type = UNKNOWN;
  	}
2562756dd   Masaki Ota   HID: add Alps I2C...
811
812
813
814
815
816
817
818
819
820
821
822
823
  	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
  	if (ret) {
  		hid_err(hdev, "hw start failed
  ");
  		return ret;
  	}
  
  	return 0;
  }
  
  static void alps_remove(struct hid_device *hdev)
  {
  	hid_hw_stop(hdev);
2562756dd   Masaki Ota   HID: add Alps I2C...
824
825
826
827
  }
  
  static const struct hid_device_id alps_id[] = {
  	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY,
819d64e51   Masaki Ota   HID: alps: a few ...
828
  		USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL) },
73196ebe1   Masaki Ota   HID: alps: add su...
829
  	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY,
287b8e119   Masaki Ota   HID: alps: add ne...
830
831
  		USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1) },
  	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY,
73196ebe1   Masaki Ota   HID: alps: add su...
832
  		USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_T4_BTNLESS) },
2562756dd   Masaki Ota   HID: add Alps I2C...
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
  	{ }
  };
  MODULE_DEVICE_TABLE(hid, alps_id);
  
  static struct hid_driver alps_driver = {
  	.name = "hid-alps",
  	.id_table		= alps_id,
  	.probe			= alps_probe,
  	.remove			= alps_remove,
  	.raw_event		= alps_raw_event,
  	.input_mapping		= alps_input_mapping,
  	.input_configured	= alps_input_configured,
  #ifdef CONFIG_PM
  	.resume			= alps_post_resume,
  	.reset_resume		= alps_post_reset,
  #endif
  };
  
  module_hid_driver(alps_driver);
  
  MODULE_AUTHOR("Masaki Ota <masaki.ota@jp.alps.com>");
  MODULE_DESCRIPTION("ALPS HID driver");
  MODULE_LICENSE("GPL");