Commit | Line | Data |
---|---|---|
25338628 | 1 | // SPDX-License-Identifier: GPL-2.0 |
f5016082 ES |
2 | /* |
3 | * Copyright (c) 2007 by Silicon Motion, Inc. (SMI) | |
4 | * | |
f5016082 ES |
5 | * swi2c.c --- SM750/SM718 DDK |
6 | * This file contains the source code for I2C using software | |
7 | * implementation. | |
8 | */ | |
9 | ||
efe9bc08 | 10 | #include "ddk750_chip.h" |
81dee67e SM |
11 | #include "ddk750_reg.h" |
12 | #include "ddk750_swi2c.h" | |
13 | #include "ddk750_power.h" | |
14 | ||
f5016082 | 15 | /* |
81dee67e SM |
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 | * | |
f5016082 | 51 | */ |
81dee67e SM |
52 | |
53 | /* GPIO pins used for this I2C. It ranges from 0 to 63. */ | |
53bc6b6e MR |
54 | static unsigned char sw_i2c_clk_gpio = DEFAULT_I2C_SCL; |
55 | static unsigned char sw_i2c_data_gpio = DEFAULT_I2C_SDA; | |
81dee67e SM |
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 */ | |
53bc6b6e MR |
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; | |
81dee67e SM |
72 | |
73 | /* i2c Data GPIO Register usage */ | |
53bc6b6e MR |
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; | |
81dee67e | 77 | |
81dee67e SM |
78 | /* |
79 | * This function puts a delay between command | |
80 | */ | |
6c78f4ce | 81 | static void sw_i2c_wait(void) |
81dee67e SM |
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 | |
35e4d8ca | 89 | */ |
1282bade | 90 | |
81dee67e | 91 | /* Change wait algorithm to use PCI bus clock, |
35e4d8ca EF |
92 | * it's more reliable than counter loop .. |
93 | * write 0x61 to 0x3ce and read from 0x3cf | |
94 | */ | |
fe820044 | 95 | int i, tmp; |
81dee67e | 96 | |
6bdee8bd | 97 | for (i = 0; i < 600; i++) { |
fe820044 MR |
98 | tmp = i; |
99 | tmp += i; | |
7ef803a9 | 100 | } |
81dee67e SM |
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 | */ | |
6c78f4ce | 115 | static void sw_i2c_scl(unsigned char value) |
81dee67e | 116 | { |
fe820044 MR |
117 | unsigned long gpio_data; |
118 | unsigned long gpio_dir; | |
7ef803a9 | 119 | |
c075b6f2 | 120 | gpio_dir = peek32(sw_i2c_clk_gpio_data_dir_reg); |
d3f431d0 | 121 | if (value) { /* High */ |
9137f812 MR |
122 | /* |
123 | * Set direction as input. This will automatically | |
124 | * pull the signal up. | |
125 | */ | |
fe820044 | 126 | gpio_dir &= ~(1 << sw_i2c_clk_gpio); |
c075b6f2 | 127 | poke32(sw_i2c_clk_gpio_data_dir_reg, gpio_dir); |
d3f431d0 | 128 | } else { /* Low */ |
7ef803a9 | 129 | /* Set the signal down */ |
c075b6f2 | 130 | gpio_data = peek32(sw_i2c_clk_gpio_data_reg); |
fe820044 | 131 | gpio_data &= ~(1 << sw_i2c_clk_gpio); |
c075b6f2 | 132 | poke32(sw_i2c_clk_gpio_data_reg, gpio_data); |
7ef803a9 IA |
133 | |
134 | /* Set direction as output */ | |
fe820044 | 135 | gpio_dir |= (1 << sw_i2c_clk_gpio); |
c075b6f2 | 136 | poke32(sw_i2c_clk_gpio_data_dir_reg, gpio_dir); |
7ef803a9 | 137 | } |
81dee67e SM |
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 | */ | |
6c78f4ce | 152 | static void sw_i2c_sda(unsigned char value) |
81dee67e | 153 | { |
fe820044 MR |
154 | unsigned long gpio_data; |
155 | unsigned long gpio_dir; | |
7ef803a9 | 156 | |
c075b6f2 | 157 | gpio_dir = peek32(sw_i2c_data_gpio_data_dir_reg); |
d3f431d0 | 158 | if (value) { /* High */ |
9137f812 MR |
159 | /* |
160 | * Set direction as input. This will automatically | |
161 | * pull the signal up. | |
162 | */ | |
fe820044 | 163 | gpio_dir &= ~(1 << sw_i2c_data_gpio); |
c075b6f2 | 164 | poke32(sw_i2c_data_gpio_data_dir_reg, gpio_dir); |
d3f431d0 | 165 | } else { /* Low */ |
7ef803a9 | 166 | /* Set the signal down */ |
c075b6f2 | 167 | gpio_data = peek32(sw_i2c_data_gpio_data_reg); |
fe820044 | 168 | gpio_data &= ~(1 << sw_i2c_data_gpio); |
c075b6f2 | 169 | poke32(sw_i2c_data_gpio_data_reg, gpio_data); |
7ef803a9 IA |
170 | |
171 | /* Set direction as output */ | |
fe820044 | 172 | gpio_dir |= (1 << sw_i2c_data_gpio); |
c075b6f2 | 173 | poke32(sw_i2c_data_gpio_data_dir_reg, gpio_dir); |
7ef803a9 | 174 | } |
81dee67e SM |
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 | */ | |
6c78f4ce | 183 | static unsigned char sw_i2c_read_sda(void) |
81dee67e | 184 | { |
fe820044 MR |
185 | unsigned long gpio_dir; |
186 | unsigned long gpio_data; | |
9137f812 | 187 | unsigned long dir_mask = 1 << sw_i2c_data_gpio; |
7ef803a9 IA |
188 | |
189 | /* Make sure that the direction is input (High) */ | |
c075b6f2 | 190 | gpio_dir = peek32(sw_i2c_data_gpio_data_dir_reg); |
9137f812 | 191 | if ((gpio_dir & dir_mask) != ~dir_mask) { |
fe820044 | 192 | gpio_dir &= ~(1 << sw_i2c_data_gpio); |
c075b6f2 | 193 | poke32(sw_i2c_data_gpio_data_dir_reg, gpio_dir); |
7ef803a9 IA |
194 | } |
195 | ||
196 | /* Now read the SDA line */ | |
c075b6f2 | 197 | gpio_data = peek32(sw_i2c_data_gpio_data_reg); |
fe820044 | 198 | if (gpio_data & (1 << sw_i2c_data_gpio)) |
7ef803a9 IA |
199 | return 1; |
200 | else | |
201 | return 0; | |
81dee67e SM |
202 | } |
203 | ||
81dee67e SM |
204 | /* |
205 | * This function sends ACK signal | |
206 | */ | |
6c78f4ce | 207 | static void sw_i2c_ack(void) |
81dee67e | 208 | { |
7ef803a9 | 209 | return; /* Single byte read is ok without it. */ |
81dee67e SM |
210 | } |
211 | ||
212 | /* | |
213 | * This function sends the start command to the slave device | |
214 | */ | |
6c78f4ce | 215 | static void sw_i2c_start(void) |
81dee67e | 216 | { |
7ef803a9 | 217 | /* Start I2C */ |
6c78f4ce MR |
218 | sw_i2c_sda(1); |
219 | sw_i2c_scl(1); | |
220 | sw_i2c_sda(0); | |
81dee67e SM |
221 | } |
222 | ||
223 | /* | |
224 | * This function sends the stop command to the slave device | |
225 | */ | |
6c78f4ce | 226 | static void sw_i2c_stop(void) |
81dee67e | 227 | { |
7ef803a9 | 228 | /* Stop the I2C */ |
6c78f4ce MR |
229 | sw_i2c_scl(1); |
230 | sw_i2c_sda(0); | |
231 | sw_i2c_sda(1); | |
81dee67e SM |
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 | */ | |
6c78f4ce | 244 | static long sw_i2c_write_byte(unsigned char data) |
81dee67e | 245 | { |
7ef803a9 IA |
246 | unsigned char value = data; |
247 | int i; | |
248 | ||
249 | /* Sending the data bit by bit */ | |
d3f431d0 | 250 | for (i = 0; i < 8; i++) { |
7ef803a9 | 251 | /* Set SCL to low */ |
6c78f4ce | 252 | sw_i2c_scl(0); |
7ef803a9 IA |
253 | |
254 | /* Send data bit */ | |
255 | if ((value & 0x80) != 0) | |
6c78f4ce | 256 | sw_i2c_sda(1); |
7ef803a9 | 257 | else |
6c78f4ce | 258 | sw_i2c_sda(0); |
7ef803a9 | 259 | |
6c78f4ce | 260 | sw_i2c_wait(); |
7ef803a9 IA |
261 | |
262 | /* Toggle clk line to one */ | |
6c78f4ce MR |
263 | sw_i2c_scl(1); |
264 | sw_i2c_wait(); | |
7ef803a9 IA |
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) */ | |
6c78f4ce MR |
271 | sw_i2c_scl(0); |
272 | sw_i2c_sda(1); | |
7ef803a9 IA |
273 | |
274 | /* Set the SCL High for ack */ | |
6c78f4ce MR |
275 | sw_i2c_wait(); |
276 | sw_i2c_scl(1); | |
277 | sw_i2c_wait(); | |
7ef803a9 IA |
278 | |
279 | /* Read SDA, until SDA==0 */ | |
6bdee8bd | 280 | for (i = 0; i < 0xff; i++) { |
6c78f4ce | 281 | if (!sw_i2c_read_sda()) |
7ef803a9 IA |
282 | break; |
283 | ||
6c78f4ce MR |
284 | sw_i2c_scl(0); |
285 | sw_i2c_wait(); | |
286 | sw_i2c_scl(1); | |
287 | sw_i2c_wait(); | |
7ef803a9 IA |
288 | } |
289 | ||
290 | /* Set the SCL Low and SDA High */ | |
6c78f4ce MR |
291 | sw_i2c_scl(0); |
292 | sw_i2c_sda(1); | |
7ef803a9 | 293 | |
6d43b0f4 | 294 | if (i < 0xff) |
7ef803a9 IA |
295 | return 0; |
296 | else | |
297 | return -1; | |
81dee67e SM |
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 | */ | |
6c78f4ce | 310 | static unsigned char sw_i2c_read_byte(unsigned char ack) |
81dee67e | 311 | { |
7ef803a9 IA |
312 | int i; |
313 | unsigned char data = 0; | |
81dee67e | 314 | |
6bdee8bd | 315 | for (i = 7; i >= 0; i--) { |
7ef803a9 | 316 | /* Set the SCL to Low and SDA to High (Input) */ |
6c78f4ce MR |
317 | sw_i2c_scl(0); |
318 | sw_i2c_sda(1); | |
319 | sw_i2c_wait(); | |
81dee67e | 320 | |
7ef803a9 | 321 | /* Set the SCL High */ |
6c78f4ce MR |
322 | sw_i2c_scl(1); |
323 | sw_i2c_wait(); | |
81dee67e | 324 | |
7ef803a9 | 325 | /* Read data bits from SDA */ |
6c78f4ce | 326 | data |= (sw_i2c_read_sda() << i); |
7ef803a9 | 327 | } |
81dee67e | 328 | |
7ef803a9 | 329 | if (ack) |
6c78f4ce | 330 | sw_i2c_ack(); |
81dee67e | 331 | |
7ef803a9 | 332 | /* Set the SCL Low and SDA High */ |
6c78f4ce MR |
333 | sw_i2c_scl(0); |
334 | sw_i2c_sda(1); | |
81dee67e | 335 | |
7ef803a9 | 336 | return data; |
81dee67e | 337 | } |
81dee67e SM |
338 | |
339 | /* | |
340 | * This function initializes GPIO port for SW I2C communication. | |
341 | * | |
342 | * Parameters: | |
fe820044 MR |
343 | * clk_gpio - The GPIO pin to be used as i2c SCL |
344 | * data_gpio - The GPIO pin to be used as i2c SDA | |
81dee67e SM |
345 | * |
346 | * Return Value: | |
347 | * -1 - Fail to initialize the i2c | |
348 | * 0 - Success | |
349 | */ | |
c9750456 | 350 | static long sm750le_i2c_init(unsigned char clk_gpio, unsigned char data_gpio) |
81dee67e | 351 | { |
7ef803a9 | 352 | int i; |
81dee67e | 353 | |
7ef803a9 | 354 | /* Initialize the GPIO pin for the i2c Clock Register */ |
53bc6b6e MR |
355 | sw_i2c_clk_gpio_data_reg = GPIO_DATA_SM750LE; |
356 | sw_i2c_clk_gpio_data_dir_reg = GPIO_DATA_DIRECTION_SM750LE; | |
81dee67e | 357 | |
7ef803a9 | 358 | /* Initialize the Clock GPIO Offset */ |
fe820044 | 359 | sw_i2c_clk_gpio = clk_gpio; |
81dee67e | 360 | |
7ef803a9 | 361 | /* Initialize the GPIO pin for the i2c Data Register */ |
53bc6b6e MR |
362 | sw_i2c_data_gpio_data_reg = GPIO_DATA_SM750LE; |
363 | sw_i2c_data_gpio_data_dir_reg = GPIO_DATA_DIRECTION_SM750LE; | |
81dee67e | 364 | |
7ef803a9 | 365 | /* Initialize the Data GPIO Offset */ |
fe820044 | 366 | sw_i2c_data_gpio = data_gpio; |
81dee67e | 367 | |
7ef803a9 | 368 | /* Note that SM750LE don't have GPIO MUX and power is always on */ |
81dee67e | 369 | |
7ef803a9 | 370 | /* Clear the i2c lines. */ |
6bdee8bd | 371 | for (i = 0; i < 9; i++) |
6c78f4ce | 372 | sw_i2c_stop(); |
81dee67e | 373 | |
7ef803a9 | 374 | return 0; |
81dee67e SM |
375 | } |
376 | ||
377 | /* | |
378 | * This function initializes the i2c attributes and bus | |
379 | * | |
380 | * Parameters: | |
fe820044 MR |
381 | * clk_gpio - The GPIO pin to be used as i2c SCL |
382 | * data_gpio - The GPIO pin to be used as i2c SDA | |
81dee67e SM |
383 | * |
384 | * Return Value: | |
385 | * -1 - Fail to initialize the i2c | |
386 | * 0 - Success | |
387 | */ | |
c9750456 | 388 | long sm750_sw_i2c_init(unsigned char clk_gpio, unsigned char data_gpio) |
81dee67e | 389 | { |
7ef803a9 | 390 | int i; |
81dee67e | 391 | |
9137f812 MR |
392 | /* |
393 | * Return 0 if the GPIO pins to be used is out of range. The | |
394 | * range is only from [0..63] | |
395 | */ | |
fe820044 | 396 | if ((clk_gpio > 31) || (data_gpio > 31)) |
7ef803a9 | 397 | return -1; |
81dee67e | 398 | |
06a4f429 | 399 | if (sm750_get_chip_type() == SM750LE) |
fe820044 | 400 | return sm750le_i2c_init(clk_gpio, data_gpio); |
81dee67e | 401 | |
7ef803a9 | 402 | /* Initialize the GPIO pin for the i2c Clock Register */ |
53bc6b6e MR |
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; | |
81dee67e | 406 | |
7ef803a9 | 407 | /* Initialize the Clock GPIO Offset */ |
fe820044 | 408 | sw_i2c_clk_gpio = clk_gpio; |
81dee67e | 409 | |
7ef803a9 | 410 | /* Initialize the GPIO pin for the i2c Data Register */ |
53bc6b6e MR |
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; | |
81dee67e | 414 | |
7ef803a9 | 415 | /* Initialize the Data GPIO Offset */ |
fe820044 | 416 | sw_i2c_data_gpio = data_gpio; |
81dee67e | 417 | |
7ef803a9 | 418 | /* Enable the GPIO pins for the i2c Clock and Data (GPIO MUX) */ |
c075b6f2 MS |
419 | poke32(sw_i2c_clk_gpio_mux_reg, |
420 | peek32(sw_i2c_clk_gpio_mux_reg) & ~(1 << sw_i2c_clk_gpio)); | |
421 | poke32(sw_i2c_data_gpio_mux_reg, | |
422 | peek32(sw_i2c_data_gpio_mux_reg) & ~(1 << sw_i2c_data_gpio)); | |
81dee67e | 423 | |
7ef803a9 | 424 | /* Enable GPIO power */ |
52d0744d | 425 | sm750_enable_gpio(1); |
81dee67e | 426 | |
7ef803a9 | 427 | /* Clear the i2c lines. */ |
6bdee8bd | 428 | for (i = 0; i < 9; i++) |
6c78f4ce | 429 | sw_i2c_stop(); |
81dee67e | 430 | |
7ef803a9 | 431 | return 0; |
81dee67e SM |
432 | } |
433 | ||
434 | /* | |
435 | * This function reads the slave device's register | |
436 | * | |
437 | * Parameters: | |
fe820044 | 438 | * addr - i2c Slave device address which register |
81dee67e | 439 | * to be read from |
fe820044 | 440 | * reg - Slave device's register to be read |
81dee67e SM |
441 | * |
442 | * Return Value: | |
443 | * Register value | |
444 | */ | |
c9750456 | 445 | unsigned char sm750_sw_i2c_read_reg(unsigned char addr, unsigned char reg) |
81dee67e | 446 | { |
7ef803a9 | 447 | unsigned char data; |
81dee67e | 448 | |
7ef803a9 | 449 | /* Send the Start signal */ |
6c78f4ce | 450 | sw_i2c_start(); |
81dee67e | 451 | |
7ef803a9 | 452 | /* Send the device address */ |
fe820044 | 453 | sw_i2c_write_byte(addr); |
81dee67e | 454 | |
7ef803a9 | 455 | /* Send the register index */ |
fe820044 | 456 | sw_i2c_write_byte(reg); |
81dee67e | 457 | |
7ef803a9 | 458 | /* Get the bus again and get the data from the device read address */ |
6c78f4ce | 459 | sw_i2c_start(); |
fe820044 | 460 | sw_i2c_write_byte(addr + 1); |
6c78f4ce | 461 | data = sw_i2c_read_byte(1); |
81dee67e | 462 | |
7ef803a9 | 463 | /* Stop swI2C and release the bus */ |
6c78f4ce | 464 | sw_i2c_stop(); |
81dee67e | 465 | |
7ef803a9 | 466 | return data; |
81dee67e SM |
467 | } |
468 | ||
469 | /* | |
470 | * This function writes a value to the slave device's register | |
471 | * | |
472 | * Parameters: | |
fe820044 | 473 | * addr - i2c Slave device address which register |
81dee67e | 474 | * to be written |
fe820044 | 475 | * reg - Slave device's register to be written |
81dee67e SM |
476 | * data - Data to be written to the register |
477 | * | |
478 | * Result: | |
479 | * 0 - Success | |
480 | * -1 - Fail | |
481 | */ | |
c9750456 MD |
482 | long sm750_sw_i2c_write_reg(unsigned char addr, |
483 | unsigned char reg, | |
484 | unsigned char data) | |
81dee67e | 485 | { |
fe820044 | 486 | long ret = 0; |
81dee67e | 487 | |
7ef803a9 | 488 | /* Send the Start signal */ |
6c78f4ce | 489 | sw_i2c_start(); |
81dee67e | 490 | |
7ef803a9 | 491 | /* Send the device address and read the data. All should return success |
35e4d8ca EF |
492 | * in order for the writing processed to be successful |
493 | */ | |
fe820044 MR |
494 | if ((sw_i2c_write_byte(addr) != 0) || |
495 | (sw_i2c_write_byte(reg) != 0) || | |
6c78f4ce | 496 | (sw_i2c_write_byte(data) != 0)) { |
fe820044 | 497 | ret = -1; |
7ef803a9 | 498 | } |
81dee67e | 499 | |
7ef803a9 | 500 | /* Stop i2c and release the bus */ |
6c78f4ce | 501 | sw_i2c_stop(); |
81dee67e | 502 | |
fe820044 | 503 | return ret; |
81dee67e | 504 | } |