Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / staging / sm750fb / ddk750_swi2c.c
1 /*******************************************************************
2 *
3 *         Copyright (c) 2007 by Silicon Motion, Inc. (SMI)
4 *
5 *  All rights are reserved. Reproduction or in part is prohibited
6 *  without the written consent of the copyright owner.
7 *
8 *  swi2c.c --- SM750/SM718 DDK
9 *  This file contains the source code for I2C using software
10 *  implementation.
11 *
12 *******************************************************************/
13 #include "ddk750_help.h"
14 #include "ddk750_reg.h"
15 #include "ddk750_swi2c.h"
16 #include "ddk750_power.h"
17
18
19 /*******************************************************************
20  * I2C Software Master Driver:
21  * ===========================
22  * Each i2c cycle is split into 4 sections. Each of these section marks
23  * a point in time where the SCL or SDA may be changed.
24  *
25  * 1 Cycle == |  Section I. |  Section 2. |  Section 3. |  Section 4. |
26  *            +-------------+-------------+-------------+-------------+
27  *            | SCL set LOW |SCL no change| SCL set HIGH|SCL no change|
28  *
29  *                                          ____________ _____________
30  * SCL == XXXX _____________ ____________ /
31  *
32  * I.e. the SCL may only be changed in section 1. and section 3. while
33  * the SDA may only be changed in section 2. and section 4. The table
34  * below gives the changes for these 2 lines in the varios sections.
35  *
36  * Section changes Table:
37  * ======================
38  * blank = no change, L = set bit LOW, H = set bit HIGH
39  *
40  *                                | 1.| 2.| 3.| 4.|
41  *                 ---------------+---+---+---+---+
42  *                 Tx Start   SDA |   | H |   | L |
43  *                            SCL | L |   | H |   |
44  *                 ---------------+---+---+---+---+
45  *                 Tx Stop    SDA |   | L |   | H |
46  *                            SCL | L |   | H |   |
47  *                 ---------------+---+---+---+---+
48  *                 Tx bit H   SDA |   | H |   |   |
49  *                            SCL | L |   | H |   |
50  *                 ---------------+---+---+---+---+
51  *                 Tx bit L   SDA |   | L |   |   |
52  *                            SCL | L |   | H |   |
53  *                 ---------------+---+---+---+---+
54  *
55  ******************************************************************/
56
57 /* GPIO pins used for this I2C. It ranges from 0 to 63. */
58 static unsigned char g_i2cClockGPIO = DEFAULT_I2C_SCL;
59 static unsigned char g_i2cDataGPIO = DEFAULT_I2C_SDA;
60
61 /*
62  *  Below is the variable declaration for the GPIO pin register usage
63  *  for the i2c Clock and i2c Data.
64  *
65  *  Note:
66  *      Notice that the GPIO usage for the i2c clock and i2c Data are
67  *      separated. This is to make this code flexible enough when
68  *      two separate GPIO pins for the clock and data are located
69  *      in two different GPIO register set (worst case).
70  */
71
72 /* i2c Clock GPIO Register usage */
73 static unsigned long g_i2cClkGPIOMuxReg = GPIO_MUX;
74 static unsigned long g_i2cClkGPIODataReg = GPIO_DATA;
75 static unsigned long g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION;
76
77 /* i2c Data GPIO Register usage */
78 static unsigned long g_i2cDataGPIOMuxReg = GPIO_MUX;
79 static unsigned long g_i2cDataGPIODataReg = GPIO_DATA;
80 static unsigned long g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION;
81
82 /*
83  *  This function puts a delay between command
84  */
85 static void swI2CWait(void)
86 {
87         /* find a bug:
88          * peekIO method works well before suspend/resume
89          * but after suspend, peekIO(0x3ce,0x61) & 0x10
90          * always be non-zero,which makes the while loop
91          * never finish.
92          * use non-ultimate for loop below is safe
93          * */
94 #if 0
95     /* Change wait algorithm to use PCI bus clock,
96        it's more reliable than counter loop ..
97        write 0x61 to 0x3ce and read from 0x3cf
98        */
99         while(peekIO(0x3ce,0x61) & 0x10);
100 #else
101     int i, Temp;
102
103     for(i=0; i<600; i++)
104     {
105         Temp = i;
106         Temp += i;
107     }
108 #endif
109 }
110
111 /*
112  *  This function set/reset the SCL GPIO pin
113  *
114  *  Parameters:
115  *      value    - Bit value to set to the SCL or SDA (0 = low, 1 = high)
116  *
117  *  Notes:
118  *      When setting SCL to high, just set the GPIO as input where the pull up
119  *      resistor will pull the signal up. Do not use software to pull up the
120  *      signal because the i2c will fail when other device try to drive the
121  *      signal due to SM50x will drive the signal to always high.
122  */
123 void swI2CSCL(unsigned char value)
124 {
125     unsigned long ulGPIOData;
126     unsigned long ulGPIODirection;
127
128     ulGPIODirection = PEEK32(g_i2cClkGPIODataDirReg);
129     if (value)      /* High */
130     {
131         /* Set direction as input. This will automatically pull the signal up. */
132         ulGPIODirection &= ~(1 << g_i2cClockGPIO);
133         POKE32(g_i2cClkGPIODataDirReg, ulGPIODirection);
134     }
135     else            /* Low */
136     {
137         /* Set the signal down */
138         ulGPIOData = PEEK32(g_i2cClkGPIODataReg);
139         ulGPIOData &= ~(1 << g_i2cClockGPIO);
140         POKE32(g_i2cClkGPIODataReg, ulGPIOData);
141
142         /* Set direction as output */
143         ulGPIODirection |= (1 << g_i2cClockGPIO);
144         POKE32(g_i2cClkGPIODataDirReg, ulGPIODirection);
145     }
146 }
147
148 /*
149  *  This function set/reset the SDA GPIO pin
150  *
151  *  Parameters:
152  *      value    - Bit value to set to the SCL or SDA (0 = low, 1 = high)
153  *
154  *  Notes:
155  *      When setting SCL to high, just set the GPIO as input where the pull up
156  *      resistor will pull the signal up. Do not use software to pull up the
157  *      signal because the i2c will fail when other device try to drive the
158  *      signal due to SM50x will drive the signal to always high.
159  */
160 void swI2CSDA(unsigned char value)
161 {
162     unsigned long ulGPIOData;
163     unsigned long ulGPIODirection;
164
165     ulGPIODirection = PEEK32(g_i2cDataGPIODataDirReg);
166     if (value)      /* High */
167     {
168         /* Set direction as input. This will automatically pull the signal up. */
169         ulGPIODirection &= ~(1 << g_i2cDataGPIO);
170         POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection);
171     }
172     else            /* Low */
173     {
174         /* Set the signal down */
175         ulGPIOData = PEEK32(g_i2cDataGPIODataReg);
176         ulGPIOData &= ~(1 << g_i2cDataGPIO);
177         POKE32(g_i2cDataGPIODataReg, ulGPIOData);
178
179         /* Set direction as output */
180         ulGPIODirection |= (1 << g_i2cDataGPIO);
181         POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection);
182     }
183 }
184
185 /*
186  *  This function read the data from the SDA GPIO pin
187  *
188  *  Return Value:
189  *      The SDA data bit sent by the Slave
190  */
191 static unsigned char swI2CReadSDA(void)
192 {
193     unsigned long ulGPIODirection;
194     unsigned long ulGPIOData;
195
196     /* Make sure that the direction is input (High) */
197     ulGPIODirection = PEEK32(g_i2cDataGPIODataDirReg);
198     if ((ulGPIODirection & (1 << g_i2cDataGPIO)) != (~(1 << g_i2cDataGPIO)))
199     {
200         ulGPIODirection &= ~(1 << g_i2cDataGPIO);
201         POKE32(g_i2cDataGPIODataDirReg, ulGPIODirection);
202     }
203
204     /* Now read the SDA line */
205     ulGPIOData = PEEK32(g_i2cDataGPIODataReg);
206     if (ulGPIOData & (1 << g_i2cDataGPIO))
207         return 1;
208     else
209         return 0;
210 }
211
212 /*
213  *  This function sends ACK signal
214  */
215 static void swI2CAck(void)
216 {
217     return;  /* Single byte read is ok without it. */
218 }
219
220 /*
221  *  This function sends the start command to the slave device
222  */
223 static void swI2CStart(void)
224 {
225     /* Start I2C */
226     swI2CSDA(1);
227     swI2CSCL(1);
228     swI2CSDA(0);
229 }
230
231 /*
232  *  This function sends the stop command to the slave device
233  */
234 static void swI2CStop(void)
235 {
236     /* Stop the I2C */
237     swI2CSCL(1);
238     swI2CSDA(0);
239     swI2CSDA(1);
240 }
241
242 /*
243  *  This function writes one byte to the slave device
244  *
245  *  Parameters:
246  *      data    - Data to be write to the slave device
247  *
248  *  Return Value:
249  *       0   - Success
250  *      -1   - Fail to write byte
251  */
252 static long swI2CWriteByte(unsigned char data)
253 {
254     unsigned char value = data;
255     int i;
256
257     /* Sending the data bit by bit */
258     for (i=0; i<8; i++)
259     {
260         /* Set SCL to low */
261         swI2CSCL(0);
262
263         /* Send data bit */
264         if ((value & 0x80) != 0)
265             swI2CSDA(1);
266         else
267             swI2CSDA(0);
268
269         swI2CWait();
270
271         /* Toggle clk line to one */
272         swI2CSCL(1);
273         swI2CWait();
274
275         /* Shift byte to be sent */
276         value = value << 1;
277     }
278
279     /* Set the SCL Low and SDA High (prepare to get input) */
280     swI2CSCL(0);
281     swI2CSDA(1);
282
283     /* Set the SCL High for ack */
284     swI2CWait();
285     swI2CSCL(1);
286     swI2CWait();
287
288     /* Read SDA, until SDA==0 */
289     for(i=0; i<0xff; i++)
290     {
291         if (!swI2CReadSDA())
292             break;
293
294         swI2CSCL(0);
295         swI2CWait();
296         swI2CSCL(1);
297         swI2CWait();
298     }
299
300     /* Set the SCL Low and SDA High */
301     swI2CSCL(0);
302     swI2CSDA(1);
303
304     if (i<0xff)
305         return 0;
306     else
307         return -1;
308 }
309
310 /*
311  *  This function reads one byte from the slave device
312  *
313  *  Parameters:
314  *      ack    - Flag to indicate either to send the acknowledge
315  *            message to the slave device or not
316  *
317  *  Return Value:
318  *      One byte data read from the Slave device
319  */
320 static unsigned char swI2CReadByte(unsigned char ack)
321 {
322     int i;
323     unsigned char data = 0;
324
325     for(i=7; i>=0; i--)
326     {
327         /* Set the SCL to Low and SDA to High (Input) */
328         swI2CSCL(0);
329         swI2CSDA(1);
330         swI2CWait();
331
332         /* Set the SCL High */
333         swI2CSCL(1);
334         swI2CWait();
335
336         /* Read data bits from SDA */
337         data |= (swI2CReadSDA() << i);
338     }
339
340     if (ack)
341         swI2CAck();
342
343     /* Set the SCL Low and SDA High */
344     swI2CSCL(0);
345     swI2CSDA(1);
346
347     return data;
348 }
349
350 /*
351  * This function initializes GPIO port for SW I2C communication.
352  *
353  * Parameters:
354  *      i2cClkGPIO      - The GPIO pin to be used as i2c SCL
355  *      i2cDataGPIO     - The GPIO pin to be used as i2c SDA
356  *
357  * Return Value:
358  *      -1   - Fail to initialize the i2c
359  *       0   - Success
360  */
361 static long swI2CInit_SM750LE(unsigned char i2cClkGPIO,
362                               unsigned char i2cDataGPIO)
363 {
364     int i;
365
366     /* Initialize the GPIO pin for the i2c Clock Register */
367     g_i2cClkGPIODataReg = GPIO_DATA_SM750LE;
368     g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION_SM750LE;
369
370     /* Initialize the Clock GPIO Offset */
371     g_i2cClockGPIO = i2cClkGPIO;
372
373     /* Initialize the GPIO pin for the i2c Data Register */
374     g_i2cDataGPIODataReg = GPIO_DATA_SM750LE;
375     g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION_SM750LE;
376
377     /* Initialize the Data GPIO Offset */
378     g_i2cDataGPIO = i2cDataGPIO;
379
380     /* Note that SM750LE don't have GPIO MUX and power is always on */
381
382     /* Clear the i2c lines. */
383     for(i=0; i<9; i++)
384         swI2CStop();
385
386     return 0;
387 }
388
389 /*
390  * This function initializes the i2c attributes and bus
391  *
392  * Parameters:
393  *      i2cClkGPIO      - The GPIO pin to be used as i2c SCL
394  *      i2cDataGPIO     - The GPIO pin to be used as i2c SDA
395  *
396  * Return Value:
397  *      -1   - Fail to initialize the i2c
398  *       0   - Success
399  */
400 long swI2CInit(
401     unsigned char i2cClkGPIO,
402     unsigned char i2cDataGPIO
403 )
404 {
405     int i;
406
407     /* Return 0 if the GPIO pins to be used is out of range. The range is only from [0..63] */
408     if ((i2cClkGPIO > 31) || (i2cDataGPIO > 31))
409         return -1;
410
411     if (getChipType() == SM750LE)
412         return swI2CInit_SM750LE(i2cClkGPIO, i2cDataGPIO);
413
414     /* Initialize the GPIO pin for the i2c Clock Register */
415     g_i2cClkGPIOMuxReg = GPIO_MUX;
416     g_i2cClkGPIODataReg = GPIO_DATA;
417     g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION;
418
419     /* Initialize the Clock GPIO Offset */
420     g_i2cClockGPIO = i2cClkGPIO;
421
422     /* Initialize the GPIO pin for the i2c Data Register */
423     g_i2cDataGPIOMuxReg = GPIO_MUX;
424     g_i2cDataGPIODataReg = GPIO_DATA;
425     g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION;
426
427     /* Initialize the Data GPIO Offset */
428     g_i2cDataGPIO = i2cDataGPIO;
429
430     /* Enable the GPIO pins for the i2c Clock and Data (GPIO MUX) */
431     POKE32(g_i2cClkGPIOMuxReg,
432                       PEEK32(g_i2cClkGPIOMuxReg) & ~(1 << g_i2cClockGPIO));
433     POKE32(g_i2cDataGPIOMuxReg,
434                       PEEK32(g_i2cDataGPIOMuxReg) & ~(1 << g_i2cDataGPIO));
435
436     /* Enable GPIO power */
437     enableGPIO(1);
438
439     /* Clear the i2c lines. */
440     for(i=0; i<9; i++)
441         swI2CStop();
442
443     return 0;
444 }
445
446 /*
447  *  This function reads the slave device's register
448  *
449  *  Parameters:
450  *      deviceAddress   - i2c Slave device address which register
451  *                        to be read from
452  *      registerIndex   - Slave device's register to be read
453  *
454  *  Return Value:
455  *      Register value
456  */
457 unsigned char swI2CReadReg(
458     unsigned char deviceAddress,
459     unsigned char registerIndex
460 )
461 {
462     unsigned char data;
463
464     /* Send the Start signal */
465     swI2CStart();
466
467     /* Send the device address */
468     swI2CWriteByte(deviceAddress);
469
470     /* Send the register index */
471     swI2CWriteByte(registerIndex);
472
473     /* Get the bus again and get the data from the device read address */
474     swI2CStart();
475     swI2CWriteByte(deviceAddress + 1);
476     data = swI2CReadByte(1);
477
478     /* Stop swI2C and release the bus */
479     swI2CStop();
480
481     return data;
482 }
483
484 /*
485  *  This function writes a value to the slave device's register
486  *
487  *  Parameters:
488  *      deviceAddress   - i2c Slave device address which register
489  *                        to be written
490  *      registerIndex   - Slave device's register to be written
491  *      data            - Data to be written to the register
492  *
493  *  Result:
494  *          0   - Success
495  *         -1   - Fail
496  */
497 long swI2CWriteReg(
498     unsigned char deviceAddress,
499     unsigned char registerIndex,
500     unsigned char data
501 )
502 {
503     long returnValue = 0;
504
505     /* Send the Start signal */
506     swI2CStart();
507
508     /* Send the device address and read the data. All should return success
509        in order for the writing processed to be successful
510      */
511     if ((swI2CWriteByte(deviceAddress) != 0) ||
512         (swI2CWriteByte(registerIndex) != 0) ||
513         (swI2CWriteByte(data) != 0))
514     {
515         returnValue = -1;
516     }
517
518     /* Stop i2c and release the bus */
519     swI2CStop();
520
521     return returnValue;
522 }