xref: /OK3568_Linux_fs/kernel/drivers/input/touchscreen/focaltech_touch/focaltech_i2c.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  *
3  * FocalTech TouchScreen driver.
4  *
5  * Copyright (c) 2012-2018, FocalTech Systems, Ltd., all rights reserved.
6  *
7  * This software is licensed under the terms of the GNU General Public
8  * License version 2, as published by the Free Software Foundation, and
9  * may be copied, distributed, and modified under those terms.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17 
18 /************************************************************************
19 *
20 * File Name: focaltech_i2c.c
21 *
22 * Author: Focaltech Driver Team
23 *
24 * Created: 2016-08-04
25 *
26 * Abstract: i2c communication with TP
27 *
28 * Version: v1.0
29 *
30 * Revision History:
31 *
32 ************************************************************************/
33 
34 /*****************************************************************************
35 * Included header files
36 *****************************************************************************/
37 #include "focaltech_core.h"
38 
39 /*****************************************************************************
40 * Private constant and macro definitions using #define
41 *****************************************************************************/
42 #define I2C_RETRY_NUMBER        3
43 /*****************************************************************************
44 * Private enumerations, structures and unions using typedef
45 *****************************************************************************/
46 
47 /*****************************************************************************
48 * Static variables
49 *****************************************************************************/
50 static DEFINE_MUTEX(i2c_rw_access);
51 
52 /*****************************************************************************
53 * Global variable or extern global variabls/functions
54 *****************************************************************************/
55 
56 /*****************************************************************************
57 * Static function prototypes
58 *****************************************************************************/
59 
60 /*****************************************************************************
61 * functions body
62 *****************************************************************************/
63 
64 /************************************************************************
65 * Name: fts_i2c_read
66 * Brief: i2c read
67 * Input: i2c info, write buf, write len, read buf, read len
68 * Output: get data in the 3rd buf
69 * Return: fail <0
70 ***********************************************************************/
fts_i2c_read(struct i2c_client * client,char * writebuf,int writelen,char * readbuf,int readlen)71 int fts_i2c_read(struct i2c_client *client, char *writebuf, int writelen, char *readbuf, int readlen)
72 {
73     int ret = 0;
74     int i = 0;
75 
76     mutex_lock(&i2c_rw_access);
77 
78     if (readlen > 0) {
79         if (writelen > 0) {
80             struct i2c_msg msgs[] = {
81                 {
82                     .addr = client->addr,
83                     .flags = 0,
84                     .len = writelen,
85                     .buf = writebuf,
86                 },
87                 {
88                     .addr = client->addr,
89                     .flags = I2C_M_RD,
90                     .len = readlen,
91                     .buf = readbuf,
92                 },
93             };
94             for (i = 0; i < I2C_RETRY_NUMBER; i++) {
95                 ret = i2c_transfer(client->adapter, msgs, 2);
96                 if (ret < 0) {
97                     FTS_ERROR("[IIC]: i2c_transfer(write) error, ret=%d!!", ret);
98                 } else
99                     break;
100             }
101         } else {
102             struct i2c_msg msgs[] = {
103                 {
104                     .addr = client->addr,
105                     .flags = I2C_M_RD,
106                     .len = readlen,
107                     .buf = readbuf,
108                 },
109             };
110             for (i = 0; i < I2C_RETRY_NUMBER; i++) {
111                 ret = i2c_transfer(client->adapter, msgs, 1);
112                 if (ret < 0) {
113                     FTS_ERROR("[IIC]: i2c_transfer(read) error, ret=%d!!", ret);
114                 } else
115                     break;
116             }
117         }
118     }
119 
120     mutex_unlock(&i2c_rw_access);
121     return ret;
122 }
123 
124 /************************************************************************
125 * Name: fts_i2c_write
126 * Brief: i2c write
127 * Input: i2c info, write buf, write len
128 * Output: no
129 * Return: fail <0
130 ***********************************************************************/
fts_i2c_write(struct i2c_client * client,char * writebuf,int writelen)131 int fts_i2c_write(struct i2c_client *client, char *writebuf, int writelen)
132 {
133     int ret = 0;
134     int i = 0;
135 
136     mutex_lock(&i2c_rw_access);
137     if (writelen > 0) {
138         struct i2c_msg msgs[] = {
139             {
140                 .addr = client->addr,
141                 .flags = 0,
142                 .len = writelen,
143                 .buf = writebuf,
144             },
145         };
146         for (i = 0; i < I2C_RETRY_NUMBER; i++) {
147             ret = i2c_transfer(client->adapter, msgs, 1);
148             if (ret < 0) {
149                 FTS_ERROR("%s: i2c_transfer(write) error, ret=%d", __func__, ret);
150             } else
151                 break;
152         }
153     }
154     mutex_unlock(&i2c_rw_access);
155 
156     return ret;
157 }
158 
159 /************************************************************************
160 * Name: fts_i2c_write_reg
161 * Brief: write register
162 * Input: i2c info, reg address, reg value
163 * Output: no
164 * Return: fail <0
165 ***********************************************************************/
fts_i2c_write_reg(struct i2c_client * client,u8 regaddr,u8 regvalue)166 int fts_i2c_write_reg(struct i2c_client *client, u8 regaddr, u8 regvalue)
167 {
168     u8 buf[2] = {0};
169 
170     buf[0] = regaddr;
171     buf[1] = regvalue;
172     return fts_i2c_write(client, buf, sizeof(buf));
173 }
174 
175 /************************************************************************
176 * Name: fts_i2c_read_reg
177 * Brief: read register
178 * Input: i2c info, reg address, reg value
179 * Output: get reg value
180 * Return: fail <0
181 ***********************************************************************/
fts_i2c_read_reg(struct i2c_client * client,u8 regaddr,u8 * regvalue)182 int fts_i2c_read_reg(struct i2c_client *client, u8 regaddr, u8 *regvalue)
183 {
184     return fts_i2c_read(client, &regaddr, 1, regvalue, 1);
185 }
186 
187 /************************************************************************
188 * HID to standard I2C
189 ***********************************************************************/
fts_i2c_hid2std(struct i2c_client * client)190 void fts_i2c_hid2std(struct i2c_client *client)
191 {
192     int ret = 0;
193     u8 buf[3] = {0xeb, 0xaa, 0x09};
194 
195     ret = fts_i2c_write(client, buf, 3);
196     if (ret < 0)
197         FTS_ERROR("hid2std cmd write fail");
198     else {
199         msleep(10);
200         buf[0] = buf[1] = buf[2] = 0;
201         ret = fts_i2c_read(client, NULL, 0, buf, 3);
202         if (ret < 0)
203             FTS_ERROR("hid2std cmd read fail");
204         else if ((0xeb == buf[0]) && (0xaa == buf[1]) && (0x08 == buf[2])) {
205             FTS_DEBUG("hidi2c change to stdi2c successful");
206         } else {
207             FTS_ERROR("hidi2c change to stdi2c fail");
208         }
209     }
210 }
211 
212 /************************************************************************
213 * Name: fts_i2c_init
214 * Brief: fts i2c init
215 * Input:
216 * Output:
217 * Return:
218 ***********************************************************************/
fts_i2c_init(void)219 int fts_i2c_init(void)
220 {
221     FTS_FUNC_ENTER();
222 
223     FTS_FUNC_EXIT();
224     return 0;
225 }
226 /************************************************************************
227 * Name: fts_i2c_exit
228 * Brief: fts i2c exit
229 * Input:
230 * Output:
231 * Return:
232 ***********************************************************************/
fts_i2c_exit(void)233 int fts_i2c_exit(void)
234 {
235     FTS_FUNC_ENTER();
236 
237     FTS_FUNC_EXIT();
238     return 0;
239 }
240 
241