]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/staging/sm750fb/ddk750_swi2c.c
Staging: sm750fb: ddk750_swi2c.c: Insert spaces around operators
[mirror_ubuntu-artful-kernel.git] / drivers / staging / sm750fb / ddk750_swi2c.c
CommitLineData
81dee67e
SM
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. */
58static unsigned char g_i2cClockGPIO = DEFAULT_I2C_SCL;
59static 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 */
73static unsigned long g_i2cClkGPIOMuxReg = GPIO_MUX;
74static unsigned long g_i2cClkGPIODataReg = GPIO_DATA;
75static unsigned long g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION;
76
77/* i2c Data GPIO Register usage */
78static unsigned long g_i2cDataGPIOMuxReg = GPIO_MUX;
79static unsigned long g_i2cDataGPIODataReg = GPIO_DATA;
80static unsigned long g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION;
81
81dee67e
SM
82/*
83 * This function puts a delay between command
84 */
85static 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 */
f31b55ac 99 while(peekIO(0x3ce, 0x61) & 0x10);
81dee67e 100#else
7ef803a9 101 int i, Temp;
81dee67e 102
6d43b0f4 103 for(i = 0; i < 600; i++)
7ef803a9
IA
104 {
105 Temp = i;
106 Temp += i;
107 }
81dee67e
SM
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 */
123void swI2CSCL(unsigned char value)
124{
7ef803a9
IA
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 }
81dee67e
SM
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 */
160void swI2CSDA(unsigned char value)
161{
7ef803a9
IA
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 }
81dee67e
SM
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 */
191static unsigned char swI2CReadSDA(void)
192{
7ef803a9
IA
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;
81dee67e
SM
210}
211
81dee67e
SM
212/*
213 * This function sends ACK signal
214 */
215static void swI2CAck(void)
216{
7ef803a9 217 return; /* Single byte read is ok without it. */
81dee67e
SM
218}
219
220/*
221 * This function sends the start command to the slave device
222 */
6a9df430 223static void swI2CStart(void)
81dee67e 224{
7ef803a9
IA
225 /* Start I2C */
226 swI2CSDA(1);
227 swI2CSCL(1);
228 swI2CSDA(0);
81dee67e
SM
229}
230
231/*
232 * This function sends the stop command to the slave device
233 */
6a9df430 234static void swI2CStop(void)
81dee67e 235{
7ef803a9
IA
236 /* Stop the I2C */
237 swI2CSCL(1);
238 swI2CSDA(0);
239 swI2CSDA(1);
81dee67e
SM
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 */
6a9df430 252static long swI2CWriteByte(unsigned char data)
81dee67e 253{
7ef803a9
IA
254 unsigned char value = data;
255 int i;
256
257 /* Sending the data bit by bit */
6d43b0f4 258 for (i = 0; i < 8; i++)
7ef803a9
IA
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 */
6d43b0f4 289 for(i = 0; i < 0xff; i++)
7ef803a9
IA
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
6d43b0f4 304 if (i < 0xff)
7ef803a9
IA
305 return 0;
306 else
307 return -1;
81dee67e
SM
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 */
6a9df430 320static unsigned char swI2CReadByte(unsigned char ack)
81dee67e 321{
7ef803a9
IA
322 int i;
323 unsigned char data = 0;
81dee67e 324
6d43b0f4 325 for(i = 7; i >= 0; i--)
7ef803a9
IA
326 {
327 /* Set the SCL to Low and SDA to High (Input) */
328 swI2CSCL(0);
329 swI2CSDA(1);
330 swI2CWait();
81dee67e 331
7ef803a9
IA
332 /* Set the SCL High */
333 swI2CSCL(1);
334 swI2CWait();
81dee67e 335
7ef803a9
IA
336 /* Read data bits from SDA */
337 data |= (swI2CReadSDA() << i);
338 }
81dee67e 339
7ef803a9
IA
340 if (ack)
341 swI2CAck();
81dee67e 342
7ef803a9
IA
343 /* Set the SCL Low and SDA High */
344 swI2CSCL(0);
345 swI2CSDA(1);
81dee67e 346
7ef803a9 347 return data;
81dee67e 348}
81dee67e
SM
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 */
6a9df430
RRD
361static long swI2CInit_SM750LE(unsigned char i2cClkGPIO,
362 unsigned char i2cDataGPIO)
81dee67e 363{
7ef803a9 364 int i;
81dee67e 365
7ef803a9
IA
366 /* Initialize the GPIO pin for the i2c Clock Register */
367 g_i2cClkGPIODataReg = GPIO_DATA_SM750LE;
368 g_i2cClkGPIODataDirReg = GPIO_DATA_DIRECTION_SM750LE;
81dee67e 369
7ef803a9
IA
370 /* Initialize the Clock GPIO Offset */
371 g_i2cClockGPIO = i2cClkGPIO;
81dee67e 372
7ef803a9
IA
373 /* Initialize the GPIO pin for the i2c Data Register */
374 g_i2cDataGPIODataReg = GPIO_DATA_SM750LE;
375 g_i2cDataGPIODataDirReg = GPIO_DATA_DIRECTION_SM750LE;
81dee67e 376
7ef803a9
IA
377 /* Initialize the Data GPIO Offset */
378 g_i2cDataGPIO = i2cDataGPIO;
81dee67e 379
7ef803a9 380 /* Note that SM750LE don't have GPIO MUX and power is always on */
81dee67e 381
7ef803a9 382 /* Clear the i2c lines. */
6d43b0f4 383 for(i = 0; i < 9; i++)
7ef803a9 384 swI2CStop();
81dee67e 385
7ef803a9 386 return 0;
81dee67e
SM
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 */
400long swI2CInit(
7ef803a9
IA
401 unsigned char i2cClkGPIO,
402 unsigned char i2cDataGPIO
81dee67e
SM
403)
404{
7ef803a9 405 int i;
81dee67e 406
7ef803a9
IA
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;
81dee67e 410
7ef803a9
IA
411 if (getChipType() == SM750LE)
412 return swI2CInit_SM750LE(i2cClkGPIO, i2cDataGPIO);
81dee67e 413
7ef803a9
IA
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;
81dee67e 418
7ef803a9
IA
419 /* Initialize the Clock GPIO Offset */
420 g_i2cClockGPIO = i2cClkGPIO;
81dee67e 421
7ef803a9
IA
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;
81dee67e 426
7ef803a9
IA
427 /* Initialize the Data GPIO Offset */
428 g_i2cDataGPIO = i2cDataGPIO;
81dee67e 429
7ef803a9
IA
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));
81dee67e 435
7ef803a9
IA
436 /* Enable GPIO power */
437 enableGPIO(1);
81dee67e 438
7ef803a9 439 /* Clear the i2c lines. */
6d43b0f4 440 for(i = 0; i < 9; i++)
7ef803a9 441 swI2CStop();
81dee67e 442
7ef803a9 443 return 0;
81dee67e
SM
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 */
457unsigned char swI2CReadReg(
7ef803a9
IA
458 unsigned char deviceAddress,
459 unsigned char registerIndex
81dee67e
SM
460)
461{
7ef803a9 462 unsigned char data;
81dee67e 463
7ef803a9
IA
464 /* Send the Start signal */
465 swI2CStart();
81dee67e 466
7ef803a9
IA
467 /* Send the device address */
468 swI2CWriteByte(deviceAddress);
81dee67e 469
7ef803a9
IA
470 /* Send the register index */
471 swI2CWriteByte(registerIndex);
81dee67e 472
7ef803a9
IA
473 /* Get the bus again and get the data from the device read address */
474 swI2CStart();
475 swI2CWriteByte(deviceAddress + 1);
476 data = swI2CReadByte(1);
81dee67e 477
7ef803a9
IA
478 /* Stop swI2C and release the bus */
479 swI2CStop();
81dee67e 480
7ef803a9 481 return data;
81dee67e
SM
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 */
497long swI2CWriteReg(
7ef803a9
IA
498 unsigned char deviceAddress,
499 unsigned char registerIndex,
500 unsigned char data
81dee67e
SM
501)
502{
7ef803a9 503 long returnValue = 0;
81dee67e 504
7ef803a9
IA
505 /* Send the Start signal */
506 swI2CStart();
81dee67e 507
7ef803a9
IA
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 }
81dee67e 517
7ef803a9
IA
518 /* Stop i2c and release the bus */
519 swI2CStop();
81dee67e 520
7ef803a9 521 return returnValue;
81dee67e 522}