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