video: rockchip: hdmi: support hdr function
[firefly-linux-kernel-4.4.55.git] / drivers / input / ts / ts-i2c.c
1 /* drivers/input/ts/ts-i2c.c - touchscreen i2c handle\r
2  *\r
3  * Copyright (C) 2012-2015 ROCKCHIP.\r
4  * Author: luowei <lw@rock-chips.com>\r
5  *\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
9  *\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
14  *\r
15  */\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
32 #endif\r
33 #include <linux/ts-auto.h>\r
34 \r
35 #define TS_I2C_RATE 200*1000\r
36 \r
37 #if 0\r
38 #define TS_DEBUG_ENABLE\r
39 #define DBG(x...) printk(x)\r
40 #else\r
41 #define DBG(x...)\r
42 #endif\r
43 \r
44 \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
47 {\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
51         int i,res;\r
52         \r
53         if (!dest || !i2c_adap) {\r
54                 printk("%s:line=%d,error\n",__func__,__LINE__);\r
55                 return -EINVAL;\r
56         }\r
57 \r
58         client->addr = ts->ops->slave_addr;\r
59 \r
60         msgs[0].addr = client->addr;\r
61         msgs[0].flags = 0;      /* write */\r
62         msgs[0].buf = (unsigned char *)&reg;\r
63         if(reg_size == 2)               \r
64         msgs[0].len = 2;\r
65         else    \r
66         msgs[0].len = 1;\r
67         msgs[0].scl_rate = TS_I2C_RATE;\r
68         \r
69         msgs[1].addr = client->addr;\r
70         msgs[1].flags = I2C_M_RD;\r
71         msgs[1].buf = dest;\r
72         msgs[1].len = bytes;\r
73         msgs[1].scl_rate = TS_I2C_RATE; \r
74 \r
75         res = i2c_transfer(i2c_adap, msgs, 2);\r
76         if (res == 2)\r
77                 return 0;\r
78         else if(res == 0)\r
79                 return -EBUSY;\r
80         else\r
81                 return res;\r
82         \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
87         DBG("\n");\r
88 #endif  \r
89 \r
90         \r
91 }\r
92 \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
95  * revised.\r
96  */\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
99 {\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
103         int res;\r
104         unsigned char buf[bytes + 2];\r
105         \r
106         if (!src || !i2c_adap) {\r
107                 printk("%s:line=%d,error\n",__func__,__LINE__);\r
108                 return -EINVAL;\r
109         }\r
110 \r
111         \r
112         client->addr = ts->ops->slave_addr;\r
113         \r
114         if(ts->ops->reg_size == 2)\r
115         {\r
116                 buf[0] = (reg & 0xff00) >> 8;\r
117                 buf[1] = (reg & 0x00ff) & 0xff;\r
118                 memcpy(&buf[2], src, bytes);\r
119         }\r
120         else\r
121         {\r
122                 buf[0] = reg & 0xff;\r
123                 memcpy(&buf[1], src, bytes);\r
124         }\r
125 \r
126 #ifdef TS_DEBUG_ENABLE\r
127         int i = 0;\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
131         DBG("\n");\r
132 #endif  \r
133 \r
134         if (!src || !i2c_adap) {\r
135                 printk("%s:line=%d,error\n",__func__,__LINE__);\r
136                 return -EINVAL;\r
137         }\r
138 \r
139         msgs[0].addr = client->addr;\r
140         msgs[0].flags = 0;      /* write */\r
141         msgs[0].buf = buf;\r
142         if(ts->ops->reg_size  == 2)             \r
143         msgs[0].len = bytes+2;\r
144         else    \r
145         msgs[0].len = bytes+1;  \r
146         msgs[0].scl_rate = TS_I2C_RATE;\r
147 \r
148         res = i2c_transfer(i2c_adap, msgs, 1);\r
149         if (res == 1)\r
150                 return 0;\r
151         else if(res == 0)\r
152                 return -EBUSY;\r
153         else\r
154                 return res;\r
155                         \r
156 }\r
157 \r
158 int ts_bulk_read_normal(struct ts_private_data *ts,\r
159                      int count, unsigned char *buf, int rate)\r
160 {\r
161         int ret;\r
162         unsigned short reg;\r
163         struct i2c_client *client = ts->control_data;\r
164         client->addr = ts->ops->slave_addr;\r
165         \r
166         mutex_lock(&ts->io_lock);\r
167         ret = i2c_master_normal_recv(client, buf, count, rate);\r
168         if(ret == 1)\r
169                 ret = 0;\r
170         mutex_unlock(&ts->io_lock);\r
171 \r
172         return ret;\r
173 }\r
174 EXPORT_SYMBOL_GPL(ts_bulk_read_normal);\r
175 \r
176 \r
177 int ts_bulk_write_normal(struct ts_private_data *ts, int count, unsigned char *buf, int rate)\r
178 {\r
179         int ret;\r
180         unsigned short reg;\r
181         struct i2c_client *client = ts->control_data;\r
182         client->addr = ts->ops->slave_addr;\r
183         \r
184         mutex_lock(&ts->io_lock);\r
185         ret = i2c_master_normal_send(client, buf, count, rate);\r
186         if(ret == 1)\r
187                 ret = 0;\r
188         mutex_unlock(&ts->io_lock);\r
189 \r
190         return ret;\r
191 }\r
192 EXPORT_SYMBOL_GPL(ts_bulk_write_normal);\r
193 \r
194 \r
195 \r
196 #ifdef CONFIG_HAS_EARLYSUSPEND\r
197 static void ts_suspend(struct early_suspend *h)\r
198 {\r
199         struct ts_private_data *ts = \r
200                         container_of(h, struct ts_private_data, early_suspend);\r
201         \r
202         return ts_device_suspend(ts);\r
203 }\r
204 \r
205 static void ts_resume(struct early_suspend *h)\r
206 {\r
207         struct ts_private_data *ts = \r
208                         container_of(h, struct ts_private_data, early_suspend);\r
209 \r
210         return ts_device_resume(ts);\r
211 }\r
212 #endif\r
213 \r
214 static int ts_i2c_probe(struct i2c_client *i2c,\r
215                             const struct i2c_device_id *id)\r
216 {\r
217         struct ts_private_data *ts;\r
218         int ret,gpio,irq;\r
219         int type = TS_BUS_TYPE_I2C;\r
220 \r
221         if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) {\r
222                 dev_err(&i2c->adapter->dev, "%s failed\n", __func__);\r
223                 return -ENODEV;\r
224         }\r
225         \r
226         ts = kzalloc(sizeof(struct ts_private_data), GFP_KERNEL);\r
227         if (ts == NULL)\r
228                 return -ENOMEM;\r
229 \r
230         i2c_set_clientdata(i2c, ts);\r
231         \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
237 \r
238         ret = ts_device_init(ts, type, ts->irq);\r
239         if(ret)\r
240         {\r
241                 printk("%s:fail to regist touch, type is %d\n",__func__, type);\r
242                 return -1;\r
243         }\r
244         \r
245 #ifdef CONFIG_HAS_EARLYSUSPEND\r
246         if((ts->ops->suspend) && (ts->ops->resume))\r
247         {\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
252         }\r
253 #endif\r
254 \r
255         return 0;\r
256 }\r
257 \r
258 static int ts_i2c_remove(struct i2c_client *i2c)\r
259 {\r
260         struct ts_private_data *ts = i2c_get_clientdata(i2c);\r
261 \r
262         ts_device_exit(ts);\r
263 \r
264         return 0;\r
265 }\r
266 \r
267 \r
268 static const struct i2c_device_id ts_i2c_id[] = {\r
269         {"auto_ts_i2c", 0},\r
270         {},\r
271 };\r
272 MODULE_DEVICE_TABLE(i2c, ts_i2c_id);\r
273 \r
274 static struct i2c_driver ts_i2c_driver = {\r
275         .driver = {\r
276                 .name = "auto_ts_i2c",\r
277                 .owner = THIS_MODULE,\r
278         },\r
279         .probe = ts_i2c_probe,\r
280         .remove = ts_i2c_remove,\r
281         .id_table = ts_i2c_id,\r
282 };\r
283 \r
284 static int __init ts_i2c_init(void)\r
285 {\r
286         int ret;\r
287 \r
288         printk("%s\n", __FUNCTION__);\r
289         ret = i2c_add_driver(&ts_i2c_driver);\r
290         if (ret != 0)\r
291                 pr_err("Failed to register ts I2C driver: %d\n", ret);\r
292 \r
293         return ret;\r
294 }\r
295 subsys_initcall_sync(ts_i2c_init);\r
296 \r
297 static void __exit ts_i2c_exit(void)\r
298 {\r
299         i2c_del_driver(&ts_i2c_driver);\r
300 }\r
301 module_exit(ts_i2c_exit);\r
302 \r