1 /* drivers/input/ts/ts-i2c.c - touchscreen i2c handle
\r
3 * Copyright (C) 2012-2015 ROCKCHIP.
\r
4 * Author: luowei <lw@rock-chips.com>
\r
6 * This software is licensed under the terms of the GNU General Public
\r
7 * License version 2, as published by the Free Software Foundation, and
\r
8 * may be copied, distributed, and modified under those terms.
\r
10 * This program is distributed in the hope that it will be useful,
\r
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
13 * GNU General Public License for more details.
\r
16 #include <linux/interrupt.h>
\r
17 #include <linux/i2c.h>
\r
18 #include <linux/slab.h>
\r
19 #include <linux/irq.h>
\r
20 #include <linux/miscdevice.h>
\r
21 #include <linux/gpio.h>
\r
22 #include <asm/uaccess.h>
\r
23 #include <asm/atomic.h>
\r
24 #include <linux/delay.h>
\r
25 #include <linux/input.h>
\r
26 #include <linux/workqueue.h>
\r
27 #include <linux/freezer.h>
\r
28 #include <mach/gpio.h>
\r
29 #include <mach/board.h>
\r
30 #ifdef CONFIG_HAS_EARLYSUSPEND
\r
31 #include <linux/earlysuspend.h>
\r
33 #include <linux/ts-auto.h>
\r
35 #define TS_I2C_RATE 200*1000
\r
38 #define TS_DEBUG_ENABLE
\r
39 #define DBG(x...) printk(x)
\r
45 static int ts_i2c_read_device(struct ts_private_data *ts, unsigned short reg,
\r
46 int bytes, void *dest, int reg_size)
\r
48 struct i2c_client *client = ts->control_data;
\r
49 struct i2c_adapter *i2c_adap = client->adapter;
\r
50 struct i2c_msg msgs[2];
\r
53 if (!dest || !i2c_adap) {
\r
54 printk("%s:line=%d,error\n",__func__,__LINE__);
\r
58 client->addr = ts->ops->slave_addr;
\r
60 msgs[0].addr = client->addr;
\r
61 msgs[0].flags = 0; /* write */
\r
62 msgs[0].buf = (unsigned char *)®
\r
67 msgs[0].scl_rate = TS_I2C_RATE;
\r
69 msgs[1].addr = client->addr;
\r
70 msgs[1].flags = I2C_M_RD;
\r
72 msgs[1].len = bytes;
\r
73 msgs[1].scl_rate = TS_I2C_RATE;
\r
75 res = i2c_transfer(i2c_adap, msgs, 2);
\r
83 #ifdef TS_DEBUG_ENABLE
\r
84 DBG("%s:reg=0x%x,len=%d,rxdata:",__func__, reg, bytes);
\r
85 for(i=0; i<bytes; i++)
\r
86 DBG("0x%x,",(unsigned char *)dest[i]);
\r
93 /* Currently we allocate the write buffer on the stack; this is OK for
\r
94 * small writes - if we need to do large writes this will need to be
\r
97 static int ts_i2c_write_device(struct ts_private_data *ts, unsigned short reg,
\r
98 int bytes, void *src, int reg_size)
\r
100 struct i2c_client *client = ts->control_data;
\r
101 struct i2c_adapter *i2c_adap = client->adapter;
\r
102 struct i2c_msg msgs[1];
\r
104 unsigned char buf[bytes + 2];
\r
106 if (!src || !i2c_adap) {
\r
107 printk("%s:line=%d,error\n",__func__,__LINE__);
\r
112 client->addr = ts->ops->slave_addr;
\r
114 if(ts->ops->reg_size == 2)
\r
116 buf[0] = (reg & 0xff00) >> 8;
\r
117 buf[1] = (reg & 0x00ff) & 0xff;
\r
118 memcpy(&buf[2], src, bytes);
\r
122 buf[0] = reg & 0xff;
\r
123 memcpy(&buf[1], src, bytes);
\r
126 #ifdef TS_DEBUG_ENABLE
\r
128 DBG("%s:reg=0x%x,len=%d,txdata:",__func__, reg, bytes);
\r
129 for(i=0; i<length; i++)
\r
130 DBG("0x%x,",buf[i]);
\r
134 if (!src || !i2c_adap) {
\r
135 printk("%s:line=%d,error\n",__func__,__LINE__);
\r
139 msgs[0].addr = client->addr;
\r
140 msgs[0].flags = 0; /* write */
\r
142 if(ts->ops->reg_size == 2)
\r
143 msgs[0].len = bytes+2;
\r
145 msgs[0].len = bytes+1;
\r
146 msgs[0].scl_rate = TS_I2C_RATE;
\r
148 res = i2c_transfer(i2c_adap, msgs, 1);
\r
158 int ts_bulk_read_normal(struct ts_private_data *ts,
\r
159 int count, unsigned char *buf, int rate)
\r
162 unsigned short reg;
\r
163 struct i2c_client *client = ts->control_data;
\r
164 client->addr = ts->ops->slave_addr;
\r
166 mutex_lock(&ts->io_lock);
\r
167 ret = i2c_master_normal_recv(client, buf, count, rate);
\r
170 mutex_unlock(&ts->io_lock);
\r
174 EXPORT_SYMBOL_GPL(ts_bulk_read_normal);
\r
177 int ts_bulk_write_normal(struct ts_private_data *ts, int count, unsigned char *buf, int rate)
\r
180 unsigned short reg;
\r
181 struct i2c_client *client = ts->control_data;
\r
182 client->addr = ts->ops->slave_addr;
\r
184 mutex_lock(&ts->io_lock);
\r
185 ret = i2c_master_normal_send(client, buf, count, rate);
\r
188 mutex_unlock(&ts->io_lock);
\r
192 EXPORT_SYMBOL_GPL(ts_bulk_write_normal);
\r
196 #ifdef CONFIG_HAS_EARLYSUSPEND
\r
197 static void ts_suspend(struct early_suspend *h)
\r
199 struct ts_private_data *ts =
\r
200 container_of(h, struct ts_private_data, early_suspend);
\r
202 return ts_device_suspend(ts);
\r
205 static void ts_resume(struct early_suspend *h)
\r
207 struct ts_private_data *ts =
\r
208 container_of(h, struct ts_private_data, early_suspend);
\r
210 return ts_device_resume(ts);
\r
214 static int ts_i2c_probe(struct i2c_client *i2c,
\r
215 const struct i2c_device_id *id)
\r
217 struct ts_private_data *ts;
\r
219 int type = TS_BUS_TYPE_I2C;
\r
221 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) {
\r
222 dev_err(&i2c->adapter->dev, "%s failed\n", __func__);
\r
226 ts = kzalloc(sizeof(struct ts_private_data), GFP_KERNEL);
\r
230 i2c_set_clientdata(i2c, ts);
\r
232 ts->irq = i2c->irq;
\r
233 ts->dev = &i2c->dev;
\r
234 ts->control_data = i2c;
\r
235 ts->read_dev = ts_i2c_read_device;
\r
236 ts->write_dev = ts_i2c_write_device;
\r
238 ret = ts_device_init(ts, type, ts->irq);
\r
241 printk("%s:fail to regist touch, type is %d\n",__func__, type);
\r
245 #ifdef CONFIG_HAS_EARLYSUSPEND
\r
246 if((ts->ops->suspend) && (ts->ops->resume))
\r
248 ts->early_suspend.suspend = ts_suspend;
\r
249 ts->early_suspend.resume = ts_resume;
\r
250 ts->early_suspend.level = 0x02;
\r
251 register_early_suspend(&ts->early_suspend);
\r
258 static int ts_i2c_remove(struct i2c_client *i2c)
\r
260 struct ts_private_data *ts = i2c_get_clientdata(i2c);
\r
262 ts_device_exit(ts);
\r
268 static const struct i2c_device_id ts_i2c_id[] = {
\r
269 {"auto_ts_i2c", 0},
\r
272 MODULE_DEVICE_TABLE(i2c, ts_i2c_id);
\r
274 static struct i2c_driver ts_i2c_driver = {
\r
276 .name = "auto_ts_i2c",
\r
277 .owner = THIS_MODULE,
\r
279 .probe = ts_i2c_probe,
\r
280 .remove = ts_i2c_remove,
\r
281 .id_table = ts_i2c_id,
\r
284 static int __init ts_i2c_init(void)
\r
288 printk("%s\n", __FUNCTION__);
\r
289 ret = i2c_add_driver(&ts_i2c_driver);
\r
291 pr_err("Failed to register ts I2C driver: %d\n", ret);
\r
295 subsys_initcall_sync(ts_i2c_init);
\r
297 static void __exit ts_i2c_exit(void)
\r
299 i2c_del_driver(&ts_i2c_driver);
\r
301 module_exit(ts_i2c_exit);
\r