Commit | Line | Data |
---|---|---|
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. */ | |
53bc6b6e MR |
58 | static unsigned char sw_i2c_clk_gpio = DEFAULT_I2C_SCL; |
59 | static unsigned char sw_i2c_data_gpio = DEFAULT_I2C_SDA; | |
81dee67e SM |
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 */ | |
53bc6b6e MR |
73 | static unsigned long sw_i2c_clk_gpio_mux_reg = GPIO_MUX; |
74 | static unsigned long sw_i2c_clk_gpio_data_reg = GPIO_DATA; | |
75 | static unsigned long sw_i2c_clk_gpio_data_dir_reg = GPIO_DATA_DIRECTION; | |
81dee67e SM |
76 | |
77 | /* i2c Data GPIO Register usage */ | |
53bc6b6e MR |
78 | static unsigned long sw_i2c_data_gpio_mux_reg = GPIO_MUX; |
79 | static unsigned long sw_i2c_data_gpio_data_reg = GPIO_DATA; | |
80 | static unsigned long sw_i2c_data_gpio_data_dir_reg = GPIO_DATA_DIRECTION; | |
81dee67e | 81 | |
81dee67e SM |
82 | /* |
83 | * This function puts a delay between command | |
84 | */ | |
6c78f4ce | 85 | static void sw_i2c_wait(void) |
81dee67e SM |
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 | */ | |
6bdee8bd | 99 | while (peekIO(0x3ce, 0x61) & 0x10); |
81dee67e | 100 | #else |
7ef803a9 | 101 | int i, Temp; |
81dee67e | 102 | |
6bdee8bd | 103 | for (i = 0; i < 600; i++) { |
7ef803a9 IA |
104 | Temp = i; |
105 | Temp += i; | |
106 | } | |
81dee67e SM |
107 | #endif |
108 | } | |
109 | ||
110 | /* | |
111 | * This function set/reset the SCL GPIO pin | |
112 | * | |
113 | * Parameters: | |
114 | * value - Bit value to set to the SCL or SDA (0 = low, 1 = high) | |
115 | * | |
116 | * Notes: | |
117 | * When setting SCL to high, just set the GPIO as input where the pull up | |
118 | * resistor will pull the signal up. Do not use software to pull up the | |
119 | * signal because the i2c will fail when other device try to drive the | |
120 | * signal due to SM50x will drive the signal to always high. | |
121 | */ | |
6c78f4ce | 122 | static void sw_i2c_scl(unsigned char value) |
81dee67e | 123 | { |
7ef803a9 IA |
124 | unsigned long ulGPIOData; |
125 | unsigned long ulGPIODirection; | |
126 | ||
53bc6b6e | 127 | ulGPIODirection = PEEK32(sw_i2c_clk_gpio_data_dir_reg); |
d3f431d0 | 128 | if (value) { /* High */ |
7ef803a9 | 129 | /* Set direction as input. This will automatically pull the signal up. */ |
53bc6b6e MR |
130 | ulGPIODirection &= ~(1 << sw_i2c_clk_gpio); |
131 | POKE32(sw_i2c_clk_gpio_data_dir_reg, ulGPIODirection); | |
d3f431d0 | 132 | } else { /* Low */ |
7ef803a9 | 133 | /* Set the signal down */ |
53bc6b6e MR |
134 | ulGPIOData = PEEK32(sw_i2c_clk_gpio_data_reg); |
135 | ulGPIOData &= ~(1 << sw_i2c_clk_gpio); | |
136 | POKE32(sw_i2c_clk_gpio_data_reg, ulGPIOData); | |
7ef803a9 IA |
137 | |
138 | /* Set direction as output */ | |
53bc6b6e MR |
139 | ulGPIODirection |= (1 << sw_i2c_clk_gpio); |
140 | POKE32(sw_i2c_clk_gpio_data_dir_reg, ulGPIODirection); | |
7ef803a9 | 141 | } |
81dee67e SM |
142 | } |
143 | ||
144 | /* | |
145 | * This function set/reset the SDA GPIO pin | |
146 | * | |
147 | * Parameters: | |
148 | * value - Bit value to set to the SCL or SDA (0 = low, 1 = high) | |
149 | * | |
150 | * Notes: | |
151 | * When setting SCL to high, just set the GPIO as input where the pull up | |
152 | * resistor will pull the signal up. Do not use software to pull up the | |
153 | * signal because the i2c will fail when other device try to drive the | |
154 | * signal due to SM50x will drive the signal to always high. | |
155 | */ | |
6c78f4ce | 156 | static void sw_i2c_sda(unsigned char value) |
81dee67e | 157 | { |
7ef803a9 IA |
158 | unsigned long ulGPIOData; |
159 | unsigned long ulGPIODirection; | |
160 | ||
53bc6b6e | 161 | ulGPIODirection = PEEK32(sw_i2c_data_gpio_data_dir_reg); |
d3f431d0 | 162 | if (value) { /* High */ |
7ef803a9 | 163 | /* Set direction as input. This will automatically pull the signal up. */ |
53bc6b6e MR |
164 | ulGPIODirection &= ~(1 << sw_i2c_data_gpio); |
165 | POKE32(sw_i2c_data_gpio_data_dir_reg, ulGPIODirection); | |
d3f431d0 | 166 | } else { /* Low */ |
7ef803a9 | 167 | /* Set the signal down */ |
53bc6b6e MR |
168 | ulGPIOData = PEEK32(sw_i2c_data_gpio_data_reg); |
169 | ulGPIOData &= ~(1 << sw_i2c_data_gpio); | |
170 | POKE32(sw_i2c_data_gpio_data_reg, ulGPIOData); | |
7ef803a9 IA |
171 | |
172 | /* Set direction as output */ | |
53bc6b6e MR |
173 | ulGPIODirection |= (1 << sw_i2c_data_gpio); |
174 | POKE32(sw_i2c_data_gpio_data_dir_reg, ulGPIODirection); | |
7ef803a9 | 175 | } |
81dee67e SM |
176 | } |
177 | ||
178 | /* | |
179 | * This function read the data from the SDA GPIO pin | |
180 | * | |
181 | * Return Value: | |
182 | * The SDA data bit sent by the Slave | |
183 | */ | |
6c78f4ce | 184 | static unsigned char sw_i2c_read_sda(void) |
81dee67e | 185 | { |
7ef803a9 IA |
186 | unsigned long ulGPIODirection; |
187 | unsigned long ulGPIOData; | |
188 | ||
189 | /* Make sure that the direction is input (High) */ | |
53bc6b6e MR |
190 | ulGPIODirection = PEEK32(sw_i2c_data_gpio_data_dir_reg); |
191 | if ((ulGPIODirection & (1 << sw_i2c_data_gpio)) != (~(1 << sw_i2c_data_gpio))) { | |
192 | ulGPIODirection &= ~(1 << sw_i2c_data_gpio); | |
193 | POKE32(sw_i2c_data_gpio_data_dir_reg, ulGPIODirection); | |
7ef803a9 IA |
194 | } |
195 | ||
196 | /* Now read the SDA line */ | |
53bc6b6e MR |
197 | ulGPIOData = PEEK32(sw_i2c_data_gpio_data_reg); |
198 | if (ulGPIOData & (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: | |
343 | * i2cClkGPIO - The GPIO pin to be used as i2c SCL | |
344 | * i2cDataGPIO - The GPIO pin to be used as i2c SDA | |
345 | * | |
346 | * Return Value: | |
347 | * -1 - Fail to initialize the i2c | |
348 | * 0 - Success | |
349 | */ | |
6c78f4ce | 350 | static long sm750le_i2c_init(unsigned char i2cClkGPIO, |
6a9df430 | 351 | unsigned char i2cDataGPIO) |
81dee67e | 352 | { |
7ef803a9 | 353 | int i; |
81dee67e | 354 | |
7ef803a9 | 355 | /* Initialize the GPIO pin for the i2c Clock Register */ |
53bc6b6e MR |
356 | sw_i2c_clk_gpio_data_reg = GPIO_DATA_SM750LE; |
357 | sw_i2c_clk_gpio_data_dir_reg = GPIO_DATA_DIRECTION_SM750LE; | |
81dee67e | 358 | |
7ef803a9 | 359 | /* Initialize the Clock GPIO Offset */ |
53bc6b6e | 360 | sw_i2c_clk_gpio = i2cClkGPIO; |
81dee67e | 361 | |
7ef803a9 | 362 | /* Initialize the GPIO pin for the i2c Data Register */ |
53bc6b6e MR |
363 | sw_i2c_data_gpio_data_reg = GPIO_DATA_SM750LE; |
364 | sw_i2c_data_gpio_data_dir_reg = GPIO_DATA_DIRECTION_SM750LE; | |
81dee67e | 365 | |
7ef803a9 | 366 | /* Initialize the Data GPIO Offset */ |
53bc6b6e | 367 | sw_i2c_data_gpio = i2cDataGPIO; |
81dee67e | 368 | |
7ef803a9 | 369 | /* Note that SM750LE don't have GPIO MUX and power is always on */ |
81dee67e | 370 | |
7ef803a9 | 371 | /* Clear the i2c lines. */ |
6bdee8bd | 372 | for (i = 0; i < 9; i++) |
6c78f4ce | 373 | sw_i2c_stop(); |
81dee67e | 374 | |
7ef803a9 | 375 | return 0; |
81dee67e SM |
376 | } |
377 | ||
378 | /* | |
379 | * This function initializes the i2c attributes and bus | |
380 | * | |
381 | * Parameters: | |
382 | * i2cClkGPIO - The GPIO pin to be used as i2c SCL | |
383 | * i2cDataGPIO - The GPIO pin to be used as i2c SDA | |
384 | * | |
385 | * Return Value: | |
386 | * -1 - Fail to initialize the i2c | |
387 | * 0 - Success | |
388 | */ | |
f2ea7733 | 389 | long sm750_sw_i2c_init( |
7ef803a9 IA |
390 | unsigned char i2cClkGPIO, |
391 | unsigned char i2cDataGPIO | |
81dee67e SM |
392 | ) |
393 | { | |
7ef803a9 | 394 | int i; |
81dee67e | 395 | |
7ef803a9 IA |
396 | /* Return 0 if the GPIO pins to be used is out of range. The range is only from [0..63] */ |
397 | if ((i2cClkGPIO > 31) || (i2cDataGPIO > 31)) | |
398 | return -1; | |
81dee67e | 399 | |
7ef803a9 | 400 | if (getChipType() == SM750LE) |
6c78f4ce | 401 | return sm750le_i2c_init(i2cClkGPIO, i2cDataGPIO); |
81dee67e | 402 | |
7ef803a9 | 403 | /* Initialize the GPIO pin for the i2c Clock Register */ |
53bc6b6e MR |
404 | sw_i2c_clk_gpio_mux_reg = GPIO_MUX; |
405 | sw_i2c_clk_gpio_data_reg = GPIO_DATA; | |
406 | sw_i2c_clk_gpio_data_dir_reg = GPIO_DATA_DIRECTION; | |
81dee67e | 407 | |
7ef803a9 | 408 | /* Initialize the Clock GPIO Offset */ |
53bc6b6e | 409 | sw_i2c_clk_gpio = i2cClkGPIO; |
81dee67e | 410 | |
7ef803a9 | 411 | /* Initialize the GPIO pin for the i2c Data Register */ |
53bc6b6e MR |
412 | sw_i2c_data_gpio_mux_reg = GPIO_MUX; |
413 | sw_i2c_data_gpio_data_reg = GPIO_DATA; | |
414 | sw_i2c_data_gpio_data_dir_reg = GPIO_DATA_DIRECTION; | |
81dee67e | 415 | |
7ef803a9 | 416 | /* Initialize the Data GPIO Offset */ |
53bc6b6e | 417 | sw_i2c_data_gpio = i2cDataGPIO; |
81dee67e | 418 | |
7ef803a9 | 419 | /* Enable the GPIO pins for the i2c Clock and Data (GPIO MUX) */ |
53bc6b6e MR |
420 | POKE32(sw_i2c_clk_gpio_mux_reg, |
421 | PEEK32(sw_i2c_clk_gpio_mux_reg) & ~(1 << sw_i2c_clk_gpio)); | |
422 | POKE32(sw_i2c_data_gpio_mux_reg, | |
423 | PEEK32(sw_i2c_data_gpio_mux_reg) & ~(1 << sw_i2c_data_gpio)); | |
81dee67e | 424 | |
7ef803a9 IA |
425 | /* Enable GPIO power */ |
426 | enableGPIO(1); | |
81dee67e | 427 | |
7ef803a9 | 428 | /* Clear the i2c lines. */ |
6bdee8bd | 429 | for (i = 0; i < 9; i++) |
6c78f4ce | 430 | sw_i2c_stop(); |
81dee67e | 431 | |
7ef803a9 | 432 | return 0; |
81dee67e SM |
433 | } |
434 | ||
435 | /* | |
436 | * This function reads the slave device's register | |
437 | * | |
438 | * Parameters: | |
439 | * deviceAddress - i2c Slave device address which register | |
440 | * to be read from | |
441 | * registerIndex - Slave device's register to be read | |
442 | * | |
443 | * Return Value: | |
444 | * Register value | |
445 | */ | |
288836b6 | 446 | unsigned char sm750_sw_i2c_read_reg( |
7ef803a9 IA |
447 | unsigned char deviceAddress, |
448 | unsigned char registerIndex | |
81dee67e SM |
449 | ) |
450 | { | |
7ef803a9 | 451 | unsigned char data; |
81dee67e | 452 | |
7ef803a9 | 453 | /* Send the Start signal */ |
6c78f4ce | 454 | sw_i2c_start(); |
81dee67e | 455 | |
7ef803a9 | 456 | /* Send the device address */ |
6c78f4ce | 457 | sw_i2c_write_byte(deviceAddress); |
81dee67e | 458 | |
7ef803a9 | 459 | /* Send the register index */ |
6c78f4ce | 460 | sw_i2c_write_byte(registerIndex); |
81dee67e | 461 | |
7ef803a9 | 462 | /* Get the bus again and get the data from the device read address */ |
6c78f4ce MR |
463 | sw_i2c_start(); |
464 | sw_i2c_write_byte(deviceAddress + 1); | |
465 | data = sw_i2c_read_byte(1); | |
81dee67e | 466 | |
7ef803a9 | 467 | /* Stop swI2C and release the bus */ |
6c78f4ce | 468 | sw_i2c_stop(); |
81dee67e | 469 | |
7ef803a9 | 470 | return data; |
81dee67e SM |
471 | } |
472 | ||
473 | /* | |
474 | * This function writes a value to the slave device's register | |
475 | * | |
476 | * Parameters: | |
477 | * deviceAddress - i2c Slave device address which register | |
478 | * to be written | |
479 | * registerIndex - Slave device's register to be written | |
480 | * data - Data to be written to the register | |
481 | * | |
482 | * Result: | |
483 | * 0 - Success | |
484 | * -1 - Fail | |
485 | */ | |
d33b4204 | 486 | long sm750_sw_i2c_write_reg( |
7ef803a9 IA |
487 | unsigned char deviceAddress, |
488 | unsigned char registerIndex, | |
489 | unsigned char data | |
81dee67e SM |
490 | ) |
491 | { | |
7ef803a9 | 492 | long returnValue = 0; |
81dee67e | 493 | |
7ef803a9 | 494 | /* Send the Start signal */ |
6c78f4ce | 495 | sw_i2c_start(); |
81dee67e | 496 | |
7ef803a9 IA |
497 | /* Send the device address and read the data. All should return success |
498 | in order for the writing processed to be successful | |
499 | */ | |
6c78f4ce MR |
500 | if ((sw_i2c_write_byte(deviceAddress) != 0) || |
501 | (sw_i2c_write_byte(registerIndex) != 0) || | |
502 | (sw_i2c_write_byte(data) != 0)) { | |
7ef803a9 IA |
503 | returnValue = -1; |
504 | } | |
81dee67e | 505 | |
7ef803a9 | 506 | /* Stop i2c and release the bus */ |
6c78f4ce | 507 | sw_i2c_stop(); |
81dee67e | 508 | |
7ef803a9 | 509 | return returnValue; |
81dee67e | 510 | } |