tizen 2.4 release
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / input / touchscreen / ist30xxc / ist30xxc_sys.c
1 /*
2  *  Copyright (C) 2010,Imagis Technology Co. Ltd. All Rights Reserved.
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  */
15
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/slab.h>
19 #include <linux/i2c.h>
20 #include <linux/delay.h>
21 #include <asm/unaligned.h>
22
23 #include <asm/io.h>
24 #include <linux/regulator/consumer.h>
25 #include <linux/regulator/machine.h>
26
27 #include "ist30xxc.h"
28 #include "ist30xxc_tracking.h"
29
30 extern char *ist_vdd_name;
31 /******************************************************************************
32  * Return value of Error
33  * EPERM  : 1 (Operation not permitted)
34  * ENOENT : 2 (No such file or directory)
35  * EIO    : 5 (I/O error)
36  * ENXIO  : 6 (No such device or address)
37  * EINVAL : 22 (Invalid argument)
38  *****************************************************************************/
39
40 int ist30xx_cmd_gesture(struct i2c_client *client, int value)
41 {
42         int ret = -EIO;
43
44         if (value > 3)
45                 return ret;
46
47         ret = ist30xx_write_cmd(client,
48                         IST30XX_HIB_CMD, (eHCOM_GESTURE_EN << 16) | (value & 0xFFFF));
49
50         return ret;
51 }
52
53 int ist30xx_cmd_start_scan(struct ist30xx_data *data)
54 {
55         int ret = ist30xx_write_cmd(data->client, IST30XX_HIB_CMD,
56                         (eHCOM_FW_START << 16) | (IST30XX_ENABLE & 0xFFFF));
57
58         ist30xx_tracking(TRACK_CMD_SCAN);
59
60         data->status.noise_mode = true;
61
62         return ret;
63 }
64
65 int ist30xx_cmd_calibrate(struct i2c_client *client)
66 {
67         int ret = ist30xx_write_cmd(client,
68                         IST30XX_HIB_CMD, (eHCOM_RUN_CAL_AUTO << 16));
69
70         ist30xx_tracking(TRACK_CMD_CALIB);
71
72         tsp_info("%s\n", __func__);
73
74         return ret;
75 }
76
77 int ist30xx_cmd_check_calib(struct i2c_client *client)
78 {
79         int ret = ist30xx_write_cmd(client, IST30XX_HIB_CMD,
80                         (eHCOM_RUN_CAL_PARAM << 16) | (IST30XX_ENABLE & 0xFFFF));
81
82         ist30xx_tracking(TRACK_CMD_CHECK_CALIB);
83
84         tsp_info("*** Check Calibration cmd ***\n");
85
86         return ret;
87 }
88
89 int ist30xx_cmd_hold(struct i2c_client *client, int enable)
90 {
91         int ret = ist30xx_write_cmd(client,
92                         IST30XX_HIB_CMD, (eHCOM_FW_HOLD << 16) | (enable & 0xFFFF));
93
94         msleep(40);
95
96         if (enable)
97                 ist30xx_tracking(TRACK_CMD_ENTER_REG);
98         else
99                 ist30xx_tracking(TRACK_CMD_EXIT_REG);
100
101         return ret;
102 }
103
104 int ist30xx_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
105                          int msg_num, u8 *cmd_buf)
106 {
107         int ret = 0;
108         int idx = msg_num - 1;
109         int size = msgs[idx].len;
110         u8 *msg_buf = NULL;
111         u8 *pbuf = NULL;
112         int trans_size, max_size = 0;
113
114         if (msg_num == WRITE_CMD_MSG_LEN)
115                 max_size = I2C_MAX_WRITE_SIZE;
116         else if (msg_num == READ_CMD_MSG_LEN)
117                 max_size = I2C_MAX_READ_SIZE;
118
119         if (unlikely(max_size == 0)) {
120                 tsp_err("%s() : transaction size(%d)\n", __func__, max_size);
121                 return -EINVAL;
122         }
123
124         if (msg_num == WRITE_CMD_MSG_LEN) {
125                 msg_buf = kmalloc(max_size + IST30XX_ADDR_LEN, GFP_KERNEL);
126                 if (!msg_buf)
127                         return -ENOMEM;
128                 memcpy(msg_buf, cmd_buf, IST30XX_ADDR_LEN);
129                 pbuf = msgs[idx].buf;
130         }
131
132         while (size > 0) {
133                 trans_size = (size >= max_size ? max_size : size);
134
135                 msgs[idx].len = trans_size;
136                 if (msg_num == WRITE_CMD_MSG_LEN) {
137                         memcpy(&msg_buf[IST30XX_ADDR_LEN], pbuf, trans_size);
138                         msgs[idx].buf = msg_buf;
139                         msgs[idx].len += IST30XX_ADDR_LEN;
140                 }
141                 ret = i2c_transfer(adap, msgs, msg_num);
142                 if (unlikely(ret != msg_num)) {
143                         tsp_err("%s() : i2c_transfer failed(%d), num=%d\n",
144                                 __func__, ret, msg_num);
145                         break;
146                 }
147
148                 if (msg_num == WRITE_CMD_MSG_LEN)
149                         pbuf += trans_size;
150                 else
151                         msgs[idx].buf += trans_size;
152
153                 size -= trans_size;
154         }
155
156         if (msg_num == WRITE_CMD_MSG_LEN)
157                 kfree(msg_buf);
158
159         return ret;
160 }
161
162 int ist30xx_read_buf(struct i2c_client *client, u32 cmd, u32 *buf, u16 len)
163 {
164         int ret, i;
165         u32 le_reg = cpu_to_be32(cmd);
166
167         struct i2c_msg msg[READ_CMD_MSG_LEN] = {
168                 {
169                         .addr = client->addr,
170                         .flags = 0,
171                         .len = IST30XX_ADDR_LEN,
172                         .buf = (u8 *)&le_reg,
173                 },
174                 {
175                         .addr = client->addr,
176                         .flags = I2C_M_RD,
177                         .len = len * IST30XX_DATA_LEN,
178                         .buf = (u8 *)buf,
179                 },
180         };
181
182         ret = ist30xx_i2c_transfer(client->adapter, msg, READ_CMD_MSG_LEN, NULL);
183         if (unlikely(ret != READ_CMD_MSG_LEN))
184                 return -EIO;
185
186         for (i = 0; i < len; i++)
187                 buf[i] = cpu_to_be32(buf[i]);
188
189         return 0;
190 }
191
192 int ist30xx_write_buf(struct i2c_client *client, u32 cmd, u32 *buf, u16 len)
193 {
194         int i;
195         int ret;
196         struct i2c_msg msg;
197         u8 cmd_buf[IST30XX_ADDR_LEN];
198         u8 msg_buf[IST30XX_DATA_LEN * (len + 1)];
199
200         put_unaligned_be32(cmd, cmd_buf);
201
202         if (likely(len > 0)) {
203                 for (i = 0; i < len; i++)
204                         put_unaligned_be32(buf[i], msg_buf + (i * IST30XX_DATA_LEN));
205         } else {
206                 /* then add dummy data(4byte) */
207                 put_unaligned_be32(0, msg_buf);
208                 len = 1;
209         }
210
211         msg.addr = client->addr;
212         msg.flags = 0;
213         msg.len = len * IST30XX_DATA_LEN;
214         msg.buf = msg_buf;
215
216         ret = ist30xx_i2c_transfer(client->adapter, &msg, WRITE_CMD_MSG_LEN,
217                                    cmd_buf);
218         if (unlikely(ret != WRITE_CMD_MSG_LEN))
219                 return -EIO;
220
221         return 0;
222 }
223
224 int ist30xx_read_reg(struct i2c_client *client, u32 reg, u32 *buf)
225 {
226         int ret;
227         u32 le_reg = cpu_to_be32(reg);
228
229         struct i2c_msg msg[READ_CMD_MSG_LEN] = {
230                 {
231                         .addr = client->addr,
232                         .flags = 0,
233                         .len = IST30XX_ADDR_LEN,
234                         .buf = (u8 *)&le_reg,
235                 },
236                 {
237                         .addr = client->addr,
238                         .flags = I2C_M_RD,
239                         .len = IST30XX_DATA_LEN,
240                         .buf = (u8 *)buf,
241                 },
242         };
243
244         ret = i2c_transfer(client->adapter, msg, READ_CMD_MSG_LEN);
245         if (ret != READ_CMD_MSG_LEN) {
246                 tsp_err("%s: i2c failed (%d), cmd: %x\n", __func__, ret, reg);
247                 return -EIO;
248         }
249         *buf = cpu_to_be32(*buf);
250
251         return 0;
252 }
253
254 int ist30xx_read_cmd(struct ist30xx_data *data, u32 cmd, u32 *buf)
255 {
256         int ret;
257
258         ret = ist30xx_cmd_hold(data->client, 1);
259         if (unlikely(ret))
260                 return ret;
261
262         ist30xx_read_reg(data->client, IST30XX_DA_ADDR(cmd), buf);
263
264         ret = ist30xx_cmd_hold(data->client, 0);
265         if (unlikely(ret)) {
266                 ist30xx_reset(data, false);
267                 return ret;
268         }
269
270         return ret;
271 }
272
273 int ist30xx_write_cmd(struct i2c_client *client, u32 cmd, u32 val)
274 {
275         int ret;
276
277         struct i2c_msg msg;
278         u8 msg_buf[IST30XX_ADDR_LEN + IST30XX_DATA_LEN];
279
280         put_unaligned_be32(cmd, msg_buf);
281         put_unaligned_be32(val, msg_buf + IST30XX_ADDR_LEN);
282
283         msg.addr = client->addr;
284         msg.flags = 0;
285         msg.len = IST30XX_ADDR_LEN + IST30XX_DATA_LEN;
286         msg.buf = msg_buf;
287
288         ret = i2c_transfer(client->adapter, &msg, WRITE_CMD_MSG_LEN);
289         if (ret != WRITE_CMD_MSG_LEN) {
290                 tsp_err("%s: i2c failed (%d), cmd: %x(%x)\n", __func__, ret, cmd, val);
291                 return -EIO;
292         }
293
294         msleep(40);
295
296         return 0;
297 }
298
299 int ist30xx_burst_read(struct i2c_client *client, u32 addr,
300                         u32 *buf32, u16 len, bool bit_en)
301 {
302         int ret = 0;
303         int i;
304         u16 max_len = I2C_MAX_READ_SIZE / IST30XX_DATA_LEN;
305         u16 remain_len = len;
306
307         if (bit_en)
308                 addr = IST30XX_BA_ADDR(addr);
309
310         for (i = 0; i < len; i += max_len) {
311                 if (remain_len < max_len) max_len = remain_len;
312
313                 ret = ist30xx_read_buf(client, addr, buf32, max_len);
314                 if (unlikely(ret)) {
315                         tsp_err("Burst fail, addr: %x\n", __func__, addr);
316                         return ret;
317                 }
318
319                 addr += max_len * IST30XX_DATA_LEN;
320                 buf32 += max_len;
321                 remain_len -= max_len;
322         }
323
324         return 0;
325 }
326
327 int ist30xx_burst_write(struct i2c_client *client, u32 addr,
328             u32 *buf32, u16 len)
329 {
330         int ret = 0;
331         int i;
332         u16 max_len = I2C_MAX_WRITE_SIZE / IST30XX_DATA_LEN;
333         u16 remain_len = len;
334
335         addr = IST30XX_BA_ADDR(addr);
336
337         for (i = 0; i < len; i += max_len) {
338                 if (remain_len < max_len) max_len = remain_len;
339
340                 ret = ist30xx_write_buf(client, addr, buf32, max_len);
341                 if (unlikely(ret)) {
342                         tsp_err("Burst fail, addr: %x\n", __func__, addr);
343                         return ret;
344                 }
345
346                 addr += max_len * IST30XX_DATA_LEN;
347                 buf32 += max_len;
348                 remain_len -= max_len;
349         }
350
351         return 0;
352 }
353
354 static struct regulator *touch_regulator;
355 static void ts_power_enable(struct ist30xx_data *data, int en)
356 {
357         struct i2c_client *client = data->client;
358         int ret;
359
360         tsp_info("%s %s\n", __func__, (en) ? "on" : "off");
361
362         if (touch_regulator == NULL) {
363                 touch_regulator = regulator_get(&client->dev, ist_vdd_name);
364                 if (IS_ERR(touch_regulator)) {
365                         ret = PTR_ERR(touch_regulator);
366                         dev_err(&client->dev,
367                                 "Failed to get vdd regulator(%d)\n", ret);
368                         return ret;
369                 }
370
371                 ret = regulator_set_voltage(touch_regulator, 3000000, 3000000);
372                 if (ret < 0) {
373                         dev_err(&client->dev,
374                                 "Failed to set vdd regulator(%d)\n", ret);
375                         regulator_put(touch_regulator);
376                         touch_regulator = NULL;
377                         return ret;
378                 }
379         }
380
381         if (en){
382                 if(data->status.power)
383                         printk("%s:already enabled\n",__func__);
384                 else
385                         regulator_enable(touch_regulator);
386         }
387         else{
388                 if(data->status.power)
389                         regulator_disable(touch_regulator);
390                 else
391                         printk("%s:already disabled\n",__func__);
392         }
393 }
394
395 int ist30xx_power_on(struct ist30xx_data *data, bool download)
396 {
397         if (data->status.power != 1) {
398                 tsp_info("%s()\n", __func__);
399                 ist30xx_tracking(TRACK_PWR_ON);
400                 /* VDD enable */
401                 ts_power_enable(data, 1);
402                 if (download)
403                         msleep(8);
404                 else
405                         msleep(50);
406
407                 data->status.power = 1;
408         }
409
410         return 0;
411 }
412
413 int ist30xx_power_off(struct ist30xx_data *data)
414 {
415         if (data->status.power != 0) {
416                 tsp_info("%s()\n", __func__);
417                 ist30xx_tracking(TRACK_PWR_OFF);
418                 /* VDD disable */
419                 ts_power_enable(data, 0);
420                 msleep(50);
421                 data->status.power = 0;
422                 data->status.noise_mode = false;
423         }
424
425         return 0;
426 }
427
428 int ist30xx_reset(struct ist30xx_data *data, bool download)
429 {
430         tsp_info("%s()\n", __func__);
431         ist30xx_power_off(data);
432         msleep(10);
433         ist30xx_power_on(data, download);
434
435         return 0;
436 }
437
438 int ist30xx_internal_suspend(struct ist30xx_data *data)
439 {
440 #if IST30XX_GESTURE
441         data->suspend = true;
442         if (data->gesture) {
443                 ist30xx_reset(data, false);
444                 ist30xx_cmd_gesture(data->client, 3);
445         } else {
446                 ist30xx_power_off(data);
447         }
448 #else
449         ist30xx_power_off(data);
450 #endif
451         return 0;
452 }
453
454 int ist30xx_internal_resume(struct ist30xx_data *data)
455 {
456 #if IST30XX_GESTURE
457         data->suspend = false;
458         if (data->gesture)
459                 ist30xx_reset(data, false);
460         else
461                 ist30xx_power_on(data, false);
462 #else
463         ist30xx_power_on(data, false);
464 #endif
465
466         return 0;
467 }
468
469 int ist30xx_init_system(struct ist30xx_data *data)
470 {
471         int ret;
472
473         // TODO : place additional code here.
474         ret = ist30xx_power_on(data, false);
475         if (ret) {
476                 tsp_err("%s: ist30xx_init_system failed (%d)\n", __func__, ret);
477                 return -EIO;
478         }
479
480         return 0;
481 }