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