import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / input / touchscreen / mediatek / cy8ctma / cyttsp4_i2c.c
1 /* BEGIN PN:DTS2013051703879 ,Added by l00184147, 2013/5/17*/
2 //add Touch driver for G610-T11
3 /* BEGIN PN:DTS2013012601133 ,Modified by l00184147, 2013/1/26*/
4 /* BEGIN PN:DTS2013011401860 ,Modified by l00184147, 2013/1/14*/
5 /* BEGIN PN:SPBB-1218 ,Added by l00184147, 2012/12/20*/
6 /* BEGIN PN:SPBB-1226 ,Added by f00184246, 2012/1/05*/
7 /*
8 * cyttsp4_i2c.c
9 * Cypress TrueTouch(TM) Standard Product V4 I2C Driver module.
10 * For use with Cypress Txx4xx parts.
11 * Supported parts include:
12 * TMA4XX
13 * TMA1036
14 *
15 * Copyright (C) 2012 Cypress Semiconductor
16 * Copyright (C) 2011 Sony Ericsson Mobile Communications AB.
17 *
18 * Author: Aleksej Makarov <aleksej.makarov@sonyericsson.com>
19 * Modified by: Cypress Semiconductor for test with device
20 *
21 * This program is free software; you can redistribute it and/or
22 * modify it under the terms of the GNU General Public License
23 * version 2, and only version 2, as published by the
24 * Free Software Foundation.
25 *
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 *
31 * You should have received a copy of the GNU General Public License along
32 * with this program; if not, write to the Free Software Foundation, Inc.,
33 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
34 *
35 * Contact Cypress Semiconductor at www.cypress.com <ttdrivers@cypress.com>
36 *
37 */
38
39 #include "cyttsp4_bus.h"
40 #include "cyttsp4_core.h"
41 #include "cyttsp4_i2c.h"
42
43 #include <linux/delay.h>
44 #include <linux/hrtimer.h>
45 #include <linux/i2c.h>
46 #include <linux/init.h>
47 #include <linux/module.h>
48 #include <linux/mutex.h>
49 #include <linux/pm_runtime.h>
50 #include <linux/slab.h>
51
52 #define lmdebug_dump_buf //
53
54 #define CY_I2C_DATA_SIZE (3 * 256)
55
56 struct cyttsp4_i2c {
57 struct i2c_client *client;
58 u8 wr_buf[CY_I2C_DATA_SIZE];
59 struct hrtimer timer;
60 struct mutex lock;
61 atomic_t timeout;
62 };
63
64 #define lmdebug_dump_buf //
65 #ifndef lmdebug_dump_buf
66 extern void lmdebug_dump_buf(u8 *dptr, int size,const char *data_name); // pr_buf
67 #endif
68
69 #define MTK_I2C_DMA
70 #ifdef MTK_I2C_DMA
71 extern int cyttsp4_MTK_i2c_write(struct i2c_client *client, const uint8_t *buf, int len);
72 extern int cyttsp4_MTK_i2c_read(struct i2c_client *client, uint8_t *buf, int len);
73 #endif
74
75 static int cyttsp4_i2c_read_block_data(struct cyttsp4_i2c *ts_i2c, u8 addr,
76 size_t length, void *values)
77 {
78 int rc;
79
80 //pr_info("cyttsp4_i2c_read_block_data addr:0x%x length:%d buf:0x%p \n", addr, length, values);
81
82 /* write addr */
83 #ifdef MTK_I2C_DMA
84 rc = cyttsp4_MTK_i2c_write(ts_i2c->client, &addr, sizeof(addr));
85 #else
86 rc = i2c_master_send(ts_i2c->client, &addr, sizeof(addr));
87 #endif
88 if (rc < 0)
89 return rc;
90 else if (rc != sizeof(addr))
91 return -EIO;
92
93 /* read data */
94 #ifdef MTK_I2C_DMA
95 rc = cyttsp4_MTK_i2c_read(ts_i2c->client, values, length);
96 #else
97 rc = i2c_master_recv(ts_i2c->client, values, length);
98 #endif
99
100 return (rc < 0) ? rc : rc != length ? -EIO : 0;
101 }
102
103
104 static int cyttsp4_i2c_write_block_data(struct cyttsp4_i2c *ts_i2c, u8 addr,
105 size_t length, const void *values)
106 {
107 int rc;
108
109 if (sizeof(ts_i2c->wr_buf) < (length + 1))
110 return -ENOMEM;
111
112 ts_i2c->wr_buf[0] = addr;
113 memcpy(&ts_i2c->wr_buf[1], values, length);
114 length += 1;
115
116 /* write data */
117 #ifdef MTK_I2C_DMA
118 rc = cyttsp4_MTK_i2c_write(ts_i2c->client, ts_i2c->wr_buf, length);
119 #else
120 rc = i2c_master_send(ts_i2c->client, ts_i2c->wr_buf, length);
121 #endif
122
123 return (rc < 0) ? rc : rc != length ? -EIO : 0;
124 }
125
126 static int cyttsp4_i2c_write(struct cyttsp4_adapter *adap, u8 addr,
127 const void *buf, int size)
128 {
129 struct cyttsp4_i2c *ts = dev_get_drvdata(adap->dev);
130 int rc;
131 lmdebug_dump_buf(buf, size, "cyttsp4_i2c_write");
132
133 pm_runtime_get_noresume(adap->dev);
134 mutex_lock(&ts->lock);
135 rc = cyttsp4_i2c_write_block_data(ts, addr, size, buf);
136 mutex_unlock(&ts->lock);
137 pm_runtime_put_noidle(adap->dev);
138
139 //dev_dbg("%s: Done\n", __func__);
140 return rc;
141 }
142
143 static int cyttsp4_i2c_read(struct cyttsp4_adapter *adap, u8 addr,
144 void *buf, int size)
145 {
146 struct cyttsp4_i2c *ts = dev_get_drvdata(adap->dev);
147 int rc;
148 //pr_info("%s: Enter\n", __func__);
149
150 pm_runtime_get_noresume(adap->dev);
151 mutex_lock(&ts->lock);
152 rc = cyttsp4_i2c_read_block_data(ts, addr, size, buf);
153 mutex_unlock(&ts->lock);
154 pm_runtime_put_noidle(adap->dev);
155
156 lmdebug_dump_buf(buf, size, "cyttsp4_i2c_read");
157
158 return rc;
159 }
160
161 static struct cyttsp4_ops ops = {
162 .write = cyttsp4_i2c_write,
163 .read = cyttsp4_i2c_read,
164 };
165
166 static int cyttsp4_i2c_probe(struct i2c_client *client,
167 const struct i2c_device_id *i2c_id)
168 {
169 struct cyttsp4_i2c *ts_i2c;
170 struct device *dev = &client->dev;
171 char const *adap_id = dev_get_platdata(dev);
172 char const *id;
173 int rc;
174
175 dev_info(dev, "%s: Starting %s probe...\n", __func__, CYTTSP4_I2C_NAME);
176
177 dev_dbg(dev, "%s: debug on\n", __func__);
178 dev_vdbg(dev, "%s: verbose debug on\n", __func__);
179
180 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
181 dev_err(dev, "%s: fail check I2C functionality\n", __func__);
182 rc = -EIO;
183 goto error_alloc_data_failed;
184 }
185
186 ts_i2c = kzalloc(sizeof(struct cyttsp4_i2c), GFP_KERNEL);
187 if (ts_i2c == NULL) {
188 dev_err(dev, "%s: Error, kzalloc.\n", __func__);
189 rc = -ENOMEM;
190 goto error_alloc_data_failed;
191 }
192
193 mutex_init(&ts_i2c->lock);
194 ts_i2c->client = client;
195 client->dev.bus = &i2c_bus_type;
196 i2c_set_clientdata(client, ts_i2c);
197 //dev_set_drvdata(&client->dev, ts_i2c); //MOD BY ZHONG: no need??
198
199 if (adap_id)
200 id = adap_id;
201 else
202 id = CYTTSP4_I2C_NAME;
203
204 dev_dbg(dev, "%s: add adap='%s' (CYTTSP4_I2C_NAME=%s)\n", __func__, id,
205 CYTTSP4_I2C_NAME);
206
207 pm_runtime_enable(&client->dev);
208
209 rc = cyttsp4_add_adapter(id, &ops, dev);
210 if (rc) {
211 dev_err(dev, "%s: Error on probe %s\n", __func__,
212 CYTTSP4_I2C_NAME);
213 goto add_adapter_err;
214 }
215
216 dev_info(dev, "%s: Successful probe %s\n", __func__, CYTTSP4_I2C_NAME);
217
218 return 0;
219
220 add_adapter_err:
221 pm_runtime_disable(&client->dev);
222 //dev_set_drvdata(&client->dev, NULL); //MOD BY ZHONG: no need??
223 i2c_set_clientdata(client, NULL);
224 kfree(ts_i2c);
225 error_alloc_data_failed:
226 return rc;
227 }
228
229 /* registered in driver struct */
230 static int cyttsp4_i2c_remove(struct i2c_client *client)
231 {
232 struct device *dev = &client->dev;
233 struct cyttsp4_i2c *ts_i2c = dev_get_drvdata(dev);
234 char const *adap_id = dev_get_platdata(dev);
235 char const *id;
236
237 if (adap_id)
238 id = adap_id;
239 else
240 id = CYTTSP4_I2C_NAME;
241
242 dev_info(dev, "%s\n", __func__);
243 cyttsp4_del_adapter(id);
244 pm_runtime_disable(&client->dev);
245 dev_set_drvdata(&client->dev, NULL);
246 i2c_set_clientdata(client, NULL);
247 kfree(ts_i2c);
248 return 0;
249 }
250
251 static const struct i2c_device_id cyttsp4_i2c_id[] = {
252 { CYTTSP4_I2C_NAME, 0 }, { }
253 };
254
255 static struct i2c_driver cyttsp4_i2c_driver = {
256 .driver = {
257 .name = CYTTSP4_I2C_NAME,
258 .owner = THIS_MODULE,
259 },
260 .probe = cyttsp4_i2c_probe,
261 .remove = cyttsp4_i2c_remove,
262 .id_table = cyttsp4_i2c_id,
263 };
264
265 static int __init cyttsp4_i2c_init(void)
266 {
267 int rc = i2c_add_driver(&cyttsp4_i2c_driver);
268
269 pr_info("%s: Cypress TTSP I2C Touchscreen Driver (Built %s) rc=%d\n",
270 __func__, CY_DRIVER_DATE, rc);
271 return rc;
272 }
273 module_init(cyttsp4_i2c_init);
274
275 static void __exit cyttsp4_i2c_exit(void)
276 {
277 i2c_del_driver(&cyttsp4_i2c_driver);
278 pr_info("%s: module exit\n", __func__);
279 }
280 module_exit(cyttsp4_i2c_exit);
281
282 MODULE_ALIAS(CYTTSP4_I2C_NAME);
283 MODULE_LICENSE("GPL");
284 MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product (TTSP) I2C driver");
285 MODULE_AUTHOR("Cypress");
286 MODULE_DEVICE_TABLE(i2c, cyttsp4_i2c_id);
287 /* END PN:SPBB-1226 ,Added by f00184246, 2012/1/05*/
288 /* END PN:SPBB-1218 ,Added by l00184147, 2012/12/20*/
289 /* END PN:DTS2013011401860 ,Modified by l00184147, 2013/1/14*/
290 /* END PN:DTS2013012601133 ,Modified by l00184147, 2013/1/26*/
291 /* END PN:DTS2013051703879 ,Added by l00184147, 2013/5/17*/