1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (C) ST-Ericsson SA 2010 |
4 | * Author: Naveen Kumar G <naveen.gaddipati@stericsson.com> for ST-Ericsson |
5 | */ |
6 | |
7 | #include <linux/bitops.h> |
8 | #include <linux/delay.h> |
9 | #include <linux/gpio/consumer.h> |
10 | #include <linux/i2c.h> |
11 | #include <linux/input.h> |
12 | #include <linux/input/mt.h> |
13 | #include <linux/input/touchscreen.h> |
14 | #include <linux/interrupt.h> |
15 | #include <linux/kernel.h> |
16 | #include <linux/module.h> |
17 | #include <linux/property.h> |
18 | #include <linux/regulator/consumer.h> |
19 | #include <linux/slab.h> |
20 | #include <linux/types.h> |
21 | |
22 | #define MAX_FINGERS 2 |
23 | #define RESET_DELAY 30 |
24 | #define PENUP_TIMEOUT (10) |
25 | #define DELTA_MIN 16 |
26 | #define MASK_BITS 0x03 |
27 | #define SHIFT_8 8 |
28 | #define SHIFT_2 2 |
29 | #define LENGTH_OF_BUFFER 11 |
30 | #define I2C_RETRY_COUNT 5 |
31 | |
32 | #define BU21013_SENSORS_BTN_0_7_REG 0x70 |
33 | #define BU21013_SENSORS_BTN_8_15_REG 0x71 |
34 | #define BU21013_SENSORS_BTN_16_23_REG 0x72 |
35 | #define BU21013_X1_POS_MSB_REG 0x73 |
36 | #define BU21013_X1_POS_LSB_REG 0x74 |
37 | #define BU21013_Y1_POS_MSB_REG 0x75 |
38 | #define BU21013_Y1_POS_LSB_REG 0x76 |
39 | #define BU21013_X2_POS_MSB_REG 0x77 |
40 | #define BU21013_X2_POS_LSB_REG 0x78 |
41 | #define BU21013_Y2_POS_MSB_REG 0x79 |
42 | #define BU21013_Y2_POS_LSB_REG 0x7A |
43 | #define BU21013_INT_CLR_REG 0xE8 |
44 | #define BU21013_INT_MODE_REG 0xE9 |
45 | #define BU21013_GAIN_REG 0xEA |
46 | #define BU21013_OFFSET_MODE_REG 0xEB |
47 | #define BU21013_XY_EDGE_REG 0xEC |
48 | #define BU21013_RESET_REG 0xED |
49 | #define BU21013_CALIB_REG 0xEE |
50 | #define BU21013_DONE_REG 0xEF |
51 | #define BU21013_SENSOR_0_7_REG 0xF0 |
52 | #define BU21013_SENSOR_8_15_REG 0xF1 |
53 | #define BU21013_SENSOR_16_23_REG 0xF2 |
54 | #define BU21013_POS_MODE1_REG 0xF3 |
55 | #define BU21013_POS_MODE2_REG 0xF4 |
56 | #define BU21013_CLK_MODE_REG 0xF5 |
57 | #define BU21013_IDLE_REG 0xFA |
58 | #define BU21013_FILTER_REG 0xFB |
59 | #define BU21013_TH_ON_REG 0xFC |
60 | #define BU21013_TH_OFF_REG 0xFD |
61 | |
62 | |
63 | #define BU21013_RESET_ENABLE 0x01 |
64 | |
65 | #define BU21013_SENSORS_EN_0_7 0x3F |
66 | #define BU21013_SENSORS_EN_8_15 0xFC |
67 | #define BU21013_SENSORS_EN_16_23 0x1F |
68 | |
69 | #define BU21013_POS_MODE1_0 0x02 |
70 | #define BU21013_POS_MODE1_1 0x04 |
71 | #define BU21013_POS_MODE1_2 0x08 |
72 | |
73 | #define BU21013_POS_MODE2_ZERO 0x01 |
74 | #define BU21013_POS_MODE2_AVG1 0x02 |
75 | #define BU21013_POS_MODE2_AVG2 0x04 |
76 | #define BU21013_POS_MODE2_EN_XY 0x08 |
77 | #define BU21013_POS_MODE2_EN_RAW 0x10 |
78 | #define BU21013_POS_MODE2_MULTI 0x80 |
79 | |
80 | #define BU21013_CLK_MODE_DIV 0x01 |
81 | #define BU21013_CLK_MODE_EXT 0x02 |
82 | #define BU21013_CLK_MODE_CALIB 0x80 |
83 | |
84 | #define BU21013_IDLET_0 0x01 |
85 | #define BU21013_IDLET_1 0x02 |
86 | #define BU21013_IDLET_2 0x04 |
87 | #define BU21013_IDLET_3 0x08 |
88 | #define BU21013_IDLE_INTERMIT_EN 0x10 |
89 | |
90 | #define BU21013_DELTA_0_6 0x7F |
91 | #define BU21013_FILTER_EN 0x80 |
92 | |
93 | #define BU21013_INT_MODE_LEVEL 0x00 |
94 | #define BU21013_INT_MODE_EDGE 0x01 |
95 | |
96 | #define BU21013_GAIN_0 0x01 |
97 | #define BU21013_GAIN_1 0x02 |
98 | #define BU21013_GAIN_2 0x04 |
99 | |
100 | #define BU21013_OFFSET_MODE_DEFAULT 0x00 |
101 | #define BU21013_OFFSET_MODE_MOVE 0x01 |
102 | #define BU21013_OFFSET_MODE_DISABLE 0x02 |
103 | |
104 | #define BU21013_TH_ON_0 0x01 |
105 | #define BU21013_TH_ON_1 0x02 |
106 | #define BU21013_TH_ON_2 0x04 |
107 | #define BU21013_TH_ON_3 0x08 |
108 | #define BU21013_TH_ON_4 0x10 |
109 | #define BU21013_TH_ON_5 0x20 |
110 | #define BU21013_TH_ON_6 0x40 |
111 | #define BU21013_TH_ON_7 0x80 |
112 | #define BU21013_TH_ON_MAX 0xFF |
113 | |
114 | #define BU21013_TH_OFF_0 0x01 |
115 | #define BU21013_TH_OFF_1 0x02 |
116 | #define BU21013_TH_OFF_2 0x04 |
117 | #define BU21013_TH_OFF_3 0x08 |
118 | #define BU21013_TH_OFF_4 0x10 |
119 | #define BU21013_TH_OFF_5 0x20 |
120 | #define BU21013_TH_OFF_6 0x40 |
121 | #define BU21013_TH_OFF_7 0x80 |
122 | #define BU21013_TH_OFF_MAX 0xFF |
123 | |
124 | #define BU21013_X_EDGE_0 0x01 |
125 | #define BU21013_X_EDGE_1 0x02 |
126 | #define BU21013_X_EDGE_2 0x04 |
127 | #define BU21013_X_EDGE_3 0x08 |
128 | #define BU21013_Y_EDGE_0 0x10 |
129 | #define BU21013_Y_EDGE_1 0x20 |
130 | #define BU21013_Y_EDGE_2 0x40 |
131 | #define BU21013_Y_EDGE_3 0x80 |
132 | |
133 | #define BU21013_DONE 0x01 |
134 | #define BU21013_NUMBER_OF_X_SENSORS (6) |
135 | #define BU21013_NUMBER_OF_Y_SENSORS (11) |
136 | |
137 | #define DRIVER_TP "bu21013_tp" |
138 | |
139 | /** |
140 | * struct bu21013_ts - touch panel data structure |
141 | * @client: pointer to the i2c client |
142 | * @in_dev: pointer to the input device structure |
143 | * @props: the device coordinate transformation properties |
144 | * @regulator: pointer to the Regulator used for touch screen |
145 | * @cs_gpiod: chip select GPIO line |
146 | * @int_gpiod: touch interrupt GPIO line |
147 | * @touch_x_max: maximum X coordinate reported by the device |
148 | * @touch_y_max: maximum Y coordinate reported by the device |
149 | * @x_flip: indicates that the driver should invert X coordinate before |
150 | * reporting |
151 | * @y_flip: indicates that the driver should invert Y coordinate before |
152 | * reporting |
153 | * @touch_stopped: touch stop flag |
154 | * |
155 | * Touch panel device data structure |
156 | */ |
157 | struct bu21013_ts { |
158 | struct i2c_client *client; |
159 | struct input_dev *in_dev; |
160 | struct touchscreen_properties props; |
161 | struct regulator *regulator; |
162 | struct gpio_desc *cs_gpiod; |
163 | struct gpio_desc *int_gpiod; |
164 | u32 touch_x_max; |
165 | u32 touch_y_max; |
166 | bool x_flip; |
167 | bool y_flip; |
168 | bool touch_stopped; |
169 | }; |
170 | |
171 | static int bu21013_read_block_data(struct bu21013_ts *ts, u8 *buf) |
172 | { |
173 | int ret, i; |
174 | |
175 | for (i = 0; i < I2C_RETRY_COUNT; i++) { |
176 | ret = i2c_smbus_read_i2c_block_data(client: ts->client, |
177 | BU21013_SENSORS_BTN_0_7_REG, |
178 | LENGTH_OF_BUFFER, values: buf); |
179 | if (ret == LENGTH_OF_BUFFER) |
180 | return 0; |
181 | } |
182 | |
183 | return -EINVAL; |
184 | } |
185 | |
186 | static int bu21013_do_touch_report(struct bu21013_ts *ts) |
187 | { |
188 | struct input_dev *input = ts->in_dev; |
189 | struct input_mt_pos pos[MAX_FINGERS]; |
190 | int slots[MAX_FINGERS]; |
191 | u8 buf[LENGTH_OF_BUFFER]; |
192 | bool has_x_sensors, has_y_sensors; |
193 | int finger_down_count = 0; |
194 | int i; |
195 | |
196 | if (bu21013_read_block_data(ts, buf) < 0) |
197 | return -EINVAL; |
198 | |
199 | has_x_sensors = hweight32(buf[0] & BU21013_SENSORS_EN_0_7); |
200 | has_y_sensors = hweight32(((buf[1] & BU21013_SENSORS_EN_8_15) | |
201 | ((buf[2] & BU21013_SENSORS_EN_16_23) << SHIFT_8)) >> SHIFT_2); |
202 | if (!has_x_sensors || !has_y_sensors) |
203 | return 0; |
204 | |
205 | for (i = 0; i < MAX_FINGERS; i++) { |
206 | const u8 *data = &buf[4 * i + 3]; |
207 | unsigned int x, y; |
208 | |
209 | x = data[0] << SHIFT_2 | (data[1] & MASK_BITS); |
210 | y = data[2] << SHIFT_2 | (data[3] & MASK_BITS); |
211 | if (x != 0 && y != 0) |
212 | touchscreen_set_mt_pos(pos: &pos[finger_down_count++], |
213 | prop: &ts->props, x, y); |
214 | } |
215 | |
216 | if (finger_down_count == 2 && |
217 | (abs(pos[0].x - pos[1].x) < DELTA_MIN || |
218 | abs(pos[0].y - pos[1].y) < DELTA_MIN)) { |
219 | return 0; |
220 | } |
221 | |
222 | input_mt_assign_slots(dev: input, slots, pos, num_pos: finger_down_count, DELTA_MIN); |
223 | for (i = 0; i < finger_down_count; i++) { |
224 | input_mt_slot(dev: input, slot: slots[i]); |
225 | input_mt_report_slot_state(dev: input, MT_TOOL_FINGER, active: true); |
226 | input_report_abs(dev: input, ABS_MT_POSITION_X, value: pos[i].x); |
227 | input_report_abs(dev: input, ABS_MT_POSITION_Y, value: pos[i].y); |
228 | } |
229 | |
230 | input_mt_sync_frame(dev: input); |
231 | input_sync(dev: input); |
232 | |
233 | return 0; |
234 | } |
235 | |
236 | static irqreturn_t bu21013_gpio_irq(int irq, void *device_data) |
237 | { |
238 | struct bu21013_ts *ts = device_data; |
239 | int keep_polling; |
240 | int error; |
241 | |
242 | do { |
243 | error = bu21013_do_touch_report(ts); |
244 | if (error) { |
245 | dev_err(&ts->client->dev, "%s failed\n" , __func__); |
246 | break; |
247 | } |
248 | |
249 | if (unlikely(ts->touch_stopped)) |
250 | break; |
251 | |
252 | keep_polling = ts->int_gpiod ? |
253 | gpiod_get_value(desc: ts->int_gpiod) : false; |
254 | if (keep_polling) |
255 | usleep_range(min: 2000, max: 2500); |
256 | } while (keep_polling); |
257 | |
258 | return IRQ_HANDLED; |
259 | } |
260 | |
261 | static int bu21013_init_chip(struct bu21013_ts *ts) |
262 | { |
263 | struct i2c_client *client = ts->client; |
264 | int error; |
265 | |
266 | error = i2c_smbus_write_byte_data(client, BU21013_RESET_REG, |
267 | BU21013_RESET_ENABLE); |
268 | if (error) { |
269 | dev_err(&client->dev, "BU21013_RESET reg write failed\n" ); |
270 | return error; |
271 | } |
272 | msleep(RESET_DELAY); |
273 | |
274 | error = i2c_smbus_write_byte_data(client, BU21013_SENSOR_0_7_REG, |
275 | BU21013_SENSORS_EN_0_7); |
276 | if (error) { |
277 | dev_err(&client->dev, "BU21013_SENSOR_0_7 reg write failed\n" ); |
278 | return error; |
279 | } |
280 | |
281 | error = i2c_smbus_write_byte_data(client, BU21013_SENSOR_8_15_REG, |
282 | BU21013_SENSORS_EN_8_15); |
283 | if (error) { |
284 | dev_err(&client->dev, "BU21013_SENSOR_8_15 reg write failed\n" ); |
285 | return error; |
286 | } |
287 | |
288 | error = i2c_smbus_write_byte_data(client, BU21013_SENSOR_16_23_REG, |
289 | BU21013_SENSORS_EN_16_23); |
290 | if (error) { |
291 | dev_err(&client->dev, "BU21013_SENSOR_16_23 reg write failed\n" ); |
292 | return error; |
293 | } |
294 | |
295 | error = i2c_smbus_write_byte_data(client, BU21013_POS_MODE1_REG, |
296 | BU21013_POS_MODE1_0 | |
297 | BU21013_POS_MODE1_1); |
298 | if (error) { |
299 | dev_err(&client->dev, "BU21013_POS_MODE1 reg write failed\n" ); |
300 | return error; |
301 | } |
302 | |
303 | error = i2c_smbus_write_byte_data(client, BU21013_POS_MODE2_REG, |
304 | BU21013_POS_MODE2_ZERO | |
305 | BU21013_POS_MODE2_AVG1 | |
306 | BU21013_POS_MODE2_AVG2 | |
307 | BU21013_POS_MODE2_EN_RAW | |
308 | BU21013_POS_MODE2_MULTI); |
309 | if (error) { |
310 | dev_err(&client->dev, "BU21013_POS_MODE2 reg write failed\n" ); |
311 | return error; |
312 | } |
313 | |
314 | error = i2c_smbus_write_byte_data(client, BU21013_CLK_MODE_REG, |
315 | BU21013_CLK_MODE_DIV | |
316 | BU21013_CLK_MODE_CALIB); |
317 | if (error) { |
318 | dev_err(&client->dev, "BU21013_CLK_MODE reg write failed\n" ); |
319 | return error; |
320 | } |
321 | |
322 | error = i2c_smbus_write_byte_data(client, BU21013_IDLE_REG, |
323 | BU21013_IDLET_0 | |
324 | BU21013_IDLE_INTERMIT_EN); |
325 | if (error) { |
326 | dev_err(&client->dev, "BU21013_IDLE reg write failed\n" ); |
327 | return error; |
328 | } |
329 | |
330 | error = i2c_smbus_write_byte_data(client, BU21013_INT_MODE_REG, |
331 | BU21013_INT_MODE_LEVEL); |
332 | if (error) { |
333 | dev_err(&client->dev, "BU21013_INT_MODE reg write failed\n" ); |
334 | return error; |
335 | } |
336 | |
337 | error = i2c_smbus_write_byte_data(client, BU21013_FILTER_REG, |
338 | BU21013_DELTA_0_6 | |
339 | BU21013_FILTER_EN); |
340 | if (error) { |
341 | dev_err(&client->dev, "BU21013_FILTER reg write failed\n" ); |
342 | return error; |
343 | } |
344 | |
345 | error = i2c_smbus_write_byte_data(client, BU21013_TH_ON_REG, |
346 | BU21013_TH_ON_5); |
347 | if (error) { |
348 | dev_err(&client->dev, "BU21013_TH_ON reg write failed\n" ); |
349 | return error; |
350 | } |
351 | |
352 | error = i2c_smbus_write_byte_data(client, BU21013_TH_OFF_REG, |
353 | BU21013_TH_OFF_4 | BU21013_TH_OFF_3); |
354 | if (error) { |
355 | dev_err(&client->dev, "BU21013_TH_OFF reg write failed\n" ); |
356 | return error; |
357 | } |
358 | |
359 | error = i2c_smbus_write_byte_data(client, BU21013_GAIN_REG, |
360 | BU21013_GAIN_0 | BU21013_GAIN_1); |
361 | if (error) { |
362 | dev_err(&client->dev, "BU21013_GAIN reg write failed\n" ); |
363 | return error; |
364 | } |
365 | |
366 | error = i2c_smbus_write_byte_data(client, BU21013_OFFSET_MODE_REG, |
367 | BU21013_OFFSET_MODE_DEFAULT); |
368 | if (error) { |
369 | dev_err(&client->dev, "BU21013_OFFSET_MODE reg write failed\n" ); |
370 | return error; |
371 | } |
372 | |
373 | error = i2c_smbus_write_byte_data(client, BU21013_XY_EDGE_REG, |
374 | BU21013_X_EDGE_0 | |
375 | BU21013_X_EDGE_2 | |
376 | BU21013_Y_EDGE_1 | |
377 | BU21013_Y_EDGE_3); |
378 | if (error) { |
379 | dev_err(&client->dev, "BU21013_XY_EDGE reg write failed\n" ); |
380 | return error; |
381 | } |
382 | |
383 | error = i2c_smbus_write_byte_data(client, BU21013_DONE_REG, |
384 | BU21013_DONE); |
385 | if (error) { |
386 | dev_err(&client->dev, "BU21013_REG_DONE reg write failed\n" ); |
387 | return error; |
388 | } |
389 | |
390 | return 0; |
391 | } |
392 | |
393 | static void bu21013_power_off(void *_ts) |
394 | { |
395 | struct bu21013_ts *ts = _ts; |
396 | |
397 | regulator_disable(regulator: ts->regulator); |
398 | } |
399 | |
400 | static void bu21013_disable_chip(void *_ts) |
401 | { |
402 | struct bu21013_ts *ts = _ts; |
403 | |
404 | gpiod_set_value(desc: ts->cs_gpiod, value: 0); |
405 | } |
406 | |
407 | static int bu21013_probe(struct i2c_client *client) |
408 | { |
409 | struct bu21013_ts *ts; |
410 | struct input_dev *in_dev; |
411 | struct input_absinfo *info; |
412 | u32 max_x = 0, max_y = 0; |
413 | struct device *dev = &client->dev; |
414 | int error; |
415 | |
416 | if (!i2c_check_functionality(adap: client->adapter, |
417 | I2C_FUNC_SMBUS_BYTE_DATA)) { |
418 | dev_err(dev, "i2c smbus byte data not supported\n" ); |
419 | return -EIO; |
420 | } |
421 | |
422 | if (!client->irq) { |
423 | dev_err(dev, "No IRQ set up\n" ); |
424 | return -EINVAL; |
425 | } |
426 | |
427 | ts = devm_kzalloc(dev, size: sizeof(*ts), GFP_KERNEL); |
428 | if (!ts) |
429 | return -ENOMEM; |
430 | |
431 | ts->client = client; |
432 | |
433 | ts->x_flip = device_property_read_bool(dev, propname: "rohm,flip-x" ); |
434 | ts->y_flip = device_property_read_bool(dev, propname: "rohm,flip-y" ); |
435 | |
436 | in_dev = devm_input_allocate_device(dev); |
437 | if (!in_dev) { |
438 | dev_err(dev, "device memory alloc failed\n" ); |
439 | return -ENOMEM; |
440 | } |
441 | ts->in_dev = in_dev; |
442 | input_set_drvdata(dev: in_dev, data: ts); |
443 | |
444 | /* register the device to input subsystem */ |
445 | in_dev->name = DRIVER_TP; |
446 | in_dev->id.bustype = BUS_I2C; |
447 | |
448 | device_property_read_u32(dev, propname: "rohm,touch-max-x" , val: &max_x); |
449 | device_property_read_u32(dev, propname: "rohm,touch-max-y" , val: &max_y); |
450 | |
451 | input_set_abs_params(dev: in_dev, ABS_MT_POSITION_X, min: 0, max: max_x, fuzz: 0, flat: 0); |
452 | input_set_abs_params(dev: in_dev, ABS_MT_POSITION_Y, min: 0, max: max_y, fuzz: 0, flat: 0); |
453 | |
454 | touchscreen_parse_properties(input: in_dev, multitouch: true, prop: &ts->props); |
455 | |
456 | /* Adjust for the legacy "flip" properties, if present */ |
457 | if (!ts->props.invert_x && |
458 | device_property_read_bool(dev, propname: "rohm,flip-x" )) { |
459 | info = &in_dev->absinfo[ABS_MT_POSITION_X]; |
460 | info->maximum -= info->minimum; |
461 | info->minimum = 0; |
462 | } |
463 | |
464 | if (!ts->props.invert_y && |
465 | device_property_read_bool(dev, propname: "rohm,flip-y" )) { |
466 | info = &in_dev->absinfo[ABS_MT_POSITION_Y]; |
467 | info->maximum -= info->minimum; |
468 | info->minimum = 0; |
469 | } |
470 | |
471 | error = input_mt_init_slots(dev: in_dev, MAX_FINGERS, |
472 | INPUT_MT_DIRECT | INPUT_MT_TRACK | |
473 | INPUT_MT_DROP_UNUSED); |
474 | if (error) { |
475 | dev_err(dev, "failed to initialize MT slots" ); |
476 | return error; |
477 | } |
478 | |
479 | ts->regulator = devm_regulator_get(dev, id: "avdd" ); |
480 | if (IS_ERR(ptr: ts->regulator)) { |
481 | dev_err(dev, "regulator_get failed\n" ); |
482 | return PTR_ERR(ptr: ts->regulator); |
483 | } |
484 | |
485 | error = regulator_enable(regulator: ts->regulator); |
486 | if (error) { |
487 | dev_err(dev, "regulator enable failed\n" ); |
488 | return error; |
489 | } |
490 | |
491 | error = devm_add_action_or_reset(dev, bu21013_power_off, ts); |
492 | if (error) { |
493 | dev_err(dev, "failed to install power off handler\n" ); |
494 | return error; |
495 | } |
496 | |
497 | /* Named "CS" on the chip, DT binding is "reset" */ |
498 | ts->cs_gpiod = devm_gpiod_get(dev, con_id: "reset" , flags: GPIOD_OUT_HIGH); |
499 | if (IS_ERR(ptr: ts->cs_gpiod)) |
500 | return dev_err_probe(dev, err: PTR_ERR(ptr: ts->cs_gpiod), fmt: "failed to get CS GPIO\n" ); |
501 | |
502 | gpiod_set_consumer_name(desc: ts->cs_gpiod, name: "BU21013 CS" ); |
503 | |
504 | error = devm_add_action_or_reset(dev, bu21013_disable_chip, ts); |
505 | if (error) { |
506 | dev_err(dev, "failed to install chip disable handler\n" ); |
507 | return error; |
508 | } |
509 | |
510 | /* Named "INT" on the chip, DT binding is "touch" */ |
511 | ts->int_gpiod = devm_gpiod_get_optional(dev, con_id: "touch" , flags: GPIOD_IN); |
512 | error = PTR_ERR_OR_ZERO(ptr: ts->int_gpiod); |
513 | if (error) |
514 | return dev_err_probe(dev, err: error, fmt: "failed to get INT GPIO\n" ); |
515 | |
516 | if (ts->int_gpiod) |
517 | gpiod_set_consumer_name(desc: ts->int_gpiod, name: "BU21013 INT" ); |
518 | |
519 | /* configure the touch panel controller */ |
520 | error = bu21013_init_chip(ts); |
521 | if (error) { |
522 | dev_err(dev, "error in bu21013 config\n" ); |
523 | return error; |
524 | } |
525 | |
526 | error = devm_request_threaded_irq(dev, irq: client->irq, NULL, thread_fn: bu21013_gpio_irq, |
527 | IRQF_ONESHOT, DRIVER_TP, dev_id: ts); |
528 | if (error) { |
529 | dev_err(dev, "request irq %d failed\n" , client->irq); |
530 | return error; |
531 | } |
532 | |
533 | error = input_register_device(in_dev); |
534 | if (error) { |
535 | dev_err(dev, "failed to register input device\n" ); |
536 | return error; |
537 | } |
538 | |
539 | i2c_set_clientdata(client, data: ts); |
540 | |
541 | return 0; |
542 | } |
543 | |
544 | static void bu21013_remove(struct i2c_client *client) |
545 | { |
546 | struct bu21013_ts *ts = i2c_get_clientdata(client); |
547 | |
548 | /* Make sure IRQ will exit quickly even if there is contact */ |
549 | ts->touch_stopped = true; |
550 | /* The resources will be freed by devm */ |
551 | } |
552 | |
553 | static int bu21013_suspend(struct device *dev) |
554 | { |
555 | struct i2c_client *client = to_i2c_client(dev); |
556 | struct bu21013_ts *ts = i2c_get_clientdata(client); |
557 | |
558 | ts->touch_stopped = true; |
559 | mb(); |
560 | disable_irq(irq: client->irq); |
561 | |
562 | if (!device_may_wakeup(dev: &client->dev)) |
563 | regulator_disable(regulator: ts->regulator); |
564 | |
565 | return 0; |
566 | } |
567 | |
568 | static int bu21013_resume(struct device *dev) |
569 | { |
570 | struct i2c_client *client = to_i2c_client(dev); |
571 | struct bu21013_ts *ts = i2c_get_clientdata(client); |
572 | int error; |
573 | |
574 | if (!device_may_wakeup(dev: &client->dev)) { |
575 | error = regulator_enable(regulator: ts->regulator); |
576 | if (error) { |
577 | dev_err(&client->dev, |
578 | "failed to re-enable regulator when resuming\n" ); |
579 | return error; |
580 | } |
581 | |
582 | error = bu21013_init_chip(ts); |
583 | if (error) { |
584 | dev_err(&client->dev, |
585 | "failed to reinitialize chip when resuming\n" ); |
586 | return error; |
587 | } |
588 | } |
589 | |
590 | ts->touch_stopped = false; |
591 | mb(); |
592 | enable_irq(irq: client->irq); |
593 | |
594 | return 0; |
595 | } |
596 | |
597 | static DEFINE_SIMPLE_DEV_PM_OPS(bu21013_dev_pm_ops, bu21013_suspend, bu21013_resume); |
598 | |
599 | static const struct i2c_device_id bu21013_id[] = { |
600 | { DRIVER_TP, 0 }, |
601 | { } |
602 | }; |
603 | MODULE_DEVICE_TABLE(i2c, bu21013_id); |
604 | |
605 | static struct i2c_driver bu21013_driver = { |
606 | .driver = { |
607 | .name = DRIVER_TP, |
608 | .pm = pm_sleep_ptr(&bu21013_dev_pm_ops), |
609 | }, |
610 | .probe = bu21013_probe, |
611 | .remove = bu21013_remove, |
612 | .id_table = bu21013_id, |
613 | }; |
614 | |
615 | module_i2c_driver(bu21013_driver); |
616 | |
617 | MODULE_LICENSE("GPL v2" ); |
618 | MODULE_AUTHOR("Naveen Kumar G <naveen.gaddipati@stericsson.com>" ); |
619 | MODULE_DESCRIPTION("bu21013 touch screen controller driver" ); |
620 | |