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*/
9 * Cypress TrueTouch(TM) Standard Product V4 I2C Driver module.
10 * For use with Cypress Txx4xx parts.
11 * Supported parts include:
15 * Copyright (C) 2012 Cypress Semiconductor
16 * Copyright (C) 2011 Sony Ericsson Mobile Communications AB.
18 * Author: Aleksej Makarov <aleksej.makarov@sonyericsson.com>
19 * Modified by: Cypress Semiconductor for test with device
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.
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.
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.
35 * Contact Cypress Semiconductor at www.cypress.com <ttdrivers@cypress.com>
39 #include "cyttsp4_bus.h"
40 #include "cyttsp4_core.h"
41 #include "cyttsp4_i2c.h"
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>
52 #define lmdebug_dump_buf //
54 #define CY_I2C_DATA_SIZE (3 * 256)
57 struct i2c_client
*client
;
58 u8 wr_buf
[CY_I2C_DATA_SIZE
];
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
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
);
75 static int cyttsp4_i2c_read_block_data(struct cyttsp4_i2c
*ts_i2c
, u8 addr
,
76 size_t length
, void *values
)
80 //pr_info("cyttsp4_i2c_read_block_data addr:0x%x length:%d buf:0x%p \n", addr, length, values);
84 rc
= cyttsp4_MTK_i2c_write(ts_i2c
->client
, &addr
, sizeof(addr
));
86 rc
= i2c_master_send(ts_i2c
->client
, &addr
, sizeof(addr
));
90 else if (rc
!= sizeof(addr
))
95 rc
= cyttsp4_MTK_i2c_read(ts_i2c
->client
, values
, length
);
97 rc
= i2c_master_recv(ts_i2c
->client
, values
, length
);
100 return (rc
< 0) ? rc
: rc
!= length
? -EIO
: 0;
104 static int cyttsp4_i2c_write_block_data(struct cyttsp4_i2c
*ts_i2c
, u8 addr
,
105 size_t length
, const void *values
)
109 if (sizeof(ts_i2c
->wr_buf
) < (length
+ 1))
112 ts_i2c
->wr_buf
[0] = addr
;
113 memcpy(&ts_i2c
->wr_buf
[1], values
, length
);
118 rc
= cyttsp4_MTK_i2c_write(ts_i2c
->client
, ts_i2c
->wr_buf
, length
);
120 rc
= i2c_master_send(ts_i2c
->client
, ts_i2c
->wr_buf
, length
);
123 return (rc
< 0) ? rc
: rc
!= length
? -EIO
: 0;
126 static int cyttsp4_i2c_write(struct cyttsp4_adapter
*adap
, u8 addr
,
127 const void *buf
, int size
)
129 struct cyttsp4_i2c
*ts
= dev_get_drvdata(adap
->dev
);
131 lmdebug_dump_buf(buf
, size
, "cyttsp4_i2c_write");
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
);
139 //dev_dbg("%s: Done\n", __func__);
143 static int cyttsp4_i2c_read(struct cyttsp4_adapter
*adap
, u8 addr
,
146 struct cyttsp4_i2c
*ts
= dev_get_drvdata(adap
->dev
);
148 //pr_info("%s: Enter\n", __func__);
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
);
156 lmdebug_dump_buf(buf
, size
, "cyttsp4_i2c_read");
161 static struct cyttsp4_ops ops
= {
162 .write
= cyttsp4_i2c_write
,
163 .read
= cyttsp4_i2c_read
,
166 static int cyttsp4_i2c_probe(struct i2c_client
*client
,
167 const struct i2c_device_id
*i2c_id
)
169 struct cyttsp4_i2c
*ts_i2c
;
170 struct device
*dev
= &client
->dev
;
171 char const *adap_id
= dev_get_platdata(dev
);
175 dev_info(dev
, "%s: Starting %s probe...\n", __func__
, CYTTSP4_I2C_NAME
);
177 dev_dbg(dev
, "%s: debug on\n", __func__
);
178 dev_vdbg(dev
, "%s: verbose debug on\n", __func__
);
180 if (!i2c_check_functionality(client
->adapter
, I2C_FUNC_I2C
)) {
181 dev_err(dev
, "%s: fail check I2C functionality\n", __func__
);
183 goto error_alloc_data_failed
;
186 ts_i2c
= kzalloc(sizeof(struct cyttsp4_i2c
), GFP_KERNEL
);
187 if (ts_i2c
== NULL
) {
188 dev_err(dev
, "%s: Error, kzalloc.\n", __func__
);
190 goto error_alloc_data_failed
;
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??
202 id
= CYTTSP4_I2C_NAME
;
204 dev_dbg(dev
, "%s: add adap='%s' (CYTTSP4_I2C_NAME=%s)\n", __func__
, id
,
207 pm_runtime_enable(&client
->dev
);
209 rc
= cyttsp4_add_adapter(id
, &ops
, dev
);
211 dev_err(dev
, "%s: Error on probe %s\n", __func__
,
213 goto add_adapter_err
;
216 dev_info(dev
, "%s: Successful probe %s\n", __func__
, CYTTSP4_I2C_NAME
);
221 pm_runtime_disable(&client
->dev
);
222 //dev_set_drvdata(&client->dev, NULL); //MOD BY ZHONG: no need??
223 i2c_set_clientdata(client
, NULL
);
225 error_alloc_data_failed
:
229 /* registered in driver struct */
230 static int cyttsp4_i2c_remove(struct i2c_client
*client
)
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
);
240 id
= CYTTSP4_I2C_NAME
;
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
);
251 static const struct i2c_device_id cyttsp4_i2c_id
[] = {
252 { CYTTSP4_I2C_NAME
, 0 }, { }
255 static struct i2c_driver cyttsp4_i2c_driver
= {
257 .name
= CYTTSP4_I2C_NAME
,
258 .owner
= THIS_MODULE
,
260 .probe
= cyttsp4_i2c_probe
,
261 .remove
= cyttsp4_i2c_remove
,
262 .id_table
= cyttsp4_i2c_id
,
265 static int __init
cyttsp4_i2c_init(void)
267 int rc
= i2c_add_driver(&cyttsp4_i2c_driver
);
269 pr_info("%s: Cypress TTSP I2C Touchscreen Driver (Built %s) rc=%d\n",
270 __func__
, CY_DRIVER_DATE
, rc
);
273 module_init(cyttsp4_i2c_init
);
275 static void __exit
cyttsp4_i2c_exit(void)
277 i2c_del_driver(&cyttsp4_i2c_driver
);
278 pr_info("%s: module exit\n", __func__
);
280 module_exit(cyttsp4_i2c_exit
);
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*/