xref: /OK3568_Linux_fs/kernel/drivers/input/touchscreen/cyttsp5/cyttsp5_i2c.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * cyttsp5_i2c.c
3  * Parade TrueTouch(TM) Standard Product V5 I2C Module.
4  * For use with Parade touchscreen controllers.
5  * Supported parts include:
6  * CYTMA5XX
7  * CYTMA448
8  * CYTMA445A
9  * CYTT21XXX
10  * CYTT31XXX
11  *
12  * Copyright (C) 2015 Parade Technologies
13  * Copyright (C) 2012-2015 Cypress Semiconductor
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * version 2, and only version 2, as published by the
18  * Free Software Foundation.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * Contact Parade Technologies at www.paradetech.com <ttdrivers@paradetech.com>
26  *
27  */
28 
29 #include "cyttsp5_regs.h"
30 
31 #include <linux/i2c.h>
32 #include <linux/version.h>
33 
34 #define CY_I2C_DATA_SIZE  (2 * 256)
35 
36 static int cyttsp5_i2c_remove(struct i2c_client *client);
37 
cyttsp5_i2c_read_default(struct device * dev,void * buf,int size)38 static int cyttsp5_i2c_read_default(struct device *dev, void *buf, int size)
39 {
40 	struct i2c_client *client = to_i2c_client(dev);
41 	int rc;
42 
43 	if (!buf || !size || size > CY_I2C_DATA_SIZE)
44 		return -EINVAL;
45 	//printk("*****cyttsp5_i2c_read_default size=%d\n", size);
46 	rc = i2c_master_recv(client, buf, size);
47 
48 	return (rc < 0) ? rc : rc != size ? -EIO : 0;
49 }
50 
cyttsp5_i2c_read_default_nosize(struct device * dev,u8 * buf,u32 max)51 static int cyttsp5_i2c_read_default_nosize(struct device *dev, u8 *buf, u32 max)
52 {
53 	struct i2c_client *client = to_i2c_client(dev);
54 	struct i2c_msg msgs[2];
55 	u8 msg_count = 1;
56 	int rc;
57 	u32 size;
58 
59 	if (!buf)
60 		return -EINVAL;
61 
62 	//printk("*****cyttsp5_i2c_read_default_nosize max=%d\n", max);
63 	msgs[0].addr = client->addr;
64 	msgs[0].flags = (client->flags & I2C_M_TEN) | I2C_M_RD;
65 	msgs[0].len = 2;
66 	msgs[0].buf = buf;
67 	rc = i2c_transfer(client->adapter, msgs, msg_count);
68 	if (rc < 0 || rc != msg_count)
69 		return (rc < 0) ? rc : -EIO;
70 
71 	size = get_unaligned_le16(&buf[0]);
72 	if (!size || size == 2 || size >= CY_PIP_1P7_EMPTY_BUF)
73 		/* Before PIP 1.7, empty buffer is 0x0002;
74 		From PIP 1.7, empty buffer is 0xFFXX */
75 		return 0;
76 
77 	if (size > max)
78 		return -EINVAL;
79 
80 	rc = i2c_master_recv(client, buf, size);
81 
82 	return (rc < 0) ? rc : rc != (int)size ? -EIO : 0;
83 }
84 
cyttsp5_i2c_write_read_specific(struct device * dev,u8 write_len,u8 * write_buf,u8 * read_buf)85 static int cyttsp5_i2c_write_read_specific(struct device *dev, u8 write_len,
86 		u8 *write_buf, u8 *read_buf)
87 {
88 	struct i2c_client *client = to_i2c_client(dev);
89 	struct i2c_msg msgs[2];
90 	u8 msg_count = 1;
91 	int rc;
92 
93 	//printk("*****cyttsp5_i2c_write_read_specific 0x%x, 0x%x, len=%d\n", write_buf[0], write_buf[1],write_len);
94 	if (!write_buf || !write_len)
95 		return -EINVAL;
96 
97 	msgs[0].addr = client->addr;
98 	msgs[0].flags = client->flags & I2C_M_TEN;
99 	msgs[0].len = write_len;
100 	msgs[0].buf = write_buf;
101 	rc = i2c_transfer(client->adapter, msgs, msg_count);
102 
103 	//printk("*****cyttsp5_i2c_write_read_specific rc=%d\n", rc);
104 	if (rc < 0 || rc != msg_count)
105 		return (rc < 0) ? rc : -EIO;
106 
107 	rc = 0;
108 
109 	//printk("*****cyttsp5_i2c_write_read_specific read_buf=0x%x\n", read_buf);
110 	if (read_buf)
111 		rc = cyttsp5_i2c_read_default_nosize(dev, read_buf,
112 				CY_I2C_DATA_SIZE);
113 
114 	return rc;
115 }
116 
117 static struct cyttsp5_bus_ops cyttsp5_i2c_bus_ops = {
118 	.bustype = BUS_I2C,
119 	.read_default = cyttsp5_i2c_read_default,
120 	.read_default_nosize = cyttsp5_i2c_read_default_nosize,
121 	.write_read_specific = cyttsp5_i2c_write_read_specific,
122 };
123 
124 #ifdef CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP5_DEVICETREE_SUPPORT
125 static const struct of_device_id cyttsp5_i2c_of_match[] = {
126 	{ .compatible = "cy,cyttsp5_i2c_adapter", },
127 	{ }
128 };
129 MODULE_DEVICE_TABLE(of, cyttsp5_i2c_of_match);
130 #endif
131 
cyttsp5_i2c_probe(struct i2c_client * client,const struct i2c_device_id * i2c_id)132 static int cyttsp5_i2c_probe(struct i2c_client *client,
133 	const struct i2c_device_id *i2c_id)
134 {
135 	struct device *dev = &client->dev;
136 #ifdef CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP5_DEVICETREE_SUPPORT
137 	const struct of_device_id *match;
138 #endif
139 	struct cyttsp5_platform_data *pdata;
140 	int rc;
141 
142 	printk("*****cyttsp5_i2c_probe start \n");
143 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
144 		dev_err(dev, "I2C functionality not Supported\n");
145 		return -EIO;
146 	}
147 
148 
149 #ifdef CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP5_DEVICETREE_SUPPORT
150 	match = of_match_device(of_match_ptr(cyttsp5_i2c_of_match), dev);
151 	if (match) {
152 		rc = cyttsp5_devtree_create_and_get_pdata(dev);
153 		if (rc < 0)
154 			return rc;
155 	}
156 #endif
157 	pdata = dev_get_platdata(dev);
158 	if (pdata && pdata->core_pdata) {
159 		char buf[32];
160 		/* Call platform init function */
161 		if (pdata->core_pdata->init) {
162 			dev_info(dev, "%s: Init HW\n", __func__);
163 			rc = pdata->core_pdata->init(pdata->core_pdata, 1, dev);
164 			if (rc < 0) {
165 				dev_err(dev, "%s: HW Init fail %d\n", __func__, rc);
166 				return -EIO;
167 			}
168 		} else {
169 			dev_info(dev, "%s: No HW INIT function\n", __func__);
170 		}
171 		rc = cyttsp5_i2c_read_default(&client->dev, buf, 16);
172 		if (rc < 0) {
173 			dev_err(dev, "%s, read_default rc=%d\n", __func__, rc);
174 			return -ENODEV;
175 		}
176 	}
177 	rc = cyttsp5_probe(&cyttsp5_i2c_bus_ops, &client->dev, client->irq,
178 			  CY_I2C_DATA_SIZE);
179 
180 #ifdef CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP5_DEVICETREE_SUPPORT
181 	if (rc && match)
182 		cyttsp5_devtree_clean_pdata(dev);
183 #endif
184 	return rc;
185 }
186 
cyttsp5_i2c_remove(struct i2c_client * client)187 static int cyttsp5_i2c_remove(struct i2c_client *client)
188 {
189 #ifdef CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP5_DEVICETREE_SUPPORT
190 	struct device *dev = &client->dev;
191 	const struct of_device_id *match;
192 #endif
193 	struct cyttsp5_core_data *cd = i2c_get_clientdata(client);
194 
195 	cyttsp5_release(cd);
196 
197 #ifdef CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP5_DEVICETREE_SUPPORT
198 	match = of_match_device(of_match_ptr(cyttsp5_i2c_of_match), dev);
199 	if (match)
200 		cyttsp5_devtree_clean_pdata(dev);
201 #endif
202 
203 	return 0;
204 }
205 
206 static const struct i2c_device_id cyttsp5_i2c_id[] = {
207 	{ CYTTSP5_I2C_NAME, 0, },
208 	{ }
209 };
210 MODULE_DEVICE_TABLE(i2c, cyttsp5_i2c_id);
211 
212 static struct i2c_driver cyttsp5_i2c_driver = {
213 	.driver = {
214 		.name = CYTTSP5_I2C_NAME,
215 		.owner = THIS_MODULE,
216 		.pm = &cyttsp5_pm_ops,
217 #ifdef CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP5_DEVICETREE_SUPPORT
218 		.of_match_table = cyttsp5_i2c_of_match,
219 #endif
220 	},
221 	.probe = cyttsp5_i2c_probe,
222 	.remove = cyttsp5_i2c_remove,
223 	.id_table = cyttsp5_i2c_id,
224 };
225 
226 #if (KERNEL_VERSION(3, 3, 0) <= LINUX_VERSION_CODE)
227 module_i2c_driver(cyttsp5_i2c_driver);
228 #else
cyttsp5_i2c_init(void)229 static int __init cyttsp5_i2c_init(void)
230 {
231 	int rc = i2c_add_driver(&cyttsp5_i2c_driver);
232 
233 	pr_info("%s: Parade TTSP I2C Driver (Built %s) rc=%d\n",
234 			__func__, CY_DRIVER_VERSION, rc);
235 	return rc;
236 }
237 late_initcall(cyttsp5_i2c_init);
238 
cyttsp5_i2c_exit(void)239 static void __exit cyttsp5_i2c_exit(void)
240 {
241 	i2c_del_driver(&cyttsp5_i2c_driver);
242 }
243 module_exit(cyttsp5_i2c_exit);
244 #endif
245 
246 MODULE_LICENSE("GPL");
247 MODULE_DESCRIPTION("Parade TrueTouch(R) Standard Product I2C driver");
248 MODULE_AUTHOR("Parade Technologies <ttdrivers@paradetech.com>");
249