2 * Driver for ChipOne icn8318 i2c touchscreen controller
4 * Copyright (c) 2015 Red Hat Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
12 * Hans de Goede <hdegoede@redhat.com>
15 #include <linux/gpio/consumer.h>
16 #include <linux/interrupt.h>
17 #include <linux/i2c.h>
18 #include <linux/input.h>
19 #include <linux/input/mt.h>
20 #include <linux/input/touchscreen.h>
21 #include <linux/module.h>
24 #define ICN8318_REG_POWER 4
25 #define ICN8318_REG_TOUCHDATA 16
27 #define ICN8318_POWER_ACTIVE 0
28 #define ICN8318_POWER_MONITOR 1
29 #define ICN8318_POWER_HIBERNATE 2
31 #define ICN8318_MAX_TOUCHES 5
33 struct icn8318_touch
{
37 __u8 pressure
; /* Seems more like finger width then pressure really */
39 /* The difference between 2 and 3 is unclear */
40 #define ICN8318_EVENT_NO_DATA 1 /* No finger seen yet since wakeup */
41 #define ICN8318_EVENT_UPDATE1 2 /* New or updated coordinates */
42 #define ICN8318_EVENT_UPDATE2 3 /* New or updated coordinates */
43 #define ICN8318_EVENT_END 4 /* Finger lifted */
46 struct icn8318_touch_data
{
49 struct icn8318_touch touches
[ICN8318_MAX_TOUCHES
];
53 struct i2c_client
*client
;
54 struct input_dev
*input
;
55 struct gpio_desc
*wake_gpio
;
56 struct touchscreen_properties prop
;
59 static int icn8318_read_touch_data(struct i2c_client
*client
,
60 struct icn8318_touch_data
*touch_data
)
62 u8 reg
= ICN8318_REG_TOUCHDATA
;
63 struct i2c_msg msg
[2] = {
72 .len
= sizeof(struct icn8318_touch_data
),
73 .buf
= (u8
*)touch_data
77 return i2c_transfer(client
->adapter
, msg
, 2);
80 static inline bool icn8318_touch_active(u8 event
)
82 return (event
== ICN8318_EVENT_UPDATE1
) ||
83 (event
== ICN8318_EVENT_UPDATE2
);
86 static irqreturn_t
icn8318_irq(int irq
, void *dev_id
)
88 struct icn8318_data
*data
= dev_id
;
89 struct device
*dev
= &data
->client
->dev
;
90 struct icn8318_touch_data touch_data
;
93 ret
= icn8318_read_touch_data(data
->client
, &touch_data
);
95 dev_err(dev
, "Error reading touch data: %d\n", ret
);
99 if (touch_data
.softbutton
) {
101 * Other data is invalid when a softbutton is pressed.
102 * This needs some extra devicetree bindings to map the icn8318
103 * softbutton codes to evdev codes. Currently no known devices
109 if (touch_data
.touch_count
> ICN8318_MAX_TOUCHES
) {
110 dev_warn(dev
, "Too much touches %d > %d\n",
111 touch_data
.touch_count
, ICN8318_MAX_TOUCHES
);
112 touch_data
.touch_count
= ICN8318_MAX_TOUCHES
;
115 for (i
= 0; i
< touch_data
.touch_count
; i
++) {
116 struct icn8318_touch
*touch
= &touch_data
.touches
[i
];
117 bool act
= icn8318_touch_active(touch
->event
);
119 input_mt_slot(data
->input
, touch
->slot
);
120 input_mt_report_slot_state(data
->input
, MT_TOOL_FINGER
, act
);
124 touchscreen_report_pos(data
->input
, &data
->prop
,
125 be16_to_cpu(touch
->x
),
126 be16_to_cpu(touch
->y
), true);
129 input_mt_sync_frame(data
->input
);
130 input_sync(data
->input
);
135 static int icn8318_start(struct input_dev
*dev
)
137 struct icn8318_data
*data
= input_get_drvdata(dev
);
139 enable_irq(data
->client
->irq
);
140 gpiod_set_value_cansleep(data
->wake_gpio
, 1);
145 static void icn8318_stop(struct input_dev
*dev
)
147 struct icn8318_data
*data
= input_get_drvdata(dev
);
149 disable_irq(data
->client
->irq
);
150 i2c_smbus_write_byte_data(data
->client
, ICN8318_REG_POWER
,
151 ICN8318_POWER_HIBERNATE
);
152 gpiod_set_value_cansleep(data
->wake_gpio
, 0);
155 #ifdef CONFIG_PM_SLEEP
156 static int icn8318_suspend(struct device
*dev
)
158 struct icn8318_data
*data
= i2c_get_clientdata(to_i2c_client(dev
));
160 mutex_lock(&data
->input
->mutex
);
161 if (data
->input
->users
)
162 icn8318_stop(data
->input
);
163 mutex_unlock(&data
->input
->mutex
);
168 static int icn8318_resume(struct device
*dev
)
170 struct icn8318_data
*data
= i2c_get_clientdata(to_i2c_client(dev
));
172 mutex_lock(&data
->input
->mutex
);
173 if (data
->input
->users
)
174 icn8318_start(data
->input
);
175 mutex_unlock(&data
->input
->mutex
);
181 static SIMPLE_DEV_PM_OPS(icn8318_pm_ops
, icn8318_suspend
, icn8318_resume
);
183 static int icn8318_probe(struct i2c_client
*client
,
184 const struct i2c_device_id
*id
)
186 struct device
*dev
= &client
->dev
;
187 struct icn8318_data
*data
;
188 struct input_dev
*input
;
192 dev_err(dev
, "Error no irq specified\n");
196 data
= devm_kzalloc(dev
, sizeof(*data
), GFP_KERNEL
);
200 data
->wake_gpio
= devm_gpiod_get(dev
, "wake", GPIOD_OUT_LOW
);
201 if (IS_ERR(data
->wake_gpio
)) {
202 error
= PTR_ERR(data
->wake_gpio
);
203 if (error
!= -EPROBE_DEFER
)
204 dev_err(dev
, "Error getting wake gpio: %d\n", error
);
208 input
= devm_input_allocate_device(dev
);
212 input
->name
= client
->name
;
213 input
->id
.bustype
= BUS_I2C
;
214 input
->open
= icn8318_start
;
215 input
->close
= icn8318_stop
;
216 input
->dev
.parent
= dev
;
218 input_set_capability(input
, EV_ABS
, ABS_MT_POSITION_X
);
219 input_set_capability(input
, EV_ABS
, ABS_MT_POSITION_Y
);
221 touchscreen_parse_properties(input
, true, &data
->prop
);
222 if (!input_abs_get_max(input
, ABS_MT_POSITION_X
) ||
223 !input_abs_get_max(input
, ABS_MT_POSITION_Y
)) {
224 dev_err(dev
, "Error touchscreen-size-x and/or -y missing\n");
228 error
= input_mt_init_slots(input
, ICN8318_MAX_TOUCHES
,
229 INPUT_MT_DIRECT
| INPUT_MT_DROP_UNUSED
);
233 data
->client
= client
;
235 input_set_drvdata(input
, data
);
237 error
= devm_request_threaded_irq(dev
, client
->irq
, NULL
, icn8318_irq
,
238 IRQF_ONESHOT
, client
->name
, data
);
240 dev_err(dev
, "Error requesting irq: %d\n", error
);
244 /* Stop device till opened */
245 icn8318_stop(data
->input
);
247 error
= input_register_device(input
);
251 i2c_set_clientdata(client
, data
);
256 static const struct of_device_id icn8318_of_match
[] = {
257 { .compatible
= "chipone,icn8318" },
260 MODULE_DEVICE_TABLE(of
, icn8318_of_match
);
262 /* This is useless for OF-enabled devices, but it is needed by I2C subsystem */
263 static const struct i2c_device_id icn8318_i2c_id
[] = {
266 MODULE_DEVICE_TABLE(i2c
, icn8318_i2c_id
);
268 static struct i2c_driver icn8318_driver
= {
270 .name
= "chipone_icn8318",
271 .pm
= &icn8318_pm_ops
,
272 .of_match_table
= icn8318_of_match
,
274 .probe
= icn8318_probe
,
275 .id_table
= icn8318_i2c_id
,
278 module_i2c_driver(icn8318_driver
);
280 MODULE_DESCRIPTION("ChipOne icn8318 I2C Touchscreen Driver");
281 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
282 MODULE_LICENSE("GPL");