diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2006-10-25 23:24:07 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2006-10-25 23:24:07 +0000 |
commit | 784dd787456b8c1f52a98559d645714760cd0ad4 (patch) | |
tree | e6d60a5790d4bbc9689b9d1d5f71799415a2c77a /firmware/target/coldfire/pcf50606-coldfire.c | |
parent | 0642451446f3bbaae53948f5fa41485177e3f35e (diff) | |
download | rockbox-784dd787456b8c1f52a98559d645714760cd0ad4.tar.gz rockbox-784dd787456b8c1f52a98559d645714760cd0ad4.zip |
Moved pcf50606 stuff to target directory.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11348 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/coldfire/pcf50606-coldfire.c')
-rw-r--r-- | firmware/target/coldfire/pcf50606-coldfire.c | 540 |
1 files changed, 540 insertions, 0 deletions
diff --git a/firmware/target/coldfire/pcf50606-coldfire.c b/firmware/target/coldfire/pcf50606-coldfire.c new file mode 100644 index 0000000000..ecc9e0ee72 --- /dev/null +++ b/firmware/target/coldfire/pcf50606-coldfire.c | |||
@@ -0,0 +1,540 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "config.h" | ||
20 | #include "system.h" | ||
21 | #include "logf.h" | ||
22 | #include "kernel.h" | ||
23 | #include "pcf50606.h" | ||
24 | |||
25 | #define USE_ASM | ||
26 | |||
27 | /* Define the approprate bits for SDA and SCL being the only difference in | ||
28 | config between each player. */ | ||
29 | #if defined(IRIVER_H300_SERIES) | ||
30 | #define SDA_BITNUM 13 /* LRCK3/GPIO45 */ | ||
31 | #define SCL_BITNUM 12 /* SWE/GPIO12 */ | ||
32 | #elif defined(IAUDIO_X5) | ||
33 | #define SDA_BITNUM 12 /* SDA1/RXD1/GPIO44 */ | ||
34 | #define SCL_BITNUM 10 /* SCL1/TXD1/GPIO10 */ | ||
35 | #endif | ||
36 | |||
37 | /* Data */ | ||
38 | #define SDA_GPIO_READ GPIO1_READ /* MBAR2 + 0x0b0 */ | ||
39 | #define SDA_GPIO_OUT GPIO1_OUT /* MBAR2 + 0x0b4 */ | ||
40 | #define SDA_GPIO_ENABLE GPIO1_ENABLE /* MBAR2 + 0x0b8 */ | ||
41 | #define SDA_GPIO_FUNCTION GPIO1_FUNCTION /* MBAR2 + 0x0bc */ | ||
42 | |||
43 | /* Clock */ | ||
44 | #define SCL_GPIO_READ GPIO_READ /* MBAR2 + 0x000 */ | ||
45 | #define SCL_GPIO_OUT GPIO_OUT /* MBAR2 + 0x004 */ | ||
46 | #define SCL_GPIO_ENABLE GPIO_ENABLE /* MBAR2 + 0x008 */ | ||
47 | #define SCL_GPIO_FUNCTION GPIO_FUNCTION /* MBAR2 + 0x00c */ | ||
48 | |||
49 | #define PCF50606_ADDR 0x10 | ||
50 | #define SCL_BIT (1ul << SCL_BITNUM) | ||
51 | #define SDA_BIT (1ul << SDA_BITNUM) | ||
52 | |||
53 | #define SDA ( SDA_BIT & SDA_GPIO_READ) | ||
54 | #define SDA_LO_OUT or_l( SDA_BIT, &SDA_GPIO_ENABLE) | ||
55 | #define SDA_HI_IN and_l(~SDA_BIT, &SDA_GPIO_ENABLE) | ||
56 | |||
57 | #define SCL ( SCL_BIT & SCL_GPIO_READ) | ||
58 | #define SCL_LO_OUT or_l( SCL_BIT, &SCL_GPIO_ENABLE) | ||
59 | #define SCL_HI_IN and_l(~SCL_BIT, &SCL_GPIO_ENABLE); while(!SCL); | ||
60 | |||
61 | #define DELAY \ | ||
62 | asm ( \ | ||
63 | "move.l %[dly],%%d0 \n" \ | ||
64 | "1: \n" \ | ||
65 | "subq.l #1,%%d0 \n" \ | ||
66 | "bhi.s 1b \n" \ | ||
67 | : : [dly]"d"(i2c_delay) : "d0" ); | ||
68 | |||
69 | void pcf50606_i2c_init(void) | ||
70 | { | ||
71 | /* Bit banged I2C */ | ||
72 | or_l(SDA_BIT, &SDA_GPIO_FUNCTION); | ||
73 | or_l(SCL_BIT, &SCL_GPIO_FUNCTION); | ||
74 | and_l(~SDA_BIT, &SDA_GPIO_OUT); | ||
75 | and_l(~SCL_BIT, &SCL_GPIO_OUT); | ||
76 | and_l(~SDA_BIT, &SDA_GPIO_ENABLE); | ||
77 | and_l(~SCL_BIT, &SCL_GPIO_ENABLE); | ||
78 | } | ||
79 | |||
80 | static int i2c_delay IDATA_ATTR = 44; | ||
81 | |||
82 | void pcf50606_i2c_recalc_delay(int cpu_clock) | ||
83 | { | ||
84 | i2c_delay = MAX(cpu_clock / (400000*2*3) - 7, 1); | ||
85 | } | ||
86 | |||
87 | inline void pcf50606_i2c_start(void) | ||
88 | { | ||
89 | #ifdef USE_ASM | ||
90 | asm ( | ||
91 | "not.l %[sdab] \n" /* SDA_HI_IN */ | ||
92 | "and.l %[sdab],(8,%[sdard]) \n" | ||
93 | "not.l %[sdab] \n" | ||
94 | |||
95 | "not.l %[sclb] \n" /* SCL_HI_IN */ | ||
96 | "and.l %[sclb],(8,%[sclrd]) \n" | ||
97 | "not.l %[sclb] \n" | ||
98 | "1: \n" | ||
99 | "move.l (%[sclrd]),%%d0 \n" | ||
100 | "btst.l %[sclbnum], %%d0 \n" | ||
101 | "beq.s 1b \n" | ||
102 | |||
103 | "move.l %[dly],%%d0 \n" /* DELAY */ | ||
104 | "1: \n" | ||
105 | "subq.l #1,%%d0 \n" | ||
106 | "bhi.s 1b \n" | ||
107 | |||
108 | "or.l %[sdab],(8,%[sdard]) \n" /* SDA_LO_OUT */ | ||
109 | |||
110 | "move.l %[dly],%%d0 \n" /* DELAY */ | ||
111 | "1: \n" | ||
112 | "subq.l #1,%%d0 \n" | ||
113 | "bhi.s 1b \n" | ||
114 | |||
115 | "or.l %[sclb],(8,%[sclrd]) \n" /* SCL_LO_OUT */ | ||
116 | : /* outputs */ | ||
117 | : /* inputs */ | ||
118 | [sclrd] "a"(&SCL_GPIO_READ), | ||
119 | [sclb] "d"(SCL_BIT), | ||
120 | [sclbnum] "i"(SCL_BITNUM), | ||
121 | [sdard] "a"(&SDA_GPIO_READ), | ||
122 | [sdab] "d"(SDA_BIT), | ||
123 | [dly] "d"(i2c_delay) | ||
124 | : /* clobbers */ | ||
125 | "d0" | ||
126 | ); | ||
127 | #else | ||
128 | SDA_HI_IN; | ||
129 | SCL_HI_IN; | ||
130 | DELAY; | ||
131 | SDA_LO_OUT; | ||
132 | DELAY; | ||
133 | SCL_LO_OUT; | ||
134 | #endif | ||
135 | } | ||
136 | |||
137 | inline void pcf50606_i2c_stop(void) | ||
138 | { | ||
139 | #ifdef USE_ASM | ||
140 | asm ( | ||
141 | "or.l %[sdab],(8,%[sdard]) \n" /* SDA_LO_OUT */ | ||
142 | |||
143 | "not.l %[sclb] \n" /* SCL_HI_IN */ | ||
144 | "and.l %[sclb],(8,%[sclrd]) \n" | ||
145 | "not.l %[sclb] \n" | ||
146 | "1: \n" | ||
147 | "move.l (%[sclrd]),%%d0 \n" | ||
148 | "btst.l %[sclbnum],%%d0 \n" | ||
149 | "beq.s 1b \n" | ||
150 | |||
151 | "move.l %[dly],%%d0 \n" /* DELAY */ | ||
152 | "1: \n" | ||
153 | "subq.l #1,%%d0 \n" | ||
154 | "bhi.s 1b \n" | ||
155 | |||
156 | "not.l %[sdab] \n" /* SDA_HI_IN */ | ||
157 | "and.l %[sdab],(8,%[sdard]) \n" | ||
158 | "not.l %[sdab] \n" | ||
159 | : /* outputs */ | ||
160 | : /* inputs */ | ||
161 | [sclrd] "a"(&SCL_GPIO_READ), | ||
162 | [sclb] "d"(SCL_BIT), | ||
163 | [sclbnum] "i"(SCL_BITNUM), | ||
164 | [sdard] "a"(&SDA_GPIO_READ), | ||
165 | [sdab] "d"(SDA_BIT), | ||
166 | [dly] "d"(i2c_delay) | ||
167 | : /* clobbers */ | ||
168 | "d0" | ||
169 | ); | ||
170 | #else | ||
171 | SDA_LO_OUT; | ||
172 | SCL_HI_IN; | ||
173 | DELAY; | ||
174 | SDA_HI_IN; | ||
175 | #endif | ||
176 | } | ||
177 | |||
178 | inline void pcf50606_i2c_ack(bool ack) | ||
179 | { | ||
180 | #ifdef USE_ASM | ||
181 | asm ( | ||
182 | "tst.b %[ack] \n" /* if (!ack) */ | ||
183 | "bne.s 1f \n" | ||
184 | |||
185 | "not.l %[sdab] \n" /* SDA_HI_IN */ | ||
186 | "and.l %[sdab],(8,%[sdard]) \n" | ||
187 | "not.l %[sdab] \n" | ||
188 | ".word 0x51fb \n" /* trapf.l : else */ | ||
189 | "1: \n" | ||
190 | "or.l %[sdab],(8,%[sdard]) \n" /* SDA_LO_OUT */ | ||
191 | |||
192 | "not.l %[sclb] \n" /* SCL_HI_IN */ | ||
193 | "and.l %[sclb],(8,%[sclrd]) \n" | ||
194 | "not.l %[sclb] \n" | ||
195 | "1: \n" | ||
196 | "move.l (%[sclrd]),%%d0 \n" | ||
197 | "btst.l %[sclbnum],%%d0 \n" | ||
198 | "beq.s 1b \n" | ||
199 | |||
200 | "move.l %[dly],%%d0 \n" /* DELAY */ | ||
201 | "1: \n" | ||
202 | "subq.l #1,%%d0 \n" | ||
203 | "bhi.s 1b \n" | ||
204 | |||
205 | "or.l %[sclb],(8,%[sclrd]) \n" /* SCL_LO_OUT */ | ||
206 | : /* outputs */ | ||
207 | : /* inputs */ | ||
208 | [sclrd] "a"(&SCL_GPIO_READ), | ||
209 | [sclb] "d"(SCL_BIT), | ||
210 | [sclbnum] "i"(SCL_BITNUM), | ||
211 | [sdard] "a"(&SDA_GPIO_READ), | ||
212 | [sdab] "d"(SDA_BIT), | ||
213 | [dly] "d"(i2c_delay), | ||
214 | [ack] "d"(ack) | ||
215 | : /* clobbers */ | ||
216 | "d0" | ||
217 | ); | ||
218 | #else | ||
219 | if(ack) | ||
220 | SDA_LO_OUT; | ||
221 | else | ||
222 | SDA_HI_IN; | ||
223 | |||
224 | SCL_HI_IN; | ||
225 | |||
226 | DELAY; | ||
227 | SCL_LO_OUT; | ||
228 | #endif | ||
229 | } | ||
230 | |||
231 | inline bool pcf50606_i2c_getack(void) | ||
232 | { | ||
233 | bool ret; | ||
234 | |||
235 | #ifdef USE_ASM | ||
236 | asm ( | ||
237 | "not.l %[sdab] \n" /* SDA_HI_IN */ | ||
238 | "and.l %[sdab],(8,%[sdard]) \n" | ||
239 | "not.l %[sdab] \n" | ||
240 | |||
241 | "move.l %[dly],%%d0 \n" /* DELAY */ | ||
242 | "1: \n" | ||
243 | "subq.l #1,%%d0 \n" | ||
244 | "bhi.s 1b \n" | ||
245 | |||
246 | "not.l %[sclb] \n" /* SCL_HI_IN */ | ||
247 | "and.l %[sclb],(8,%[sclrd]) \n" | ||
248 | "not.l %[sclb] \n" | ||
249 | "1: \n" | ||
250 | "move.l (%[sclrd]),%%d0 \n" | ||
251 | "btst.l %[sclbnum],%%d0 \n" | ||
252 | "beq.s 1b \n" | ||
253 | |||
254 | "move.l (%[sdard]),%%d0 \n" /* ret = !SDA */ | ||
255 | "btst.l %[sdabnum],%%d0 \n" | ||
256 | "seq.b %[ret] \n" | ||
257 | |||
258 | "or.l %[sclb],(8,%[sclrd]) \n" /* SCL_LO_OUT */ | ||
259 | |||
260 | "move.l %[dly],%%d0 \n" /* DELAY */ | ||
261 | "1: \n" | ||
262 | "subq.l #1,%%d0 \n" | ||
263 | "bhi.s 1b \n" | ||
264 | : /* outputs */ | ||
265 | [ret] "=&d"(ret) | ||
266 | : /* inputs */ | ||
267 | [sclrd] "a"(&SCL_GPIO_READ), | ||
268 | [sclb] "d"(SCL_BIT), | ||
269 | [sclbnum] "i"(SCL_BITNUM), | ||
270 | [sdard] "a"(&SDA_GPIO_READ), | ||
271 | [sdab] "d"(SDA_BIT), | ||
272 | [sdabnum] "i"(SDA_BITNUM), | ||
273 | [dly] "d"(i2c_delay) | ||
274 | : /* clobbers */ | ||
275 | "d0" | ||
276 | ); | ||
277 | #else | ||
278 | SDA_HI_IN; | ||
279 | DELAY; | ||
280 | SCL_HI_IN; | ||
281 | |||
282 | ret = !SDA; | ||
283 | |||
284 | SCL_LO_OUT; | ||
285 | DELAY; | ||
286 | #endif | ||
287 | return ret; | ||
288 | } | ||
289 | |||
290 | void pcf50606_i2c_outb(unsigned char byte) | ||
291 | { | ||
292 | #ifdef USE_ASM | ||
293 | asm volatile ( | ||
294 | "moveq.l #24,%%d0 \n" /* byte <<= 24 */ | ||
295 | "lsl.l %%d0,%[byte] \n" | ||
296 | "moveq.l #8,%%d1 \n" /* i = 8 */ | ||
297 | |||
298 | "2: \n" /* do */ | ||
299 | "lsl.l #1,%[byte] \n" /* if ((byte <<= 1) carry) */ | ||
300 | "bcc.s 1f \n" | ||
301 | |||
302 | "not.l %[sdab] \n" /* SDA_HI_IN */ | ||
303 | "and.l %[sdab],(8,%[sdard]) \n" | ||
304 | "not.l %[sdab] \n" | ||
305 | ".word 0x51fb \n" /* trapf.l; else */ | ||
306 | "1: \n" | ||
307 | "or.l %[sdab],(8,%[sdard]) \n" /* SDA_LO_OUT */ | ||
308 | |||
309 | "move.l %[dly],%%d0 \n" /* DELAY */ | ||
310 | "1: \n" | ||
311 | "subq.l #1,%%d0 \n" | ||
312 | "bhi.s 1b \n" | ||
313 | |||
314 | "not.l %[sclb] \n" /* SCL_HI_IN */ | ||
315 | "and.l %[sclb],(8,%[sclrd]) \n" | ||
316 | "not.l %[sclb] \n" | ||
317 | "1: \n" | ||
318 | "move.l (%[sclrd]),%%d0 \n" | ||
319 | "btst.l %[sclbnum],%%d0 \n" | ||
320 | "beq.s 1b \n" | ||
321 | |||
322 | "move.l %[dly],%%d0 \n" /* DELAY */ | ||
323 | "1: \n" | ||
324 | "subq.l #1,%%d0 \n" | ||
325 | "bhi.s 1b \n" | ||
326 | |||
327 | "or.l %[sclb],(8,%[sclrd]) \n" /* SCL_LO_OUT */ | ||
328 | |||
329 | "subq.l #1,%%d1 \n" /* i-- */ | ||
330 | "bne.s 2b \n" /* while (i != 0) */ | ||
331 | : /* outputs */ | ||
332 | [byte] "+d"(byte) | ||
333 | : /* inputs */ | ||
334 | [sclrd] "a"(&SCL_GPIO_READ), | ||
335 | [sclb] "d"(SCL_BIT), | ||
336 | [sclbnum] "i"(SCL_BITNUM), | ||
337 | [sdard] "a"(&SDA_GPIO_READ), | ||
338 | [sdab] "d"(SDA_BIT), | ||
339 | [dly] "d"(i2c_delay) | ||
340 | : /* clobbers */ | ||
341 | "d0", "d1" | ||
342 | ); | ||
343 | #else | ||
344 | int i; | ||
345 | |||
346 | /* clock out each bit, MSB first */ | ||
347 | for ( i=0x80; i; i>>=1 ) | ||
348 | { | ||
349 | if ( i & byte ) | ||
350 | SDA_HI_IN; | ||
351 | else | ||
352 | SDA_LO_OUT; | ||
353 | DELAY; | ||
354 | SCL_HI_IN; | ||
355 | DELAY; | ||
356 | SCL_LO_OUT; | ||
357 | } | ||
358 | #endif | ||
359 | } | ||
360 | |||
361 | unsigned char pcf50606_i2c_inb(bool ack) | ||
362 | { | ||
363 | unsigned char byte = 0; | ||
364 | |||
365 | #ifdef USE_ASM | ||
366 | asm ( | ||
367 | "not.l %[sdab] \n" /* SDA_HI_IN */ | ||
368 | "and.l %[sdab],(8,%[sdard]) \n" | ||
369 | "not.l %[sdab] \n" | ||
370 | |||
371 | "moveq.l #8,%%d1 \n" /* i = 8 */ | ||
372 | "clr.l %[byte] \n" /* byte = 0 */ | ||
373 | |||
374 | "2: \n" /* do */ | ||
375 | "not.l %[sclb] \n" /* SCL_HI_IN */ | ||
376 | "and.l %[sclb],(8,%[sclrd]) \n" | ||
377 | "not.l %[sclb] \n" | ||
378 | "1: \n" | ||
379 | "move.l (%[sclrd]),%%d0 \n" | ||
380 | "btst.l %[sclbnum],%%d0 \n" | ||
381 | "beq.s 1b \n" | ||
382 | |||
383 | "move.l %[dly],%%d0 \n" /* DELAY */ | ||
384 | "1: \n" | ||
385 | "subq.l #1,%%d0 \n" | ||
386 | "bhi.s 1b \n" | ||
387 | |||
388 | "lsl.l #1,%[byte] \n" /* byte <<= 1 */ | ||
389 | "move.l (%[sdard]),%%d0 \n" /* if (SDA) */ | ||
390 | "btst.l %[sdabnum],%%d0 \n" | ||
391 | "beq.s 1f \n" | ||
392 | "addq.l #1,%[byte] \n" /* byte++ */ | ||
393 | "1: \n" | ||
394 | |||
395 | "or.l %[sclb],(8,%[sclrd]) \n" /* SCL_LO_OUT */ | ||
396 | |||
397 | "move.l %[dly],%%d0 \n" /* DELAY */ | ||
398 | "1: \n" | ||
399 | "subq.l #1,%%d0 \n" | ||
400 | "bhi.s 1b \n" | ||
401 | |||
402 | "subq.l #1,%%d1 \n" /* i-- */ | ||
403 | "bne.s 2b \n" /* while (i != 0) */ | ||
404 | : /* outputs */ | ||
405 | [byte] "=&d"(byte) | ||
406 | : /* inputs */ | ||
407 | [sclrd] "a"(&SCL_GPIO_READ), | ||
408 | [sclb] "d"(SCL_BIT), | ||
409 | [sclbnum] "i"(SCL_BITNUM), | ||
410 | [sdard] "a"(&SDA_GPIO_READ), | ||
411 | [sdab] "d"(SDA_BIT), | ||
412 | [sdabnum] "i"(SDA_BITNUM), | ||
413 | [dly] "d"(i2c_delay) | ||
414 | : /* clobbers */ | ||
415 | "d0", "d1" | ||
416 | ); | ||
417 | #else | ||
418 | int i; | ||
419 | |||
420 | /* clock in each bit, MSB first */ | ||
421 | SDA_HI_IN; | ||
422 | for ( i=0x80; i; i>>=1 ) | ||
423 | { | ||
424 | SCL_HI_IN; | ||
425 | DELAY; | ||
426 | if ( SDA ) | ||
427 | byte |= i; | ||
428 | SCL_LO_OUT; | ||
429 | DELAY; | ||
430 | } | ||
431 | #endif | ||
432 | |||
433 | pcf50606_i2c_ack(ack); | ||
434 | |||
435 | return byte; | ||
436 | } | ||
437 | |||
438 | int pcf50606_i2c_write(int address, const unsigned char* buf, int count) | ||
439 | { | ||
440 | int i,x=0; | ||
441 | |||
442 | pcf50606_i2c_start(); | ||
443 | pcf50606_i2c_outb(address & 0xfe); | ||
444 | if (pcf50606_i2c_getack()) | ||
445 | { | ||
446 | for (i=0; i<count; i++) | ||
447 | { | ||
448 | pcf50606_i2c_outb(buf[i]); | ||
449 | if (!pcf50606_i2c_getack()) | ||
450 | { | ||
451 | x=-2; | ||
452 | break; | ||
453 | } | ||
454 | } | ||
455 | } | ||
456 | else | ||
457 | { | ||
458 | logf("pcf50606_i2c_write() - no ack\n"); | ||
459 | x=-1; | ||
460 | } | ||
461 | return x; | ||
462 | } | ||
463 | |||
464 | int pcf50606_read_multiple(int address, unsigned char* buf, int count) | ||
465 | { | ||
466 | int i=0; | ||
467 | int ret = 0; | ||
468 | unsigned char obuf[1]; | ||
469 | |||
470 | obuf[0] = address; | ||
471 | |||
472 | /* send read command */ | ||
473 | if (pcf50606_i2c_write(PCF50606_ADDR, obuf, 1) >= 0) | ||
474 | { | ||
475 | pcf50606_i2c_start(); | ||
476 | pcf50606_i2c_outb(0x11); | ||
477 | if (pcf50606_i2c_getack()) | ||
478 | { | ||
479 | for(i = 0;i < count-1;i++) | ||
480 | buf[i] = pcf50606_i2c_inb(true); | ||
481 | |||
482 | buf[i] = pcf50606_i2c_inb(false); | ||
483 | } | ||
484 | else | ||
485 | { | ||
486 | ret = -1; | ||
487 | } | ||
488 | } | ||
489 | |||
490 | pcf50606_i2c_stop(); | ||
491 | |||
492 | return ret; | ||
493 | } | ||
494 | |||
495 | int pcf50606_read(int address) | ||
496 | { | ||
497 | int ret; | ||
498 | unsigned char c; | ||
499 | |||
500 | ret = pcf50606_read_multiple(address, &c, 1); | ||
501 | if(ret >= 0) | ||
502 | return c; | ||
503 | else | ||
504 | return ret; | ||
505 | } | ||
506 | |||
507 | int pcf50606_write_multiple(int address, const unsigned char* buf, int count) | ||
508 | { | ||
509 | unsigned char obuf[1]; | ||
510 | int i; | ||
511 | int ret = 0; | ||
512 | |||
513 | obuf[0] = address; | ||
514 | |||
515 | /* send write command */ | ||
516 | if (pcf50606_i2c_write(PCF50606_ADDR, obuf, 1) >= 0) | ||
517 | { | ||
518 | for (i=0; i<count; i++) | ||
519 | { | ||
520 | pcf50606_i2c_outb(buf[i]); | ||
521 | if (!pcf50606_i2c_getack()) | ||
522 | { | ||
523 | ret = -2; | ||
524 | break; | ||
525 | } | ||
526 | } | ||
527 | } | ||
528 | else | ||
529 | { | ||
530 | ret = -1; | ||
531 | } | ||
532 | |||
533 | pcf50606_i2c_stop(); | ||
534 | return ret; | ||
535 | } | ||
536 | |||
537 | int pcf50606_write(int address, unsigned char val) | ||
538 | { | ||
539 | return pcf50606_write_multiple(address, &val, 1); | ||
540 | } | ||