19c92ab61SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2c7efd123SYoichi Yuasa /*
3c7efd123SYoichi Yuasa * ROHM BU21023/24 Dual touch support resistive touch screen driver
4c7efd123SYoichi Yuasa * Copyright (C) 2012 ROHM CO.,LTD.
5c7efd123SYoichi Yuasa */
6c7efd123SYoichi Yuasa #include <linux/delay.h>
7c7efd123SYoichi Yuasa #include <linux/firmware.h>
8c7efd123SYoichi Yuasa #include <linux/i2c.h>
9c7efd123SYoichi Yuasa #include <linux/input.h>
10c7efd123SYoichi Yuasa #include <linux/input/mt.h>
11c7efd123SYoichi Yuasa #include <linux/interrupt.h>
12c7efd123SYoichi Yuasa #include <linux/module.h>
13c7efd123SYoichi Yuasa #include <linux/slab.h>
14c7efd123SYoichi Yuasa
15c7efd123SYoichi Yuasa #define BU21023_NAME "bu21023_ts"
16c7efd123SYoichi Yuasa #define BU21023_FIRMWARE_NAME "bu21023.bin"
17c7efd123SYoichi Yuasa
18c7efd123SYoichi Yuasa #define MAX_CONTACTS 2
19c7efd123SYoichi Yuasa
20c7efd123SYoichi Yuasa #define AXIS_ADJUST 4
21c7efd123SYoichi Yuasa #define AXIS_OFFSET 8
22c7efd123SYoichi Yuasa
23c7efd123SYoichi Yuasa #define FIRMWARE_BLOCK_SIZE 32U
24c7efd123SYoichi Yuasa #define FIRMWARE_RETRY_MAX 4
25c7efd123SYoichi Yuasa
26c7efd123SYoichi Yuasa #define SAMPLING_DELAY 12 /* msec */
27c7efd123SYoichi Yuasa
28c7efd123SYoichi Yuasa #define CALIBRATION_RETRY_MAX 6
29c7efd123SYoichi Yuasa
30c7efd123SYoichi Yuasa #define ROHM_TS_ABS_X_MIN 40
31c7efd123SYoichi Yuasa #define ROHM_TS_ABS_X_MAX 990
32c7efd123SYoichi Yuasa #define ROHM_TS_ABS_Y_MIN 160
33c7efd123SYoichi Yuasa #define ROHM_TS_ABS_Y_MAX 920
34c7efd123SYoichi Yuasa #define ROHM_TS_DISPLACEMENT_MAX 0 /* zero for infinite */
35c7efd123SYoichi Yuasa
36c7efd123SYoichi Yuasa /*
37c7efd123SYoichi Yuasa * BU21023GUL/BU21023MUV/BU21024FV-M registers map
38c7efd123SYoichi Yuasa */
39c7efd123SYoichi Yuasa #define VADOUT_YP_H 0x00
40c7efd123SYoichi Yuasa #define VADOUT_YP_L 0x01
41c7efd123SYoichi Yuasa #define VADOUT_XP_H 0x02
42c7efd123SYoichi Yuasa #define VADOUT_XP_L 0x03
43c7efd123SYoichi Yuasa #define VADOUT_YN_H 0x04
44c7efd123SYoichi Yuasa #define VADOUT_YN_L 0x05
45c7efd123SYoichi Yuasa #define VADOUT_XN_H 0x06
46c7efd123SYoichi Yuasa #define VADOUT_XN_L 0x07
47c7efd123SYoichi Yuasa
48c7efd123SYoichi Yuasa #define PRM1_X_H 0x08
49c7efd123SYoichi Yuasa #define PRM1_X_L 0x09
50c7efd123SYoichi Yuasa #define PRM1_Y_H 0x0a
51c7efd123SYoichi Yuasa #define PRM1_Y_L 0x0b
52c7efd123SYoichi Yuasa #define PRM2_X_H 0x0c
53c7efd123SYoichi Yuasa #define PRM2_X_L 0x0d
54c7efd123SYoichi Yuasa #define PRM2_Y_H 0x0e
55c7efd123SYoichi Yuasa #define PRM2_Y_L 0x0f
56c7efd123SYoichi Yuasa
57c7efd123SYoichi Yuasa #define MLT_PRM_MONI_X 0x10
58c7efd123SYoichi Yuasa #define MLT_PRM_MONI_Y 0x11
59c7efd123SYoichi Yuasa
60c7efd123SYoichi Yuasa #define DEBUG_MONI_1 0x12
61c7efd123SYoichi Yuasa #define DEBUG_MONI_2 0x13
62c7efd123SYoichi Yuasa
63c7efd123SYoichi Yuasa #define VADOUT_ZX_H 0x14
64c7efd123SYoichi Yuasa #define VADOUT_ZX_L 0x15
65c7efd123SYoichi Yuasa #define VADOUT_ZY_H 0x16
66c7efd123SYoichi Yuasa #define VADOUT_ZY_L 0x17
67c7efd123SYoichi Yuasa
68c7efd123SYoichi Yuasa #define Z_PARAM_H 0x18
69c7efd123SYoichi Yuasa #define Z_PARAM_L 0x19
70c7efd123SYoichi Yuasa
71c7efd123SYoichi Yuasa /*
72c7efd123SYoichi Yuasa * Value for VADOUT_*_L
73c7efd123SYoichi Yuasa */
74c7efd123SYoichi Yuasa #define VADOUT_L_MASK 0x01
75c7efd123SYoichi Yuasa
76c7efd123SYoichi Yuasa /*
77c7efd123SYoichi Yuasa * Value for PRM*_*_L
78c7efd123SYoichi Yuasa */
79c7efd123SYoichi Yuasa #define PRM_L_MASK 0x01
80c7efd123SYoichi Yuasa
81c7efd123SYoichi Yuasa #define POS_X1_H 0x20
82c7efd123SYoichi Yuasa #define POS_X1_L 0x21
83c7efd123SYoichi Yuasa #define POS_Y1_H 0x22
84c7efd123SYoichi Yuasa #define POS_Y1_L 0x23
85c7efd123SYoichi Yuasa #define POS_X2_H 0x24
86c7efd123SYoichi Yuasa #define POS_X2_L 0x25
87c7efd123SYoichi Yuasa #define POS_Y2_H 0x26
88c7efd123SYoichi Yuasa #define POS_Y2_L 0x27
89c7efd123SYoichi Yuasa
90c7efd123SYoichi Yuasa /*
91c7efd123SYoichi Yuasa * Value for POS_*_L
92c7efd123SYoichi Yuasa */
93c7efd123SYoichi Yuasa #define POS_L_MASK 0x01
94c7efd123SYoichi Yuasa
95c7efd123SYoichi Yuasa #define TOUCH 0x28
96c7efd123SYoichi Yuasa #define TOUCH_DETECT 0x01
97c7efd123SYoichi Yuasa
98c7efd123SYoichi Yuasa #define TOUCH_GESTURE 0x29
99c7efd123SYoichi Yuasa #define SINGLE_TOUCH 0x01
100c7efd123SYoichi Yuasa #define DUAL_TOUCH 0x03
101c7efd123SYoichi Yuasa #define TOUCH_MASK 0x03
102c7efd123SYoichi Yuasa #define CALIBRATION_REQUEST 0x04
103c7efd123SYoichi Yuasa #define CALIBRATION_STATUS 0x08
104c7efd123SYoichi Yuasa #define CALIBRATION_MASK 0x0c
105c7efd123SYoichi Yuasa #define GESTURE_SPREAD 0x10
106c7efd123SYoichi Yuasa #define GESTURE_PINCH 0x20
107c7efd123SYoichi Yuasa #define GESTURE_ROTATE_R 0x40
108c7efd123SYoichi Yuasa #define GESTURE_ROTATE_L 0x80
109c7efd123SYoichi Yuasa
110c7efd123SYoichi Yuasa #define INT_STATUS 0x2a
111c7efd123SYoichi Yuasa #define INT_MASK 0x3d
112c7efd123SYoichi Yuasa #define INT_CLEAR 0x3e
113c7efd123SYoichi Yuasa
114c7efd123SYoichi Yuasa /*
115c7efd123SYoichi Yuasa * Values for INT_*
116c7efd123SYoichi Yuasa */
117c7efd123SYoichi Yuasa #define COORD_UPDATE 0x01
118c7efd123SYoichi Yuasa #define CALIBRATION_DONE 0x02
119c7efd123SYoichi Yuasa #define SLEEP_IN 0x04
120c7efd123SYoichi Yuasa #define SLEEP_OUT 0x08
121c7efd123SYoichi Yuasa #define PROGRAM_LOAD_DONE 0x10
122c7efd123SYoichi Yuasa #define ERROR 0x80
123c7efd123SYoichi Yuasa #define INT_ALL 0x9f
124c7efd123SYoichi Yuasa
125c7efd123SYoichi Yuasa #define ERR_STATUS 0x2b
126c7efd123SYoichi Yuasa #define ERR_MASK 0x3f
127c7efd123SYoichi Yuasa
128c7efd123SYoichi Yuasa /*
129c7efd123SYoichi Yuasa * Values for ERR_*
130c7efd123SYoichi Yuasa */
131c7efd123SYoichi Yuasa #define ADC_TIMEOUT 0x01
132c7efd123SYoichi Yuasa #define CPU_TIMEOUT 0x02
133c7efd123SYoichi Yuasa #define CALIBRATION_ERR 0x04
134c7efd123SYoichi Yuasa #define PROGRAM_LOAD_ERR 0x10
135c7efd123SYoichi Yuasa
136c7efd123SYoichi Yuasa #define COMMON_SETUP1 0x30
137c7efd123SYoichi Yuasa #define PROGRAM_LOAD_HOST 0x02
138c7efd123SYoichi Yuasa #define PROGRAM_LOAD_EEPROM 0x03
139c7efd123SYoichi Yuasa #define CENSOR_4PORT 0x04
140c7efd123SYoichi Yuasa #define CENSOR_8PORT 0x00 /* Not supported by BU21023 */
141c7efd123SYoichi Yuasa #define CALIBRATION_TYPE_DEFAULT 0x08
142c7efd123SYoichi Yuasa #define CALIBRATION_TYPE_SPECIAL 0x00
143c7efd123SYoichi Yuasa #define INT_ACTIVE_HIGH 0x10
144c7efd123SYoichi Yuasa #define INT_ACTIVE_LOW 0x00
145c7efd123SYoichi Yuasa #define AUTO_CALIBRATION 0x40
146c7efd123SYoichi Yuasa #define MANUAL_CALIBRATION 0x00
147c7efd123SYoichi Yuasa #define COMMON_SETUP1_DEFAULT 0x4e
148c7efd123SYoichi Yuasa
149c7efd123SYoichi Yuasa #define COMMON_SETUP2 0x31
150c7efd123SYoichi Yuasa #define MAF_NONE 0x00
151c7efd123SYoichi Yuasa #define MAF_1SAMPLE 0x01
152c7efd123SYoichi Yuasa #define MAF_3SAMPLES 0x02
153c7efd123SYoichi Yuasa #define MAF_5SAMPLES 0x03
154c7efd123SYoichi Yuasa #define INV_Y 0x04
155c7efd123SYoichi Yuasa #define INV_X 0x08
156c7efd123SYoichi Yuasa #define SWAP_XY 0x10
157c7efd123SYoichi Yuasa
158c7efd123SYoichi Yuasa #define COMMON_SETUP3 0x32
159c7efd123SYoichi Yuasa #define EN_SLEEP 0x01
160c7efd123SYoichi Yuasa #define EN_MULTI 0x02
161c7efd123SYoichi Yuasa #define EN_GESTURE 0x04
162c7efd123SYoichi Yuasa #define EN_INTVL 0x08
163c7efd123SYoichi Yuasa #define SEL_STEP 0x10
164c7efd123SYoichi Yuasa #define SEL_MULTI 0x20
165c7efd123SYoichi Yuasa #define SEL_TBL_DEFAULT 0x40
166c7efd123SYoichi Yuasa
167c7efd123SYoichi Yuasa #define INTERVAL_TIME 0x33
168c7efd123SYoichi Yuasa #define INTERVAL_TIME_DEFAULT 0x10
169c7efd123SYoichi Yuasa
170c7efd123SYoichi Yuasa #define STEP_X 0x34
171c7efd123SYoichi Yuasa #define STEP_X_DEFAULT 0x41
172c7efd123SYoichi Yuasa
173c7efd123SYoichi Yuasa #define STEP_Y 0x35
174c7efd123SYoichi Yuasa #define STEP_Y_DEFAULT 0x8d
175c7efd123SYoichi Yuasa
176c7efd123SYoichi Yuasa #define OFFSET_X 0x38
177c7efd123SYoichi Yuasa #define OFFSET_X_DEFAULT 0x0c
178c7efd123SYoichi Yuasa
179c7efd123SYoichi Yuasa #define OFFSET_Y 0x39
180c7efd123SYoichi Yuasa #define OFFSET_Y_DEFAULT 0x0c
181c7efd123SYoichi Yuasa
182c7efd123SYoichi Yuasa #define THRESHOLD_TOUCH 0x3a
183c7efd123SYoichi Yuasa #define THRESHOLD_TOUCH_DEFAULT 0xa0
184c7efd123SYoichi Yuasa
185c7efd123SYoichi Yuasa #define THRESHOLD_GESTURE 0x3b
186c7efd123SYoichi Yuasa #define THRESHOLD_GESTURE_DEFAULT 0x17
187c7efd123SYoichi Yuasa
188c7efd123SYoichi Yuasa #define SYSTEM 0x40
189c7efd123SYoichi Yuasa #define ANALOG_POWER_ON 0x01
190c7efd123SYoichi Yuasa #define ANALOG_POWER_OFF 0x00
191c7efd123SYoichi Yuasa #define CPU_POWER_ON 0x02
192c7efd123SYoichi Yuasa #define CPU_POWER_OFF 0x00
193c7efd123SYoichi Yuasa
194c7efd123SYoichi Yuasa #define FORCE_CALIBRATION 0x42
195c7efd123SYoichi Yuasa #define FORCE_CALIBRATION_ON 0x01
196c7efd123SYoichi Yuasa #define FORCE_CALIBRATION_OFF 0x00
197c7efd123SYoichi Yuasa
198c7efd123SYoichi Yuasa #define CPU_FREQ 0x50 /* 10 / (reg + 1) MHz */
199c7efd123SYoichi Yuasa #define CPU_FREQ_10MHZ 0x00
200c7efd123SYoichi Yuasa #define CPU_FREQ_5MHZ 0x01
201c7efd123SYoichi Yuasa #define CPU_FREQ_1MHZ 0x09
202c7efd123SYoichi Yuasa
203c7efd123SYoichi Yuasa #define EEPROM_ADDR 0x51
204c7efd123SYoichi Yuasa
205c7efd123SYoichi Yuasa #define CALIBRATION_ADJUST 0x52
206c7efd123SYoichi Yuasa #define CALIBRATION_ADJUST_DEFAULT 0x00
207c7efd123SYoichi Yuasa
208c7efd123SYoichi Yuasa #define THRESHOLD_SLEEP_IN 0x53
209c7efd123SYoichi Yuasa
210c7efd123SYoichi Yuasa #define EVR_XY 0x56
211c7efd123SYoichi Yuasa #define EVR_XY_DEFAULT 0x10
212c7efd123SYoichi Yuasa
213c7efd123SYoichi Yuasa #define PRM_SWOFF_TIME 0x57
214c7efd123SYoichi Yuasa #define PRM_SWOFF_TIME_DEFAULT 0x04
215c7efd123SYoichi Yuasa
216c7efd123SYoichi Yuasa #define PROGRAM_VERSION 0x5f
217c7efd123SYoichi Yuasa
218c7efd123SYoichi Yuasa #define ADC_CTRL 0x60
219c7efd123SYoichi Yuasa #define ADC_DIV_MASK 0x1f /* The minimum value is 4 */
220c7efd123SYoichi Yuasa #define ADC_DIV_DEFAULT 0x08
221c7efd123SYoichi Yuasa
222c7efd123SYoichi Yuasa #define ADC_WAIT 0x61
223c7efd123SYoichi Yuasa #define ADC_WAIT_DEFAULT 0x0a
224c7efd123SYoichi Yuasa
225c7efd123SYoichi Yuasa #define SWCONT 0x62
226c7efd123SYoichi Yuasa #define SWCONT_DEFAULT 0x0f
227c7efd123SYoichi Yuasa
228c7efd123SYoichi Yuasa #define EVR_X 0x63
229c7efd123SYoichi Yuasa #define EVR_X_DEFAULT 0x86
230c7efd123SYoichi Yuasa
231c7efd123SYoichi Yuasa #define EVR_Y 0x64
232c7efd123SYoichi Yuasa #define EVR_Y_DEFAULT 0x64
233c7efd123SYoichi Yuasa
234c7efd123SYoichi Yuasa #define TEST1 0x65
235c7efd123SYoichi Yuasa #define DUALTOUCH_STABILIZE_ON 0x01
236c7efd123SYoichi Yuasa #define DUALTOUCH_STABILIZE_OFF 0x00
237c7efd123SYoichi Yuasa #define DUALTOUCH_REG_ON 0x20
238c7efd123SYoichi Yuasa #define DUALTOUCH_REG_OFF 0x00
239c7efd123SYoichi Yuasa
240c7efd123SYoichi Yuasa #define CALIBRATION_REG1 0x68
241c7efd123SYoichi Yuasa #define CALIBRATION_REG1_DEFAULT 0xd9
242c7efd123SYoichi Yuasa
243c7efd123SYoichi Yuasa #define CALIBRATION_REG2 0x69
244c7efd123SYoichi Yuasa #define CALIBRATION_REG2_DEFAULT 0x36
245c7efd123SYoichi Yuasa
246c7efd123SYoichi Yuasa #define CALIBRATION_REG3 0x6a
247c7efd123SYoichi Yuasa #define CALIBRATION_REG3_DEFAULT 0x32
248c7efd123SYoichi Yuasa
249c7efd123SYoichi Yuasa #define EX_ADDR_H 0x70
250c7efd123SYoichi Yuasa #define EX_ADDR_L 0x71
251c7efd123SYoichi Yuasa #define EX_WDAT 0x72
252c7efd123SYoichi Yuasa #define EX_RDAT 0x73
253c7efd123SYoichi Yuasa #define EX_CHK_SUM1 0x74
254c7efd123SYoichi Yuasa #define EX_CHK_SUM2 0x75
255c7efd123SYoichi Yuasa #define EX_CHK_SUM3 0x76
256c7efd123SYoichi Yuasa
257c7efd123SYoichi Yuasa struct rohm_ts_data {
258c7efd123SYoichi Yuasa struct i2c_client *client;
259c7efd123SYoichi Yuasa struct input_dev *input;
260c7efd123SYoichi Yuasa
261c7efd123SYoichi Yuasa bool initialized;
262c7efd123SYoichi Yuasa
263c7efd123SYoichi Yuasa unsigned int contact_count[MAX_CONTACTS + 1];
264c7efd123SYoichi Yuasa int finger_count;
265c7efd123SYoichi Yuasa
266c7efd123SYoichi Yuasa u8 setup2;
267c7efd123SYoichi Yuasa };
268c7efd123SYoichi Yuasa
269c7efd123SYoichi Yuasa /*
270c7efd123SYoichi Yuasa * rohm_i2c_burst_read - execute combined I2C message for ROHM BU21023/24
271c7efd123SYoichi Yuasa * @client: Handle to ROHM BU21023/24
272c7efd123SYoichi Yuasa * @start: Where to start read address from ROHM BU21023/24
273c7efd123SYoichi Yuasa * @buf: Where to store read data from ROHM BU21023/24
274c7efd123SYoichi Yuasa * @len: How many bytes to read
275c7efd123SYoichi Yuasa *
276c7efd123SYoichi Yuasa * Returns negative errno, else zero on success.
277c7efd123SYoichi Yuasa *
278c7efd123SYoichi Yuasa * Note
279c7efd123SYoichi Yuasa * In BU21023/24 burst read, stop condition is needed after "address write".
280c7efd123SYoichi Yuasa * Therefore, transmission is performed in 2 steps.
281c7efd123SYoichi Yuasa */
rohm_i2c_burst_read(struct i2c_client * client,u8 start,void * buf,size_t len)282c7efd123SYoichi Yuasa static int rohm_i2c_burst_read(struct i2c_client *client, u8 start, void *buf,
283c7efd123SYoichi Yuasa size_t len)
284c7efd123SYoichi Yuasa {
285c7efd123SYoichi Yuasa struct i2c_adapter *adap = client->adapter;
286c7efd123SYoichi Yuasa struct i2c_msg msg[2];
287c7efd123SYoichi Yuasa int i, ret = 0;
288c7efd123SYoichi Yuasa
289c7efd123SYoichi Yuasa msg[0].addr = client->addr;
290c7efd123SYoichi Yuasa msg[0].flags = 0;
291c7efd123SYoichi Yuasa msg[0].len = 1;
292c7efd123SYoichi Yuasa msg[0].buf = &start;
293c7efd123SYoichi Yuasa
294c7efd123SYoichi Yuasa msg[1].addr = client->addr;
295c7efd123SYoichi Yuasa msg[1].flags = I2C_M_RD;
296c7efd123SYoichi Yuasa msg[1].len = len;
297c7efd123SYoichi Yuasa msg[1].buf = buf;
298c7efd123SYoichi Yuasa
299193c2a07SPeter Rosin i2c_lock_bus(adap, I2C_LOCK_SEGMENT);
300c7efd123SYoichi Yuasa
301c7efd123SYoichi Yuasa for (i = 0; i < 2; i++) {
302c7efd123SYoichi Yuasa if (__i2c_transfer(adap, &msg[i], 1) < 0) {
303c7efd123SYoichi Yuasa ret = -EIO;
304c7efd123SYoichi Yuasa break;
305c7efd123SYoichi Yuasa }
306c7efd123SYoichi Yuasa }
307c7efd123SYoichi Yuasa
308193c2a07SPeter Rosin i2c_unlock_bus(adap, I2C_LOCK_SEGMENT);
309c7efd123SYoichi Yuasa
310c7efd123SYoichi Yuasa return ret;
311c7efd123SYoichi Yuasa }
312c7efd123SYoichi Yuasa
rohm_ts_manual_calibration(struct rohm_ts_data * ts)313c7efd123SYoichi Yuasa static int rohm_ts_manual_calibration(struct rohm_ts_data *ts)
314c7efd123SYoichi Yuasa {
315c7efd123SYoichi Yuasa struct i2c_client *client = ts->client;
316c7efd123SYoichi Yuasa struct device *dev = &client->dev;
317c7efd123SYoichi Yuasa u8 buf[33]; /* for PRM1_X_H(0x08)-TOUCH(0x28) */
318c7efd123SYoichi Yuasa
319c7efd123SYoichi Yuasa int retry;
320c7efd123SYoichi Yuasa bool success = false;
321c7efd123SYoichi Yuasa bool first_time = true;
322c7efd123SYoichi Yuasa bool calibration_done;
323c7efd123SYoichi Yuasa
324c7efd123SYoichi Yuasa u8 reg1, reg2, reg3;
325c7efd123SYoichi Yuasa s32 reg1_orig, reg2_orig, reg3_orig;
326c7efd123SYoichi Yuasa s32 val;
327c7efd123SYoichi Yuasa
328c7efd123SYoichi Yuasa int calib_x = 0, calib_y = 0;
329c7efd123SYoichi Yuasa int reg_x, reg_y;
330c7efd123SYoichi Yuasa int err_x, err_y;
331c7efd123SYoichi Yuasa
332c7efd123SYoichi Yuasa int error, error2;
333c7efd123SYoichi Yuasa int i;
334c7efd123SYoichi Yuasa
335c7efd123SYoichi Yuasa reg1_orig = i2c_smbus_read_byte_data(client, CALIBRATION_REG1);
336c7efd123SYoichi Yuasa if (reg1_orig < 0)
337c7efd123SYoichi Yuasa return reg1_orig;
338c7efd123SYoichi Yuasa
339c7efd123SYoichi Yuasa reg2_orig = i2c_smbus_read_byte_data(client, CALIBRATION_REG2);
340c7efd123SYoichi Yuasa if (reg2_orig < 0)
341c7efd123SYoichi Yuasa return reg2_orig;
342c7efd123SYoichi Yuasa
343c7efd123SYoichi Yuasa reg3_orig = i2c_smbus_read_byte_data(client, CALIBRATION_REG3);
344c7efd123SYoichi Yuasa if (reg3_orig < 0)
345c7efd123SYoichi Yuasa return reg3_orig;
346c7efd123SYoichi Yuasa
347c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, INT_MASK,
348c7efd123SYoichi Yuasa COORD_UPDATE | SLEEP_IN | SLEEP_OUT |
349c7efd123SYoichi Yuasa PROGRAM_LOAD_DONE);
350c7efd123SYoichi Yuasa if (error)
351c7efd123SYoichi Yuasa goto out;
352c7efd123SYoichi Yuasa
353c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, TEST1,
354c7efd123SYoichi Yuasa DUALTOUCH_STABILIZE_ON);
355c7efd123SYoichi Yuasa if (error)
356c7efd123SYoichi Yuasa goto out;
357c7efd123SYoichi Yuasa
358c7efd123SYoichi Yuasa for (retry = 0; retry < CALIBRATION_RETRY_MAX; retry++) {
359c7efd123SYoichi Yuasa /* wait 2 sampling for update */
360c7efd123SYoichi Yuasa mdelay(2 * SAMPLING_DELAY);
361c7efd123SYoichi Yuasa
362c7efd123SYoichi Yuasa #define READ_CALIB_BUF(reg) buf[((reg) - PRM1_X_H)]
363c7efd123SYoichi Yuasa
364c7efd123SYoichi Yuasa error = rohm_i2c_burst_read(client, PRM1_X_H, buf, sizeof(buf));
365c7efd123SYoichi Yuasa if (error)
366c7efd123SYoichi Yuasa goto out;
367c7efd123SYoichi Yuasa
368c7efd123SYoichi Yuasa if (READ_CALIB_BUF(TOUCH) & TOUCH_DETECT)
369c7efd123SYoichi Yuasa continue;
370c7efd123SYoichi Yuasa
371c7efd123SYoichi Yuasa if (first_time) {
372c7efd123SYoichi Yuasa /* generate calibration parameter */
373c7efd123SYoichi Yuasa calib_x = ((int)READ_CALIB_BUF(PRM1_X_H) << 2 |
374c7efd123SYoichi Yuasa READ_CALIB_BUF(PRM1_X_L)) - AXIS_OFFSET;
375c7efd123SYoichi Yuasa calib_y = ((int)READ_CALIB_BUF(PRM1_Y_H) << 2 |
376c7efd123SYoichi Yuasa READ_CALIB_BUF(PRM1_Y_L)) - AXIS_OFFSET;
377c7efd123SYoichi Yuasa
378c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, TEST1,
379c7efd123SYoichi Yuasa DUALTOUCH_STABILIZE_ON | DUALTOUCH_REG_ON);
380c7efd123SYoichi Yuasa if (error)
381c7efd123SYoichi Yuasa goto out;
382c7efd123SYoichi Yuasa
383c7efd123SYoichi Yuasa first_time = false;
384c7efd123SYoichi Yuasa } else {
385c7efd123SYoichi Yuasa /* generate adjustment parameter */
386c7efd123SYoichi Yuasa err_x = (int)READ_CALIB_BUF(PRM1_X_H) << 2 |
387c7efd123SYoichi Yuasa READ_CALIB_BUF(PRM1_X_L);
388c7efd123SYoichi Yuasa err_y = (int)READ_CALIB_BUF(PRM1_Y_H) << 2 |
389c7efd123SYoichi Yuasa READ_CALIB_BUF(PRM1_Y_L);
390c7efd123SYoichi Yuasa
391c7efd123SYoichi Yuasa /* X axis ajust */
392c7efd123SYoichi Yuasa if (err_x <= 4)
393c7efd123SYoichi Yuasa calib_x -= AXIS_ADJUST;
394c7efd123SYoichi Yuasa else if (err_x >= 60)
395c7efd123SYoichi Yuasa calib_x += AXIS_ADJUST;
396c7efd123SYoichi Yuasa
397c7efd123SYoichi Yuasa /* Y axis ajust */
398c7efd123SYoichi Yuasa if (err_y <= 4)
399c7efd123SYoichi Yuasa calib_y -= AXIS_ADJUST;
400c7efd123SYoichi Yuasa else if (err_y >= 60)
401c7efd123SYoichi Yuasa calib_y += AXIS_ADJUST;
402c7efd123SYoichi Yuasa }
403c7efd123SYoichi Yuasa
404c7efd123SYoichi Yuasa /* generate calibration setting value */
405c7efd123SYoichi Yuasa reg_x = calib_x + ((calib_x & 0x200) << 1);
406c7efd123SYoichi Yuasa reg_y = calib_y + ((calib_y & 0x200) << 1);
407c7efd123SYoichi Yuasa
408c7efd123SYoichi Yuasa /* convert for register format */
409c7efd123SYoichi Yuasa reg1 = reg_x >> 3;
410c7efd123SYoichi Yuasa reg2 = (reg_y & 0x7) << 4 | (reg_x & 0x7);
411c7efd123SYoichi Yuasa reg3 = reg_y >> 3;
412c7efd123SYoichi Yuasa
413c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client,
414c7efd123SYoichi Yuasa CALIBRATION_REG1, reg1);
415c7efd123SYoichi Yuasa if (error)
416c7efd123SYoichi Yuasa goto out;
417c7efd123SYoichi Yuasa
418c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client,
419c7efd123SYoichi Yuasa CALIBRATION_REG2, reg2);
420c7efd123SYoichi Yuasa if (error)
421c7efd123SYoichi Yuasa goto out;
422c7efd123SYoichi Yuasa
423c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client,
424c7efd123SYoichi Yuasa CALIBRATION_REG3, reg3);
425c7efd123SYoichi Yuasa if (error)
426c7efd123SYoichi Yuasa goto out;
427c7efd123SYoichi Yuasa
428c7efd123SYoichi Yuasa /*
429c7efd123SYoichi Yuasa * force calibration sequcence
430c7efd123SYoichi Yuasa */
431c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, FORCE_CALIBRATION,
432c7efd123SYoichi Yuasa FORCE_CALIBRATION_OFF);
433c7efd123SYoichi Yuasa if (error)
434c7efd123SYoichi Yuasa goto out;
435c7efd123SYoichi Yuasa
436c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, FORCE_CALIBRATION,
437c7efd123SYoichi Yuasa FORCE_CALIBRATION_ON);
438c7efd123SYoichi Yuasa if (error)
439c7efd123SYoichi Yuasa goto out;
440c7efd123SYoichi Yuasa
441c7efd123SYoichi Yuasa /* clear all interrupts */
442c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, INT_CLEAR, 0xff);
443c7efd123SYoichi Yuasa if (error)
444c7efd123SYoichi Yuasa goto out;
445c7efd123SYoichi Yuasa
446c7efd123SYoichi Yuasa /*
447c7efd123SYoichi Yuasa * Wait for the status change of calibration, max 10 sampling
448c7efd123SYoichi Yuasa */
449c7efd123SYoichi Yuasa calibration_done = false;
450c7efd123SYoichi Yuasa
451c7efd123SYoichi Yuasa for (i = 0; i < 10; i++) {
452c7efd123SYoichi Yuasa mdelay(SAMPLING_DELAY);
453c7efd123SYoichi Yuasa
454c7efd123SYoichi Yuasa val = i2c_smbus_read_byte_data(client, TOUCH_GESTURE);
455c7efd123SYoichi Yuasa if (!(val & CALIBRATION_MASK)) {
456c7efd123SYoichi Yuasa calibration_done = true;
457c7efd123SYoichi Yuasa break;
458c7efd123SYoichi Yuasa } else if (val < 0) {
459c7efd123SYoichi Yuasa error = val;
460c7efd123SYoichi Yuasa goto out;
461c7efd123SYoichi Yuasa }
462c7efd123SYoichi Yuasa }
463c7efd123SYoichi Yuasa
464c7efd123SYoichi Yuasa if (calibration_done) {
465c7efd123SYoichi Yuasa val = i2c_smbus_read_byte_data(client, INT_STATUS);
466c7efd123SYoichi Yuasa if (val == CALIBRATION_DONE) {
467c7efd123SYoichi Yuasa success = true;
468c7efd123SYoichi Yuasa break;
469c7efd123SYoichi Yuasa } else if (val < 0) {
470c7efd123SYoichi Yuasa error = val;
471c7efd123SYoichi Yuasa goto out;
472c7efd123SYoichi Yuasa }
473c7efd123SYoichi Yuasa } else {
474c7efd123SYoichi Yuasa dev_warn(dev, "calibration timeout\n");
475c7efd123SYoichi Yuasa }
476c7efd123SYoichi Yuasa }
477c7efd123SYoichi Yuasa
478c7efd123SYoichi Yuasa if (!success) {
479c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, CALIBRATION_REG1,
480c7efd123SYoichi Yuasa reg1_orig);
481c7efd123SYoichi Yuasa if (error)
482c7efd123SYoichi Yuasa goto out;
483c7efd123SYoichi Yuasa
484c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, CALIBRATION_REG2,
485c7efd123SYoichi Yuasa reg2_orig);
486c7efd123SYoichi Yuasa if (error)
487c7efd123SYoichi Yuasa goto out;
488c7efd123SYoichi Yuasa
489c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, CALIBRATION_REG3,
490c7efd123SYoichi Yuasa reg3_orig);
491c7efd123SYoichi Yuasa if (error)
492c7efd123SYoichi Yuasa goto out;
493c7efd123SYoichi Yuasa
494c7efd123SYoichi Yuasa /* calibration data enable */
495c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, TEST1,
496c7efd123SYoichi Yuasa DUALTOUCH_STABILIZE_ON |
497c7efd123SYoichi Yuasa DUALTOUCH_REG_ON);
498c7efd123SYoichi Yuasa if (error)
499c7efd123SYoichi Yuasa goto out;
500c7efd123SYoichi Yuasa
501c7efd123SYoichi Yuasa /* wait 10 sampling */
502c7efd123SYoichi Yuasa mdelay(10 * SAMPLING_DELAY);
503c7efd123SYoichi Yuasa
504c7efd123SYoichi Yuasa error = -EBUSY;
505c7efd123SYoichi Yuasa }
506c7efd123SYoichi Yuasa
507c7efd123SYoichi Yuasa out:
508c7efd123SYoichi Yuasa error2 = i2c_smbus_write_byte_data(client, INT_MASK, INT_ALL);
509c7efd123SYoichi Yuasa if (!error2)
510c7efd123SYoichi Yuasa /* Clear all interrupts */
511c7efd123SYoichi Yuasa error2 = i2c_smbus_write_byte_data(client, INT_CLEAR, 0xff);
512c7efd123SYoichi Yuasa
513c7efd123SYoichi Yuasa return error ? error : error2;
514c7efd123SYoichi Yuasa }
515c7efd123SYoichi Yuasa
516c7efd123SYoichi Yuasa static const unsigned int untouch_threshold[3] = { 0, 1, 5 };
517c7efd123SYoichi Yuasa static const unsigned int single_touch_threshold[3] = { 0, 0, 4 };
518c7efd123SYoichi Yuasa static const unsigned int dual_touch_threshold[3] = { 10, 8, 0 };
519c7efd123SYoichi Yuasa
rohm_ts_soft_irq(int irq,void * dev_id)520c7efd123SYoichi Yuasa static irqreturn_t rohm_ts_soft_irq(int irq, void *dev_id)
521c7efd123SYoichi Yuasa {
522c7efd123SYoichi Yuasa struct rohm_ts_data *ts = dev_id;
523c7efd123SYoichi Yuasa struct i2c_client *client = ts->client;
524c7efd123SYoichi Yuasa struct input_dev *input_dev = ts->input;
525c7efd123SYoichi Yuasa struct device *dev = &client->dev;
526c7efd123SYoichi Yuasa
527c7efd123SYoichi Yuasa u8 buf[10]; /* for POS_X1_H(0x20)-TOUCH_GESTURE(0x29) */
528c7efd123SYoichi Yuasa
529c7efd123SYoichi Yuasa struct input_mt_pos pos[MAX_CONTACTS];
530c7efd123SYoichi Yuasa int slots[MAX_CONTACTS];
531c7efd123SYoichi Yuasa u8 touch_flags;
532c7efd123SYoichi Yuasa unsigned int threshold;
533c7efd123SYoichi Yuasa int finger_count = -1;
534c7efd123SYoichi Yuasa int prev_finger_count = ts->finger_count;
535c7efd123SYoichi Yuasa int count;
536c7efd123SYoichi Yuasa int error;
537c7efd123SYoichi Yuasa int i;
538c7efd123SYoichi Yuasa
539c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, INT_MASK, INT_ALL);
540c7efd123SYoichi Yuasa if (error)
541c7efd123SYoichi Yuasa return IRQ_HANDLED;
542c7efd123SYoichi Yuasa
543c7efd123SYoichi Yuasa /* Clear all interrupts */
544c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, INT_CLEAR, 0xff);
545c7efd123SYoichi Yuasa if (error)
546c7efd123SYoichi Yuasa return IRQ_HANDLED;
547c7efd123SYoichi Yuasa
548c7efd123SYoichi Yuasa #define READ_POS_BUF(reg) buf[((reg) - POS_X1_H)]
549c7efd123SYoichi Yuasa
550c7efd123SYoichi Yuasa error = rohm_i2c_burst_read(client, POS_X1_H, buf, sizeof(buf));
551c7efd123SYoichi Yuasa if (error)
552c7efd123SYoichi Yuasa return IRQ_HANDLED;
553c7efd123SYoichi Yuasa
554c7efd123SYoichi Yuasa touch_flags = READ_POS_BUF(TOUCH_GESTURE) & TOUCH_MASK;
555c7efd123SYoichi Yuasa if (touch_flags) {
556c7efd123SYoichi Yuasa /* generate coordinates */
557c7efd123SYoichi Yuasa pos[0].x = ((s16)READ_POS_BUF(POS_X1_H) << 2) |
558c7efd123SYoichi Yuasa READ_POS_BUF(POS_X1_L);
559c7efd123SYoichi Yuasa pos[0].y = ((s16)READ_POS_BUF(POS_Y1_H) << 2) |
560c7efd123SYoichi Yuasa READ_POS_BUF(POS_Y1_L);
561c7efd123SYoichi Yuasa pos[1].x = ((s16)READ_POS_BUF(POS_X2_H) << 2) |
562c7efd123SYoichi Yuasa READ_POS_BUF(POS_X2_L);
563c7efd123SYoichi Yuasa pos[1].y = ((s16)READ_POS_BUF(POS_Y2_H) << 2) |
564c7efd123SYoichi Yuasa READ_POS_BUF(POS_Y2_L);
565c7efd123SYoichi Yuasa }
566c7efd123SYoichi Yuasa
567c7efd123SYoichi Yuasa switch (touch_flags) {
568c7efd123SYoichi Yuasa case 0:
569c7efd123SYoichi Yuasa threshold = untouch_threshold[prev_finger_count];
570c7efd123SYoichi Yuasa if (++ts->contact_count[0] >= threshold)
571c7efd123SYoichi Yuasa finger_count = 0;
572c7efd123SYoichi Yuasa break;
573c7efd123SYoichi Yuasa
574c7efd123SYoichi Yuasa case SINGLE_TOUCH:
575c7efd123SYoichi Yuasa threshold = single_touch_threshold[prev_finger_count];
576c7efd123SYoichi Yuasa if (++ts->contact_count[1] >= threshold)
577c7efd123SYoichi Yuasa finger_count = 1;
578c7efd123SYoichi Yuasa
579c7efd123SYoichi Yuasa if (finger_count == 1) {
580c7efd123SYoichi Yuasa if (pos[1].x != 0 && pos[1].y != 0) {
581c7efd123SYoichi Yuasa pos[0].x = pos[1].x;
582c7efd123SYoichi Yuasa pos[0].y = pos[1].y;
583c7efd123SYoichi Yuasa pos[1].x = 0;
584c7efd123SYoichi Yuasa pos[1].y = 0;
585c7efd123SYoichi Yuasa }
586c7efd123SYoichi Yuasa }
587c7efd123SYoichi Yuasa break;
588c7efd123SYoichi Yuasa
589c7efd123SYoichi Yuasa case DUAL_TOUCH:
590c7efd123SYoichi Yuasa threshold = dual_touch_threshold[prev_finger_count];
591c7efd123SYoichi Yuasa if (++ts->contact_count[2] >= threshold)
592c7efd123SYoichi Yuasa finger_count = 2;
593c7efd123SYoichi Yuasa break;
594c7efd123SYoichi Yuasa
595c7efd123SYoichi Yuasa default:
596c7efd123SYoichi Yuasa dev_dbg(dev,
597c7efd123SYoichi Yuasa "Three or more touches are not supported\n");
598c7efd123SYoichi Yuasa return IRQ_HANDLED;
599c7efd123SYoichi Yuasa }
600c7efd123SYoichi Yuasa
601c7efd123SYoichi Yuasa if (finger_count >= 0) {
602c7efd123SYoichi Yuasa if (prev_finger_count != finger_count) {
603c7efd123SYoichi Yuasa count = ts->contact_count[finger_count];
604c7efd123SYoichi Yuasa memset(ts->contact_count, 0, sizeof(ts->contact_count));
605c7efd123SYoichi Yuasa ts->contact_count[finger_count] = count;
606c7efd123SYoichi Yuasa }
607c7efd123SYoichi Yuasa
608c7efd123SYoichi Yuasa input_mt_assign_slots(input_dev, slots, pos,
609c7efd123SYoichi Yuasa finger_count, ROHM_TS_DISPLACEMENT_MAX);
610c7efd123SYoichi Yuasa
611c7efd123SYoichi Yuasa for (i = 0; i < finger_count; i++) {
612c7efd123SYoichi Yuasa input_mt_slot(input_dev, slots[i]);
613c7efd123SYoichi Yuasa input_mt_report_slot_state(input_dev,
614c7efd123SYoichi Yuasa MT_TOOL_FINGER, true);
615c7efd123SYoichi Yuasa input_report_abs(input_dev,
616c7efd123SYoichi Yuasa ABS_MT_POSITION_X, pos[i].x);
617c7efd123SYoichi Yuasa input_report_abs(input_dev,
618c7efd123SYoichi Yuasa ABS_MT_POSITION_Y, pos[i].y);
619c7efd123SYoichi Yuasa }
620c7efd123SYoichi Yuasa
621c7efd123SYoichi Yuasa input_mt_sync_frame(input_dev);
622c7efd123SYoichi Yuasa input_mt_report_pointer_emulation(input_dev, true);
623c7efd123SYoichi Yuasa input_sync(input_dev);
624c7efd123SYoichi Yuasa
625c7efd123SYoichi Yuasa ts->finger_count = finger_count;
626c7efd123SYoichi Yuasa }
627c7efd123SYoichi Yuasa
628c7efd123SYoichi Yuasa if (READ_POS_BUF(TOUCH_GESTURE) & CALIBRATION_REQUEST) {
629c7efd123SYoichi Yuasa error = rohm_ts_manual_calibration(ts);
630c7efd123SYoichi Yuasa if (error)
631c7efd123SYoichi Yuasa dev_warn(dev, "manual calibration failed: %d\n",
632c7efd123SYoichi Yuasa error);
633c7efd123SYoichi Yuasa }
634c7efd123SYoichi Yuasa
635c7efd123SYoichi Yuasa i2c_smbus_write_byte_data(client, INT_MASK,
636c7efd123SYoichi Yuasa CALIBRATION_DONE | SLEEP_OUT | SLEEP_IN |
637c7efd123SYoichi Yuasa PROGRAM_LOAD_DONE);
638c7efd123SYoichi Yuasa
639c7efd123SYoichi Yuasa return IRQ_HANDLED;
640c7efd123SYoichi Yuasa }
641c7efd123SYoichi Yuasa
rohm_ts_load_firmware(struct i2c_client * client,const char * firmware_name)642c7efd123SYoichi Yuasa static int rohm_ts_load_firmware(struct i2c_client *client,
643c7efd123SYoichi Yuasa const char *firmware_name)
644c7efd123SYoichi Yuasa {
645c7efd123SYoichi Yuasa struct device *dev = &client->dev;
646c7efd123SYoichi Yuasa const struct firmware *fw;
647c7efd123SYoichi Yuasa s32 status;
648c7efd123SYoichi Yuasa unsigned int offset, len, xfer_len;
649c7efd123SYoichi Yuasa unsigned int retry = 0;
650c7efd123SYoichi Yuasa int error, error2;
651c7efd123SYoichi Yuasa
652c7efd123SYoichi Yuasa error = request_firmware(&fw, firmware_name, dev);
653c7efd123SYoichi Yuasa if (error) {
654c7efd123SYoichi Yuasa dev_err(dev, "unable to retrieve firmware %s: %d\n",
655c7efd123SYoichi Yuasa firmware_name, error);
656c7efd123SYoichi Yuasa return error;
657c7efd123SYoichi Yuasa }
658c7efd123SYoichi Yuasa
659c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, INT_MASK,
660c7efd123SYoichi Yuasa COORD_UPDATE | CALIBRATION_DONE |
661c7efd123SYoichi Yuasa SLEEP_IN | SLEEP_OUT);
662c7efd123SYoichi Yuasa if (error)
663c7efd123SYoichi Yuasa goto out;
664c7efd123SYoichi Yuasa
665c7efd123SYoichi Yuasa do {
666c7efd123SYoichi Yuasa if (retry) {
667c7efd123SYoichi Yuasa dev_warn(dev, "retrying firmware load\n");
668c7efd123SYoichi Yuasa
669c7efd123SYoichi Yuasa /* settings for retry */
670c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, EX_WDAT, 0);
671c7efd123SYoichi Yuasa if (error)
672c7efd123SYoichi Yuasa goto out;
673c7efd123SYoichi Yuasa }
674c7efd123SYoichi Yuasa
675c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, EX_ADDR_H, 0);
676c7efd123SYoichi Yuasa if (error)
677c7efd123SYoichi Yuasa goto out;
678c7efd123SYoichi Yuasa
679c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, EX_ADDR_L, 0);
680c7efd123SYoichi Yuasa if (error)
681c7efd123SYoichi Yuasa goto out;
682c7efd123SYoichi Yuasa
683c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, COMMON_SETUP1,
684c7efd123SYoichi Yuasa COMMON_SETUP1_DEFAULT);
685c7efd123SYoichi Yuasa if (error)
686c7efd123SYoichi Yuasa goto out;
687c7efd123SYoichi Yuasa
688c7efd123SYoichi Yuasa /* firmware load to the device */
689c7efd123SYoichi Yuasa offset = 0;
690c7efd123SYoichi Yuasa len = fw->size;
691c7efd123SYoichi Yuasa
692c7efd123SYoichi Yuasa while (len) {
693c7efd123SYoichi Yuasa xfer_len = min(FIRMWARE_BLOCK_SIZE, len);
694c7efd123SYoichi Yuasa
695c7efd123SYoichi Yuasa error = i2c_smbus_write_i2c_block_data(client, EX_WDAT,
696c7efd123SYoichi Yuasa xfer_len, &fw->data[offset]);
697c7efd123SYoichi Yuasa if (error)
698c7efd123SYoichi Yuasa goto out;
699c7efd123SYoichi Yuasa
700c7efd123SYoichi Yuasa len -= xfer_len;
701c7efd123SYoichi Yuasa offset += xfer_len;
702c7efd123SYoichi Yuasa }
703c7efd123SYoichi Yuasa
704c7efd123SYoichi Yuasa /* check firmware load result */
705c7efd123SYoichi Yuasa status = i2c_smbus_read_byte_data(client, INT_STATUS);
706c7efd123SYoichi Yuasa if (status < 0) {
707c7efd123SYoichi Yuasa error = status;
708c7efd123SYoichi Yuasa goto out;
709c7efd123SYoichi Yuasa }
710c7efd123SYoichi Yuasa
711c7efd123SYoichi Yuasa /* clear all interrupts */
712c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, INT_CLEAR, 0xff);
713c7efd123SYoichi Yuasa if (error)
714c7efd123SYoichi Yuasa goto out;
715c7efd123SYoichi Yuasa
716c7efd123SYoichi Yuasa if (status == PROGRAM_LOAD_DONE)
717c7efd123SYoichi Yuasa break;
718c7efd123SYoichi Yuasa
719c7efd123SYoichi Yuasa error = -EIO;
720415a249fSDmitry Torokhov } while (++retry <= FIRMWARE_RETRY_MAX);
721c7efd123SYoichi Yuasa
722c7efd123SYoichi Yuasa out:
723c7efd123SYoichi Yuasa error2 = i2c_smbus_write_byte_data(client, INT_MASK, INT_ALL);
724c7efd123SYoichi Yuasa
725c7efd123SYoichi Yuasa release_firmware(fw);
726c7efd123SYoichi Yuasa
727c7efd123SYoichi Yuasa return error ? error : error2;
728c7efd123SYoichi Yuasa }
729c7efd123SYoichi Yuasa
swap_xy_show(struct device * dev,struct device_attribute * attr,char * buf)730c7efd123SYoichi Yuasa static ssize_t swap_xy_show(struct device *dev, struct device_attribute *attr,
731c7efd123SYoichi Yuasa char *buf)
732c7efd123SYoichi Yuasa {
733c7efd123SYoichi Yuasa struct i2c_client *client = to_i2c_client(dev);
734c7efd123SYoichi Yuasa struct rohm_ts_data *ts = i2c_get_clientdata(client);
735c7efd123SYoichi Yuasa
736c7efd123SYoichi Yuasa return sprintf(buf, "%d\n", !!(ts->setup2 & SWAP_XY));
737c7efd123SYoichi Yuasa }
738c7efd123SYoichi Yuasa
swap_xy_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)739c7efd123SYoichi Yuasa static ssize_t swap_xy_store(struct device *dev, struct device_attribute *attr,
740c7efd123SYoichi Yuasa const char *buf, size_t count)
741c7efd123SYoichi Yuasa {
742c7efd123SYoichi Yuasa struct i2c_client *client = to_i2c_client(dev);
743c7efd123SYoichi Yuasa struct rohm_ts_data *ts = i2c_get_clientdata(client);
744c7efd123SYoichi Yuasa unsigned int val;
745c7efd123SYoichi Yuasa int error;
746c7efd123SYoichi Yuasa
747c7efd123SYoichi Yuasa error = kstrtouint(buf, 0, &val);
748c7efd123SYoichi Yuasa if (error)
749c7efd123SYoichi Yuasa return error;
750c7efd123SYoichi Yuasa
751c7efd123SYoichi Yuasa error = mutex_lock_interruptible(&ts->input->mutex);
752c7efd123SYoichi Yuasa if (error)
753c7efd123SYoichi Yuasa return error;
754c7efd123SYoichi Yuasa
755c7efd123SYoichi Yuasa if (val)
756c7efd123SYoichi Yuasa ts->setup2 |= SWAP_XY;
757c7efd123SYoichi Yuasa else
758c7efd123SYoichi Yuasa ts->setup2 &= ~SWAP_XY;
759c7efd123SYoichi Yuasa
760c7efd123SYoichi Yuasa if (ts->initialized)
761c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(ts->client, COMMON_SETUP2,
762c7efd123SYoichi Yuasa ts->setup2);
763c7efd123SYoichi Yuasa
764c7efd123SYoichi Yuasa mutex_unlock(&ts->input->mutex);
765c7efd123SYoichi Yuasa
766c7efd123SYoichi Yuasa return error ? error : count;
767c7efd123SYoichi Yuasa }
768c7efd123SYoichi Yuasa
inv_x_show(struct device * dev,struct device_attribute * attr,char * buf)769c7efd123SYoichi Yuasa static ssize_t inv_x_show(struct device *dev, struct device_attribute *attr,
770c7efd123SYoichi Yuasa char *buf)
771c7efd123SYoichi Yuasa {
772c7efd123SYoichi Yuasa struct i2c_client *client = to_i2c_client(dev);
773c7efd123SYoichi Yuasa struct rohm_ts_data *ts = i2c_get_clientdata(client);
774c7efd123SYoichi Yuasa
775c7efd123SYoichi Yuasa return sprintf(buf, "%d\n", !!(ts->setup2 & INV_X));
776c7efd123SYoichi Yuasa }
777c7efd123SYoichi Yuasa
inv_x_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)778c7efd123SYoichi Yuasa static ssize_t inv_x_store(struct device *dev, struct device_attribute *attr,
779c7efd123SYoichi Yuasa const char *buf, size_t count)
780c7efd123SYoichi Yuasa {
781c7efd123SYoichi Yuasa struct i2c_client *client = to_i2c_client(dev);
782c7efd123SYoichi Yuasa struct rohm_ts_data *ts = i2c_get_clientdata(client);
783c7efd123SYoichi Yuasa unsigned int val;
784c7efd123SYoichi Yuasa int error;
785c7efd123SYoichi Yuasa
786c7efd123SYoichi Yuasa error = kstrtouint(buf, 0, &val);
787c7efd123SYoichi Yuasa if (error)
788c7efd123SYoichi Yuasa return error;
789c7efd123SYoichi Yuasa
790c7efd123SYoichi Yuasa error = mutex_lock_interruptible(&ts->input->mutex);
791c7efd123SYoichi Yuasa if (error)
792c7efd123SYoichi Yuasa return error;
793c7efd123SYoichi Yuasa
794c7efd123SYoichi Yuasa if (val)
795c7efd123SYoichi Yuasa ts->setup2 |= INV_X;
796c7efd123SYoichi Yuasa else
797c7efd123SYoichi Yuasa ts->setup2 &= ~INV_X;
798c7efd123SYoichi Yuasa
799c7efd123SYoichi Yuasa if (ts->initialized)
800c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(ts->client, COMMON_SETUP2,
801c7efd123SYoichi Yuasa ts->setup2);
802c7efd123SYoichi Yuasa
803c7efd123SYoichi Yuasa mutex_unlock(&ts->input->mutex);
804c7efd123SYoichi Yuasa
805c7efd123SYoichi Yuasa return error ? error : count;
806c7efd123SYoichi Yuasa }
807c7efd123SYoichi Yuasa
inv_y_show(struct device * dev,struct device_attribute * attr,char * buf)808c7efd123SYoichi Yuasa static ssize_t inv_y_show(struct device *dev, struct device_attribute *attr,
809c7efd123SYoichi Yuasa char *buf)
810c7efd123SYoichi Yuasa {
811c7efd123SYoichi Yuasa struct i2c_client *client = to_i2c_client(dev);
812c7efd123SYoichi Yuasa struct rohm_ts_data *ts = i2c_get_clientdata(client);
813c7efd123SYoichi Yuasa
814c7efd123SYoichi Yuasa return sprintf(buf, "%d\n", !!(ts->setup2 & INV_Y));
815c7efd123SYoichi Yuasa }
816c7efd123SYoichi Yuasa
inv_y_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)817c7efd123SYoichi Yuasa static ssize_t inv_y_store(struct device *dev, struct device_attribute *attr,
818c7efd123SYoichi Yuasa const char *buf, size_t count)
819c7efd123SYoichi Yuasa {
820c7efd123SYoichi Yuasa struct i2c_client *client = to_i2c_client(dev);
821c7efd123SYoichi Yuasa struct rohm_ts_data *ts = i2c_get_clientdata(client);
822c7efd123SYoichi Yuasa unsigned int val;
823c7efd123SYoichi Yuasa int error;
824c7efd123SYoichi Yuasa
825c7efd123SYoichi Yuasa error = kstrtouint(buf, 0, &val);
826c7efd123SYoichi Yuasa if (error)
827c7efd123SYoichi Yuasa return error;
828c7efd123SYoichi Yuasa
829c7efd123SYoichi Yuasa error = mutex_lock_interruptible(&ts->input->mutex);
830c7efd123SYoichi Yuasa if (error)
831c7efd123SYoichi Yuasa return error;
832c7efd123SYoichi Yuasa
833c7efd123SYoichi Yuasa if (val)
834c7efd123SYoichi Yuasa ts->setup2 |= INV_Y;
835c7efd123SYoichi Yuasa else
836c7efd123SYoichi Yuasa ts->setup2 &= ~INV_Y;
837c7efd123SYoichi Yuasa
838c7efd123SYoichi Yuasa if (ts->initialized)
839c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, COMMON_SETUP2,
840c7efd123SYoichi Yuasa ts->setup2);
841c7efd123SYoichi Yuasa
842c7efd123SYoichi Yuasa mutex_unlock(&ts->input->mutex);
843c7efd123SYoichi Yuasa
844c7efd123SYoichi Yuasa return error ? error : count;
845c7efd123SYoichi Yuasa }
846c7efd123SYoichi Yuasa
847c7efd123SYoichi Yuasa static DEVICE_ATTR_RW(swap_xy);
848c7efd123SYoichi Yuasa static DEVICE_ATTR_RW(inv_x);
849c7efd123SYoichi Yuasa static DEVICE_ATTR_RW(inv_y);
850c7efd123SYoichi Yuasa
851c7efd123SYoichi Yuasa static struct attribute *rohm_ts_attrs[] = {
852c7efd123SYoichi Yuasa &dev_attr_swap_xy.attr,
853c7efd123SYoichi Yuasa &dev_attr_inv_x.attr,
854c7efd123SYoichi Yuasa &dev_attr_inv_y.attr,
855c7efd123SYoichi Yuasa NULL,
856c7efd123SYoichi Yuasa };
857c7efd123SYoichi Yuasa
858c7efd123SYoichi Yuasa static const struct attribute_group rohm_ts_attr_group = {
859c7efd123SYoichi Yuasa .attrs = rohm_ts_attrs,
860c7efd123SYoichi Yuasa };
861c7efd123SYoichi Yuasa
rohm_ts_device_init(struct i2c_client * client,u8 setup2)862c7efd123SYoichi Yuasa static int rohm_ts_device_init(struct i2c_client *client, u8 setup2)
863c7efd123SYoichi Yuasa {
864c7efd123SYoichi Yuasa struct device *dev = &client->dev;
865c7efd123SYoichi Yuasa int error;
866c7efd123SYoichi Yuasa
867c7efd123SYoichi Yuasa disable_irq(client->irq);
868c7efd123SYoichi Yuasa
869c7efd123SYoichi Yuasa /*
870c7efd123SYoichi Yuasa * Wait 200usec for reset
871c7efd123SYoichi Yuasa */
872c7efd123SYoichi Yuasa udelay(200);
873c7efd123SYoichi Yuasa
874c7efd123SYoichi Yuasa /* Release analog reset */
875c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, SYSTEM,
876c7efd123SYoichi Yuasa ANALOG_POWER_ON | CPU_POWER_OFF);
877c7efd123SYoichi Yuasa if (error)
878c7efd123SYoichi Yuasa return error;
879c7efd123SYoichi Yuasa
880c7efd123SYoichi Yuasa /* Waiting for the analog warm-up, max. 200usec */
881c7efd123SYoichi Yuasa udelay(200);
882c7efd123SYoichi Yuasa
883c7efd123SYoichi Yuasa /* clear all interrupts */
884c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, INT_CLEAR, 0xff);
885c7efd123SYoichi Yuasa if (error)
886c7efd123SYoichi Yuasa return error;
887c7efd123SYoichi Yuasa
888c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, EX_WDAT, 0);
889c7efd123SYoichi Yuasa if (error)
890c7efd123SYoichi Yuasa return error;
891c7efd123SYoichi Yuasa
892c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, COMMON_SETUP1, 0);
893c7efd123SYoichi Yuasa if (error)
894c7efd123SYoichi Yuasa return error;
895c7efd123SYoichi Yuasa
896c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, COMMON_SETUP2, setup2);
897c7efd123SYoichi Yuasa if (error)
898c7efd123SYoichi Yuasa return error;
899c7efd123SYoichi Yuasa
900c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, COMMON_SETUP3,
901c7efd123SYoichi Yuasa SEL_TBL_DEFAULT | EN_MULTI);
902c7efd123SYoichi Yuasa if (error)
903c7efd123SYoichi Yuasa return error;
904c7efd123SYoichi Yuasa
905c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, THRESHOLD_GESTURE,
906c7efd123SYoichi Yuasa THRESHOLD_GESTURE_DEFAULT);
907c7efd123SYoichi Yuasa if (error)
908c7efd123SYoichi Yuasa return error;
909c7efd123SYoichi Yuasa
910c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, INTERVAL_TIME,
911c7efd123SYoichi Yuasa INTERVAL_TIME_DEFAULT);
912c7efd123SYoichi Yuasa if (error)
913c7efd123SYoichi Yuasa return error;
914c7efd123SYoichi Yuasa
915c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, CPU_FREQ, CPU_FREQ_10MHZ);
916c7efd123SYoichi Yuasa if (error)
917c7efd123SYoichi Yuasa return error;
918c7efd123SYoichi Yuasa
919c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, PRM_SWOFF_TIME,
920c7efd123SYoichi Yuasa PRM_SWOFF_TIME_DEFAULT);
921c7efd123SYoichi Yuasa if (error)
922c7efd123SYoichi Yuasa return error;
923c7efd123SYoichi Yuasa
924c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, ADC_CTRL, ADC_DIV_DEFAULT);
925c7efd123SYoichi Yuasa if (error)
926c7efd123SYoichi Yuasa return error;
927c7efd123SYoichi Yuasa
928c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, ADC_WAIT, ADC_WAIT_DEFAULT);
929c7efd123SYoichi Yuasa if (error)
930c7efd123SYoichi Yuasa return error;
931c7efd123SYoichi Yuasa
932c7efd123SYoichi Yuasa /*
933c7efd123SYoichi Yuasa * Panel setup, these values change with the panel.
934c7efd123SYoichi Yuasa */
935c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, STEP_X, STEP_X_DEFAULT);
936c7efd123SYoichi Yuasa if (error)
937c7efd123SYoichi Yuasa return error;
938c7efd123SYoichi Yuasa
939c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, STEP_Y, STEP_Y_DEFAULT);
940c7efd123SYoichi Yuasa if (error)
941c7efd123SYoichi Yuasa return error;
942c7efd123SYoichi Yuasa
943c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, OFFSET_X, OFFSET_X_DEFAULT);
944c7efd123SYoichi Yuasa if (error)
945c7efd123SYoichi Yuasa return error;
946c7efd123SYoichi Yuasa
947c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, OFFSET_Y, OFFSET_Y_DEFAULT);
948c7efd123SYoichi Yuasa if (error)
949c7efd123SYoichi Yuasa return error;
950c7efd123SYoichi Yuasa
951c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, THRESHOLD_TOUCH,
952c7efd123SYoichi Yuasa THRESHOLD_TOUCH_DEFAULT);
953c7efd123SYoichi Yuasa if (error)
954c7efd123SYoichi Yuasa return error;
955c7efd123SYoichi Yuasa
956c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, EVR_XY, EVR_XY_DEFAULT);
957c7efd123SYoichi Yuasa if (error)
958c7efd123SYoichi Yuasa return error;
959c7efd123SYoichi Yuasa
960c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, EVR_X, EVR_X_DEFAULT);
961c7efd123SYoichi Yuasa if (error)
962c7efd123SYoichi Yuasa return error;
963c7efd123SYoichi Yuasa
964c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, EVR_Y, EVR_Y_DEFAULT);
965c7efd123SYoichi Yuasa if (error)
966c7efd123SYoichi Yuasa return error;
967c7efd123SYoichi Yuasa
968c7efd123SYoichi Yuasa /* Fixed value settings */
969c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, CALIBRATION_ADJUST,
970c7efd123SYoichi Yuasa CALIBRATION_ADJUST_DEFAULT);
971c7efd123SYoichi Yuasa if (error)
972c7efd123SYoichi Yuasa return error;
973c7efd123SYoichi Yuasa
974c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, SWCONT, SWCONT_DEFAULT);
975c7efd123SYoichi Yuasa if (error)
976c7efd123SYoichi Yuasa return error;
977c7efd123SYoichi Yuasa
978c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, TEST1,
979c7efd123SYoichi Yuasa DUALTOUCH_STABILIZE_ON |
980c7efd123SYoichi Yuasa DUALTOUCH_REG_ON);
981c7efd123SYoichi Yuasa if (error)
982c7efd123SYoichi Yuasa return error;
983c7efd123SYoichi Yuasa
984c7efd123SYoichi Yuasa error = rohm_ts_load_firmware(client, BU21023_FIRMWARE_NAME);
985c7efd123SYoichi Yuasa if (error) {
986c7efd123SYoichi Yuasa dev_err(dev, "failed to load firmware: %d\n", error);
987c7efd123SYoichi Yuasa return error;
988c7efd123SYoichi Yuasa }
989c7efd123SYoichi Yuasa
990c7efd123SYoichi Yuasa /*
991c7efd123SYoichi Yuasa * Manual calibration results are not changed in same environment.
992c7efd123SYoichi Yuasa * If the force calibration is performed,
993c7efd123SYoichi Yuasa * the controller will not require calibration request interrupt
994c7efd123SYoichi Yuasa * when the typical values are set to the calibration registers.
995c7efd123SYoichi Yuasa */
996c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, CALIBRATION_REG1,
997c7efd123SYoichi Yuasa CALIBRATION_REG1_DEFAULT);
998c7efd123SYoichi Yuasa if (error)
999c7efd123SYoichi Yuasa return error;
1000c7efd123SYoichi Yuasa
1001c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, CALIBRATION_REG2,
1002c7efd123SYoichi Yuasa CALIBRATION_REG2_DEFAULT);
1003c7efd123SYoichi Yuasa if (error)
1004c7efd123SYoichi Yuasa return error;
1005c7efd123SYoichi Yuasa
1006c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, CALIBRATION_REG3,
1007c7efd123SYoichi Yuasa CALIBRATION_REG3_DEFAULT);
1008c7efd123SYoichi Yuasa if (error)
1009c7efd123SYoichi Yuasa return error;
1010c7efd123SYoichi Yuasa
1011c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, FORCE_CALIBRATION,
1012c7efd123SYoichi Yuasa FORCE_CALIBRATION_OFF);
1013c7efd123SYoichi Yuasa if (error)
1014c7efd123SYoichi Yuasa return error;
1015c7efd123SYoichi Yuasa
1016c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, FORCE_CALIBRATION,
1017c7efd123SYoichi Yuasa FORCE_CALIBRATION_ON);
1018c7efd123SYoichi Yuasa if (error)
1019c7efd123SYoichi Yuasa return error;
1020c7efd123SYoichi Yuasa
1021c7efd123SYoichi Yuasa /* Clear all interrupts */
1022c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, INT_CLEAR, 0xff);
1023c7efd123SYoichi Yuasa if (error)
1024c7efd123SYoichi Yuasa return error;
1025c7efd123SYoichi Yuasa
1026c7efd123SYoichi Yuasa /* Enable coordinates update interrupt */
1027c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, INT_MASK,
1028c7efd123SYoichi Yuasa CALIBRATION_DONE | SLEEP_OUT |
1029c7efd123SYoichi Yuasa SLEEP_IN | PROGRAM_LOAD_DONE);
1030c7efd123SYoichi Yuasa if (error)
1031c7efd123SYoichi Yuasa return error;
1032c7efd123SYoichi Yuasa
1033c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, ERR_MASK,
1034c7efd123SYoichi Yuasa PROGRAM_LOAD_ERR | CPU_TIMEOUT |
1035c7efd123SYoichi Yuasa ADC_TIMEOUT);
1036c7efd123SYoichi Yuasa if (error)
1037c7efd123SYoichi Yuasa return error;
1038c7efd123SYoichi Yuasa
1039c7efd123SYoichi Yuasa /* controller CPU power on */
1040c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, SYSTEM,
1041c7efd123SYoichi Yuasa ANALOG_POWER_ON | CPU_POWER_ON);
1042c7efd123SYoichi Yuasa
1043c7efd123SYoichi Yuasa enable_irq(client->irq);
1044c7efd123SYoichi Yuasa
1045c7efd123SYoichi Yuasa return error;
1046c7efd123SYoichi Yuasa }
1047c7efd123SYoichi Yuasa
rohm_ts_power_off(struct i2c_client * client)1048c7efd123SYoichi Yuasa static int rohm_ts_power_off(struct i2c_client *client)
1049c7efd123SYoichi Yuasa {
1050c7efd123SYoichi Yuasa int error;
1051c7efd123SYoichi Yuasa
1052c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, SYSTEM,
1053c7efd123SYoichi Yuasa ANALOG_POWER_ON | CPU_POWER_OFF);
1054c7efd123SYoichi Yuasa if (error) {
1055c7efd123SYoichi Yuasa dev_err(&client->dev,
1056c7efd123SYoichi Yuasa "failed to power off device CPU: %d\n", error);
1057c7efd123SYoichi Yuasa return error;
1058c7efd123SYoichi Yuasa }
1059c7efd123SYoichi Yuasa
1060c7efd123SYoichi Yuasa error = i2c_smbus_write_byte_data(client, SYSTEM,
1061c7efd123SYoichi Yuasa ANALOG_POWER_OFF | CPU_POWER_OFF);
1062c7efd123SYoichi Yuasa if (error)
1063c7efd123SYoichi Yuasa dev_err(&client->dev,
1064c7efd123SYoichi Yuasa "failed to power off the device: %d\n", error);
1065c7efd123SYoichi Yuasa
1066c7efd123SYoichi Yuasa return error;
1067c7efd123SYoichi Yuasa }
1068c7efd123SYoichi Yuasa
rohm_ts_open(struct input_dev * input_dev)1069c7efd123SYoichi Yuasa static int rohm_ts_open(struct input_dev *input_dev)
1070c7efd123SYoichi Yuasa {
1071c7efd123SYoichi Yuasa struct rohm_ts_data *ts = input_get_drvdata(input_dev);
1072c7efd123SYoichi Yuasa struct i2c_client *client = ts->client;
1073c7efd123SYoichi Yuasa int error;
1074c7efd123SYoichi Yuasa
1075c7efd123SYoichi Yuasa if (!ts->initialized) {
1076c7efd123SYoichi Yuasa error = rohm_ts_device_init(client, ts->setup2);
1077c7efd123SYoichi Yuasa if (error) {
1078c7efd123SYoichi Yuasa dev_err(&client->dev,
1079c7efd123SYoichi Yuasa "device initialization failed: %d\n", error);
1080c7efd123SYoichi Yuasa return error;
1081c7efd123SYoichi Yuasa }
1082c7efd123SYoichi Yuasa
1083c7efd123SYoichi Yuasa ts->initialized = true;
1084c7efd123SYoichi Yuasa }
1085c7efd123SYoichi Yuasa
1086c7efd123SYoichi Yuasa return 0;
1087c7efd123SYoichi Yuasa }
1088c7efd123SYoichi Yuasa
rohm_ts_close(struct input_dev * input_dev)1089c7efd123SYoichi Yuasa static void rohm_ts_close(struct input_dev *input_dev)
1090c7efd123SYoichi Yuasa {
1091c7efd123SYoichi Yuasa struct rohm_ts_data *ts = input_get_drvdata(input_dev);
1092c7efd123SYoichi Yuasa
1093c7efd123SYoichi Yuasa rohm_ts_power_off(ts->client);
1094c7efd123SYoichi Yuasa
1095c7efd123SYoichi Yuasa ts->initialized = false;
1096c7efd123SYoichi Yuasa }
1097c7efd123SYoichi Yuasa
rohm_bu21023_i2c_probe(struct i2c_client * client)109857e72dd7SUwe Kleine-König static int rohm_bu21023_i2c_probe(struct i2c_client *client)
1099c7efd123SYoichi Yuasa {
1100c7efd123SYoichi Yuasa struct device *dev = &client->dev;
1101c7efd123SYoichi Yuasa struct rohm_ts_data *ts;
1102c7efd123SYoichi Yuasa struct input_dev *input;
1103c7efd123SYoichi Yuasa int error;
1104c7efd123SYoichi Yuasa
1105c7efd123SYoichi Yuasa if (!client->irq) {
1106c7efd123SYoichi Yuasa dev_err(dev, "IRQ is not assigned\n");
1107c7efd123SYoichi Yuasa return -EINVAL;
1108c7efd123SYoichi Yuasa }
1109c7efd123SYoichi Yuasa
1110c7efd123SYoichi Yuasa if (!client->adapter->algo->master_xfer) {
1111c7efd123SYoichi Yuasa dev_err(dev, "I2C level transfers not supported\n");
1112c7efd123SYoichi Yuasa return -EOPNOTSUPP;
1113c7efd123SYoichi Yuasa }
1114c7efd123SYoichi Yuasa
1115c7efd123SYoichi Yuasa /* Turn off CPU just in case */
1116c7efd123SYoichi Yuasa error = rohm_ts_power_off(client);
1117c7efd123SYoichi Yuasa if (error)
1118c7efd123SYoichi Yuasa return error;
1119c7efd123SYoichi Yuasa
1120c7efd123SYoichi Yuasa ts = devm_kzalloc(dev, sizeof(struct rohm_ts_data), GFP_KERNEL);
1121c7efd123SYoichi Yuasa if (!ts)
1122c7efd123SYoichi Yuasa return -ENOMEM;
1123c7efd123SYoichi Yuasa
1124c7efd123SYoichi Yuasa ts->client = client;
1125c7efd123SYoichi Yuasa ts->setup2 = MAF_1SAMPLE;
1126c7efd123SYoichi Yuasa i2c_set_clientdata(client, ts);
1127c7efd123SYoichi Yuasa
1128c7efd123SYoichi Yuasa input = devm_input_allocate_device(dev);
1129c7efd123SYoichi Yuasa if (!input)
1130c7efd123SYoichi Yuasa return -ENOMEM;
1131c7efd123SYoichi Yuasa
1132c7efd123SYoichi Yuasa input->name = BU21023_NAME;
1133c7efd123SYoichi Yuasa input->id.bustype = BUS_I2C;
1134c7efd123SYoichi Yuasa input->open = rohm_ts_open;
1135c7efd123SYoichi Yuasa input->close = rohm_ts_close;
1136c7efd123SYoichi Yuasa
1137c7efd123SYoichi Yuasa ts->input = input;
1138c7efd123SYoichi Yuasa input_set_drvdata(input, ts);
1139c7efd123SYoichi Yuasa
1140c7efd123SYoichi Yuasa input_set_abs_params(input, ABS_MT_POSITION_X,
1141c7efd123SYoichi Yuasa ROHM_TS_ABS_X_MIN, ROHM_TS_ABS_X_MAX, 0, 0);
1142c7efd123SYoichi Yuasa input_set_abs_params(input, ABS_MT_POSITION_Y,
1143c7efd123SYoichi Yuasa ROHM_TS_ABS_Y_MIN, ROHM_TS_ABS_Y_MAX, 0, 0);
1144c7efd123SYoichi Yuasa
1145c7efd123SYoichi Yuasa error = input_mt_init_slots(input, MAX_CONTACTS,
1146c7efd123SYoichi Yuasa INPUT_MT_DIRECT | INPUT_MT_TRACK |
1147c7efd123SYoichi Yuasa INPUT_MT_DROP_UNUSED);
1148c7efd123SYoichi Yuasa if (error) {
1149c7efd123SYoichi Yuasa dev_err(dev, "failed to multi touch slots initialization\n");
1150c7efd123SYoichi Yuasa return error;
1151c7efd123SYoichi Yuasa }
1152c7efd123SYoichi Yuasa
1153c7efd123SYoichi Yuasa error = devm_request_threaded_irq(dev, client->irq,
1154c7efd123SYoichi Yuasa NULL, rohm_ts_soft_irq,
1155c7efd123SYoichi Yuasa IRQF_ONESHOT, client->name, ts);
1156c7efd123SYoichi Yuasa if (error) {
1157c7efd123SYoichi Yuasa dev_err(dev, "failed to request IRQ: %d\n", error);
1158c7efd123SYoichi Yuasa return error;
1159c7efd123SYoichi Yuasa }
1160c7efd123SYoichi Yuasa
1161c7efd123SYoichi Yuasa error = input_register_device(input);
1162c7efd123SYoichi Yuasa if (error) {
1163c7efd123SYoichi Yuasa dev_err(dev, "failed to register input device: %d\n", error);
1164c7efd123SYoichi Yuasa return error;
1165c7efd123SYoichi Yuasa }
1166c7efd123SYoichi Yuasa
1167a71b8b5cSAndi Shyti error = devm_device_add_group(dev, &rohm_ts_attr_group);
1168c7efd123SYoichi Yuasa if (error) {
1169c7efd123SYoichi Yuasa dev_err(dev, "failed to create sysfs group: %d\n", error);
1170c7efd123SYoichi Yuasa return error;
1171c7efd123SYoichi Yuasa }
1172c7efd123SYoichi Yuasa
1173c7efd123SYoichi Yuasa return error;
1174c7efd123SYoichi Yuasa }
1175c7efd123SYoichi Yuasa
1176c7efd123SYoichi Yuasa static const struct i2c_device_id rohm_bu21023_i2c_id[] = {
1177c7efd123SYoichi Yuasa { BU21023_NAME, 0 },
1178c7efd123SYoichi Yuasa { /* sentinel */ }
1179c7efd123SYoichi Yuasa };
1180c7efd123SYoichi Yuasa MODULE_DEVICE_TABLE(i2c, rohm_bu21023_i2c_id);
1181c7efd123SYoichi Yuasa
1182c7efd123SYoichi Yuasa static struct i2c_driver rohm_bu21023_i2c_driver = {
1183c7efd123SYoichi Yuasa .driver = {
1184c7efd123SYoichi Yuasa .name = BU21023_NAME,
1185c7efd123SYoichi Yuasa },
1186*d8bde56dSUwe Kleine-König .probe = rohm_bu21023_i2c_probe,
1187c7efd123SYoichi Yuasa .id_table = rohm_bu21023_i2c_id,
1188c7efd123SYoichi Yuasa };
1189c7efd123SYoichi Yuasa module_i2c_driver(rohm_bu21023_i2c_driver);
1190c7efd123SYoichi Yuasa
1191c7efd123SYoichi Yuasa MODULE_DESCRIPTION("ROHM BU21023/24 Touchscreen driver");
1192c7efd123SYoichi Yuasa MODULE_LICENSE("GPL v2");
1193c7efd123SYoichi Yuasa MODULE_AUTHOR("ROHM Co., Ltd.");
1194