upload tizen1.0 source
[kernel/linux-2.6.36.git] / drivers / input / touchscreen / s5pc210_ts_gpio_i2c.c
1 /*
2  * i2c driver
3  *
4  */
5
6 #include <linux/module.h>
7 #include <linux/kernel.h>
8 #include <linux/init.h>
9 #include <linux/irq.h>
10 #include <linux/interrupt.h>
11 #include <linux/platform_device.h>
12 #include <linux/device.h>
13 #include <linux/input.h>
14 #include <linux/fs.h>
15
16 #include <mach/irqs.h>
17 #include <asm/system.h>
18
19 #include <linux/delay.h>
20 #include <mach/regs-gpio.h>
21
22 #include "s5pc210_ts_gpio_i2c.h"
23 #include "s5pc210_ts.h"
24
25 #define GPD1CON (S5P_VA_GPIO + 0xC0)
26 #define GPD1DAT (S5P_VA_GPIO + 0xC4)
27
28
29 /* Touch I2C Address Define */
30 #define TOUCH_WR_ADDR 0xB8
31 #define TOUCH_RD_ADDR 0xB9
32
33 /* Touch I2C Port define */
34 #define GPIO_I2C_SDA_CON_PORT (*(unsigned long *)GPD1CON)
35 #define GPIO_I2C_SDA_DAT_PORT (*(unsigned long *)GPD1DAT)
36 #define GPIO_SDA_PIN 0
37
38 #define GPIO_I2C_CLK_CON_PORT (*(unsigned long *)GPD1CON)
39 #define GPIO_I2C_CLK_DAT_PORT (*(unsigned long *)GPD1DAT)
40 #define GPIO_CLK_PIN 1
41
42 #define DELAY_TIME 5    // us value
43 #define PORT_CHANGE_DELAY_TIME 5
44 #define GPIO_CON_PORT_MASK 0xF
45 #define GPIO_CON_PORT_OFFSET 0x4
46
47 #define GPIO_CON_INPUT 0x0
48 #define GPIO_CON_OUTPUT 0x1
49
50 #define HIGH 1
51 #define LOW 0
52
53 /*  debug enable flag */
54 //#define       DEBUG_GPIO_I2C
55 /*
56  * static function prototype
57  */
58 static  void                    gpio_i2c_sda_port_control       (unsigned char inout);
59 static  void                    gpio_i2c_clk_port_control       (unsigned char inout);
60
61 static  unsigned char   gpio_i2c_get_sda                        (void);
62 static  void                    gpio_i2c_set_sda                        (unsigned char hi_lo);
63 static  void                    gpio_i2c_set_clk                        (unsigned char hi_lo);
64
65 static  void                    gpio_i2c_start                          (void);
66 static  void                    gpio_i2c_stop                           (void);
67
68 static  void                    gpio_i2c_send_ack                       (void);
69 static  void                    gpio_i2c_send_noack                     (void);
70 static  unsigned char   gpio_i2c_chk_ack                        (void);
71
72 static  void                    gpio_i2c_byte_write                     (unsigned char wdata);
73 static  void                    gpio_i2c_byte_read                      (unsigned char *rdata);
74
75 /* extern function prototype */
76 int s5pv310_ts_write(unsigned char addr, unsigned char *wdata, unsigned char wsize);
77 int s5pv310_ts_read(unsigned char *rdata, unsigned char rsize);
78 void s5pv310_ts_port_init(void);
79
80 static void gpio_i2c_sda_port_control(unsigned char inout)
81 {
82         GPIO_I2C_SDA_CON_PORT &=  (unsigned long)(~(GPIO_CON_PORT_MASK << (GPIO_SDA_PIN * GPIO_CON_PORT_OFFSET)));
83         GPIO_I2C_SDA_CON_PORT |=  (unsigned long)( (inout << (GPIO_SDA_PIN * GPIO_CON_PORT_OFFSET)));
84 }
85
86 static void gpio_i2c_clk_port_control(unsigned char inout)
87 {
88         GPIO_I2C_CLK_CON_PORT &=  (unsigned long)(~(GPIO_CON_PORT_MASK << (GPIO_CLK_PIN * GPIO_CON_PORT_OFFSET)));
89         GPIO_I2C_CLK_CON_PORT |=  (unsigned long)( (inout << (GPIO_CLK_PIN * GPIO_CON_PORT_OFFSET)));
90 }
91
92 static unsigned char gpio_i2c_get_sda(void)
93 {
94         return  GPIO_I2C_SDA_DAT_PORT & (HIGH << GPIO_SDA_PIN) ? 1 : 0;
95 }
96
97 static void gpio_i2c_set_sda(unsigned char hi_lo)
98 {
99         if(hi_lo)       {
100                 gpio_i2c_sda_port_control(GPIO_CON_INPUT);
101                 udelay(PORT_CHANGE_DELAY_TIME);
102         }
103         else            {
104                 GPIO_I2C_SDA_DAT_PORT &= ~(HIGH << GPIO_SDA_PIN);
105                 gpio_i2c_sda_port_control(GPIO_CON_OUTPUT);
106                 udelay(PORT_CHANGE_DELAY_TIME);
107         }
108 }
109
110 static void gpio_i2c_set_clk (unsigned char hi_lo)
111 {
112         if(hi_lo)
113         {
114                 gpio_i2c_clk_port_control(GPIO_CON_INPUT);
115                 udelay(PORT_CHANGE_DELAY_TIME);
116         }
117         else
118         {
119                 GPIO_I2C_CLK_DAT_PORT &= ~(HIGH << GPIO_CLK_PIN);
120                 gpio_i2c_clk_port_control(GPIO_CON_OUTPUT);
121                 udelay(PORT_CHANGE_DELAY_TIME);
122         }
123 }
124
125 static void gpio_i2c_start(void)
126 {
127         // Setup SDA, CLK output High
128         gpio_i2c_set_sda(HIGH);
129         gpio_i2c_set_clk(HIGH);
130
131         udelay(DELAY_TIME);
132
133         // SDA low before CLK low
134         gpio_i2c_set_sda(LOW);  udelay(DELAY_TIME);
135         gpio_i2c_set_clk(LOW);  udelay(DELAY_TIME);
136 }
137
138 static void gpio_i2c_stop(void)
139 {
140         // Setup SDA, CLK output low
141         gpio_i2c_set_sda(LOW);
142         gpio_i2c_set_clk(LOW);
143
144         udelay(DELAY_TIME);
145
146         // SDA high after CLK high
147         gpio_i2c_set_clk(HIGH); udelay(DELAY_TIME);
148         gpio_i2c_set_sda(HIGH); udelay(DELAY_TIME);
149 }
150
151 static void gpio_i2c_send_ack(void)
152 {
153         // SDA Low
154         gpio_i2c_set_sda(LOW);
155         udelay(DELAY_TIME);
156         gpio_i2c_set_clk(HIGH);
157         udelay(DELAY_TIME);
158         gpio_i2c_set_clk(LOW);
159         udelay(DELAY_TIME);
160 }
161
162 static void gpio_i2c_send_noack(void)
163 {
164         // SDA High
165         gpio_i2c_set_sda(HIGH);
166         udelay(DELAY_TIME);
167         gpio_i2c_set_clk(HIGH);
168         udelay(DELAY_TIME);
169         gpio_i2c_set_clk(LOW);
170         udelay(DELAY_TIME);
171 }
172
173 static unsigned char gpio_i2c_chk_ack (void)
174 {
175         unsigned char   count = 0, ret = 0;
176
177         gpio_i2c_set_sda(LOW);
178         udelay(DELAY_TIME);
179         gpio_i2c_set_clk(HIGH);
180         udelay(DELAY_TIME);
181
182         gpio_i2c_sda_port_control(GPIO_CON_INPUT);
183         udelay(PORT_CHANGE_DELAY_TIME);
184
185         while(gpio_i2c_get_sda())
186         {
187                 if(count++ > 100)
188                 {
189                         ret = 1;
190                         break;
191                 }
192                 else
193                         udelay(DELAY_TIME);
194         }
195
196         gpio_i2c_set_clk(LOW);          udelay(DELAY_TIME);
197
198 #if defined(DEBUG_GPIO_I2C)
199         if(ret)
200                 printk("%s %d: no ack!!\n",__func__, ret);
201         else
202                 printk("%s %d: ack !! \n" ,__func__, ret);
203 #endif
204
205         return  ret;
206 }
207
208 static  void            gpio_i2c_byte_write             (unsigned char wdata)
209 {
210         unsigned char   cnt, mask;
211
212         for(cnt = 0, mask = 0x80; cnt < 8; cnt++, mask >>= 1)   {
213                 if(wdata & mask)                gpio_i2c_set_sda(HIGH);
214                 else                                    gpio_i2c_set_sda(LOW);
215
216                 gpio_i2c_set_clk(HIGH);         udelay(DELAY_TIME);
217                 gpio_i2c_set_clk(LOW);          udelay(DELAY_TIME);
218         }
219 }
220
221 static  void            gpio_i2c_byte_read              (unsigned char *rdata)
222 {
223         unsigned char   cnt, mask;
224
225         gpio_i2c_sda_port_control(GPIO_CON_INPUT);
226         udelay(PORT_CHANGE_DELAY_TIME);
227
228         for(cnt = 0, mask = 0x80, *rdata = 0; cnt < 8; cnt++, mask >>= 1)       {
229                 gpio_i2c_set_clk(HIGH);         udelay(DELAY_TIME);
230
231                 if(gpio_i2c_get_sda())          *rdata |= mask;
232
233                 gpio_i2c_set_clk(LOW);          udelay(DELAY_TIME);
234
235         }
236 }
237
238 int s5pv310_ts_write (unsigned char addr, unsigned char *wdata, unsigned char wsize)
239 {
240         unsigned char cnt, ack;
241
242         /* start */
243         gpio_i2c_start();
244
245         gpio_i2c_byte_write(TOUCH_WR_ADDR);     // i2c address
246
247         if((ack = gpio_i2c_chk_ack()))  {
248 #if defined(DEBUG_GPIO_I2C)
249                 printk("%s [write address] : no ack\n",__FUNCTION__);
250 #endif
251
252                 goto    write_stop;
253         }
254
255         gpio_i2c_byte_write(addr);      // register
256
257         if((ack = gpio_i2c_chk_ack()))  {
258 #if defined(DEBUG_GPIO_I2C)
259                 printk("%s [write register] : no ack\n",__FUNCTION__);
260 #endif
261         }
262
263         if(wsize)       {
264
265                 for(cnt = 0; cnt < wsize; cnt++) {
266
267                         gpio_i2c_byte_write(wdata[cnt]);
268
269                         if((ack = gpio_i2c_chk_ack()))  {
270 #if defined(DEBUG_GPIO_I2C)
271                                 printk("%s [write register] : no ack\n",__FUNCTION__);
272 #endif
273
274                                 goto    write_stop;
275                         }
276                 }
277         }
278
279 write_stop:
280
281 #if defined(CONFIG_TOUCHSCREEN_S5PV310_MT)
282         if(wsize)       gpio_i2c_stop();
283 #else
284         gpio_i2c_stop();
285 #endif
286
287 #if defined(DEBUG_GPIO_I2C)
288         printk("%s : %d\n", __FUNCTION__, ack);
289 #endif
290         return  ack;
291 }
292
293 int s5pv310_ts_read(unsigned char *rdata, unsigned char rsize)
294 {
295         unsigned char ack, cnt;
296
297         // start
298         gpio_i2c_start();
299
300         gpio_i2c_byte_write(TOUCH_RD_ADDR);     // i2c address
301
302         if((ack = gpio_i2c_chk_ack()))  {
303 #if defined(DEBUG_GPIO_I2C)
304                 printk("%s [write address] : no ack\n",__FUNCTION__);
305 #endif
306
307                 goto    read_stop;
308         }
309
310         for(cnt=0; cnt < rsize; cnt++)  {
311
312                 gpio_i2c_byte_read(&rdata[cnt]);
313
314                 if(cnt == rsize -1)
315                         gpio_i2c_send_noack();
316                 else
317                         gpio_i2c_send_ack();
318         }
319
320 read_stop:
321         gpio_i2c_stop();
322
323
324 #if defined(DEBUG_GPIO_I2C)
325         printk("%s : %d\n", __FUNCTION__, ack);
326 #endif
327         return  ack;
328 }
329
330 void s5pv310_ts_port_init (void)
331 {
332         gpio_i2c_set_sda(HIGH);
333         gpio_i2c_set_clk(HIGH);
334 }