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, ®addr, 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