1 // SPDX-License-Identifier: GPL-2.0-only
3 * Driver for cypress touch screen controller
5 * Copyright (c) 2009 Aava Mobile
7 * Some cleanups by Alan Cox <alan@linux.intel.com>
10 #include <linux/module.h>
11 #include <linux/kernel.h>
12 #include <linux/input.h>
13 #include <linux/slab.h>
14 #include <linux/interrupt.h>
16 #include <linux/i2c.h>
17 #include <linux/gpio.h>
18 #include <linux/input/cy8ctmg110_pdata.h>
20 #define CY8CTMG110_DRIVER_NAME "cy8ctmg110"
22 /* Touch coordinates */
23 #define CY8CTMG110_X_MIN 0
24 #define CY8CTMG110_Y_MIN 0
25 #define CY8CTMG110_X_MAX 759
26 #define CY8CTMG110_Y_MAX 465
29 /* cy8ctmg110 register definitions */
30 #define CY8CTMG110_TOUCH_WAKEUP_TIME 0
31 #define CY8CTMG110_TOUCH_SLEEP_TIME 2
32 #define CY8CTMG110_TOUCH_X1 3
33 #define CY8CTMG110_TOUCH_Y1 5
34 #define CY8CTMG110_TOUCH_X2 7
35 #define CY8CTMG110_TOUCH_Y2 9
36 #define CY8CTMG110_FINGERS 11
37 #define CY8CTMG110_GESTURE 12
38 #define CY8CTMG110_REG_MAX 13
42 * The touch driver structure.
45 struct input_dev
*input
;
47 struct i2c_client
*client
;
53 * cy8ctmg110_power is the routine that is called when touch hardware
54 * will powered off or on.
56 static void cy8ctmg110_power(struct cy8ctmg110
*ts
, bool poweron
)
59 gpio_direction_output(ts
->reset_pin
, 1 - poweron
);
62 static int cy8ctmg110_write_regs(struct cy8ctmg110
*tsc
, unsigned char reg
,
63 unsigned char len
, unsigned char *value
)
65 struct i2c_client
*client
= tsc
->client
;
67 unsigned char i2c_data
[6];
72 memcpy(i2c_data
+ 1, value
, len
);
74 ret
= i2c_master_send(client
, i2c_data
, len
+ 1);
76 dev_err(&client
->dev
, "i2c write data cmd failed\n");
77 return ret
< 0 ? ret
: -EIO
;
83 static int cy8ctmg110_read_regs(struct cy8ctmg110
*tsc
,
84 unsigned char *data
, unsigned char len
, unsigned char cmd
)
86 struct i2c_client
*client
= tsc
->client
;
88 struct i2c_msg msg
[2] = {
89 /* first write slave position to i2c devices */
95 /* Second read data from position */
104 ret
= i2c_transfer(client
->adapter
, msg
, 2);
111 static int cy8ctmg110_touch_pos(struct cy8ctmg110
*tsc
)
113 struct input_dev
*input
= tsc
->input
;
114 unsigned char reg_p
[CY8CTMG110_REG_MAX
];
117 memset(reg_p
, 0, CY8CTMG110_REG_MAX
);
119 /* Reading coordinates */
120 if (cy8ctmg110_read_regs(tsc
, reg_p
, 9, CY8CTMG110_TOUCH_X1
) != 0)
123 y
= reg_p
[2] << 8 | reg_p
[3];
124 x
= reg_p
[0] << 8 | reg_p
[1];
126 /* Number of touch */
128 input_report_key(input
, BTN_TOUCH
, 0);
130 input_report_key(input
, BTN_TOUCH
, 1);
131 input_report_abs(input
, ABS_X
, x
);
132 input_report_abs(input
, ABS_Y
, y
);
140 static int cy8ctmg110_set_sleepmode(struct cy8ctmg110
*ts
, bool sleep
)
142 unsigned char reg_p
[3];
154 return cy8ctmg110_write_regs(ts
, CY8CTMG110_TOUCH_WAKEUP_TIME
, 3, reg_p
);
157 static irqreturn_t
cy8ctmg110_irq_thread(int irq
, void *dev_id
)
159 struct cy8ctmg110
*tsc
= dev_id
;
161 cy8ctmg110_touch_pos(tsc
);
166 static int cy8ctmg110_probe(struct i2c_client
*client
,
167 const struct i2c_device_id
*id
)
169 const struct cy8ctmg110_pdata
*pdata
= dev_get_platdata(&client
->dev
);
170 struct cy8ctmg110
*ts
;
171 struct input_dev
*input_dev
;
174 /* No pdata no way forward */
176 dev_err(&client
->dev
, "no pdata\n");
180 if (!i2c_check_functionality(client
->adapter
,
181 I2C_FUNC_SMBUS_READ_WORD_DATA
))
184 ts
= kzalloc(sizeof(struct cy8ctmg110
), GFP_KERNEL
);
185 input_dev
= input_allocate_device();
186 if (!ts
|| !input_dev
) {
192 ts
->input
= input_dev
;
193 ts
->reset_pin
= pdata
->reset_pin
;
194 ts
->irq_pin
= pdata
->irq_pin
;
196 snprintf(ts
->phys
, sizeof(ts
->phys
),
197 "%s/input0", dev_name(&client
->dev
));
199 input_dev
->name
= CY8CTMG110_DRIVER_NAME
" Touchscreen";
200 input_dev
->phys
= ts
->phys
;
201 input_dev
->id
.bustype
= BUS_I2C
;
202 input_dev
->dev
.parent
= &client
->dev
;
204 input_dev
->evbit
[0] = BIT_MASK(EV_KEY
) | BIT_MASK(EV_ABS
);
205 input_dev
->keybit
[BIT_WORD(BTN_TOUCH
)] = BIT_MASK(BTN_TOUCH
);
207 input_set_abs_params(input_dev
, ABS_X
,
208 CY8CTMG110_X_MIN
, CY8CTMG110_X_MAX
, 4, 0);
209 input_set_abs_params(input_dev
, ABS_Y
,
210 CY8CTMG110_Y_MIN
, CY8CTMG110_Y_MAX
, 4, 0);
213 err
= gpio_request(ts
->reset_pin
, NULL
);
215 dev_err(&client
->dev
,
216 "Unable to request GPIO pin %d.\n",
222 cy8ctmg110_power(ts
, true);
223 cy8ctmg110_set_sleepmode(ts
, false);
225 err
= gpio_request(ts
->irq_pin
, "touch_irq_key");
227 dev_err(&client
->dev
,
228 "Failed to request GPIO %d, error %d\n",
230 goto err_shutoff_device
;
233 err
= gpio_direction_input(ts
->irq_pin
);
235 dev_err(&client
->dev
,
236 "Failed to configure input direction for GPIO %d, error %d\n",
238 goto err_free_irq_gpio
;
241 client
->irq
= gpio_to_irq(ts
->irq_pin
);
242 if (client
->irq
< 0) {
244 dev_err(&client
->dev
,
245 "Unable to get irq number for GPIO %d, error %d\n",
247 goto err_free_irq_gpio
;
250 err
= request_threaded_irq(client
->irq
, NULL
, cy8ctmg110_irq_thread
,
251 IRQF_TRIGGER_RISING
| IRQF_ONESHOT
,
252 "touch_reset_key", ts
);
254 dev_err(&client
->dev
,
255 "irq %d busy? error %d\n", client
->irq
, err
);
256 goto err_free_irq_gpio
;
259 err
= input_register_device(input_dev
);
263 i2c_set_clientdata(client
, ts
);
264 device_init_wakeup(&client
->dev
, 1);
268 free_irq(client
->irq
, ts
);
270 gpio_free(ts
->irq_pin
);
272 cy8ctmg110_set_sleepmode(ts
, true);
273 cy8ctmg110_power(ts
, false);
275 gpio_free(ts
->reset_pin
);
277 input_free_device(input_dev
);
282 static int __maybe_unused
cy8ctmg110_suspend(struct device
*dev
)
284 struct i2c_client
*client
= to_i2c_client(dev
);
285 struct cy8ctmg110
*ts
= i2c_get_clientdata(client
);
287 if (device_may_wakeup(&client
->dev
))
288 enable_irq_wake(client
->irq
);
290 cy8ctmg110_set_sleepmode(ts
, true);
291 cy8ctmg110_power(ts
, false);
296 static int __maybe_unused
cy8ctmg110_resume(struct device
*dev
)
298 struct i2c_client
*client
= to_i2c_client(dev
);
299 struct cy8ctmg110
*ts
= i2c_get_clientdata(client
);
301 if (device_may_wakeup(&client
->dev
))
302 disable_irq_wake(client
->irq
);
304 cy8ctmg110_power(ts
, true);
305 cy8ctmg110_set_sleepmode(ts
, false);
310 static SIMPLE_DEV_PM_OPS(cy8ctmg110_pm
, cy8ctmg110_suspend
, cy8ctmg110_resume
);
312 static int cy8ctmg110_remove(struct i2c_client
*client
)
314 struct cy8ctmg110
*ts
= i2c_get_clientdata(client
);
316 cy8ctmg110_set_sleepmode(ts
, true);
317 cy8ctmg110_power(ts
, false);
319 free_irq(client
->irq
, ts
);
320 input_unregister_device(ts
->input
);
321 gpio_free(ts
->irq_pin
);
323 gpio_free(ts
->reset_pin
);
329 static const struct i2c_device_id cy8ctmg110_idtable
[] = {
330 { CY8CTMG110_DRIVER_NAME
, 1 },
334 MODULE_DEVICE_TABLE(i2c
, cy8ctmg110_idtable
);
336 static struct i2c_driver cy8ctmg110_driver
= {
338 .name
= CY8CTMG110_DRIVER_NAME
,
339 .pm
= &cy8ctmg110_pm
,
341 .id_table
= cy8ctmg110_idtable
,
342 .probe
= cy8ctmg110_probe
,
343 .remove
= cy8ctmg110_remove
,
346 module_i2c_driver(cy8ctmg110_driver
);
348 MODULE_AUTHOR("Samuli Konttila <samuli.konttila@aavamobile.com>");
349 MODULE_DESCRIPTION("cy8ctmg110 TouchScreen Driver");
350 MODULE_LICENSE("GPL v2");