1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9 * Physical interface of the Philips TEA5767 in iriver H10 series
11 * Copyright (C) 2002 by Linus Nielsen Feltzing
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
26 #include "fmradio_i2c.h"
28 /* cute little functions, atomic read-modify-write */
30 #define SDA_OUTINIT GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x08)
31 #define SDA_HI_IN GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x08)
32 #define SDA_LO_OUT GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x08)
33 #define SDA (GPIOD_INPUT_VAL & 0x08)
35 #define SCL_INPUT GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x10)
36 #define SCL_OUTPUT GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x10)
37 #define SCL_LO GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x10)
38 #define SCL_HI GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL,0x10)
39 #define SCL (GPIOD_INPUT_VAL & 0x10)
41 #define DELAY udelay(2)
43 static void fmradio_i2c_start(void)
55 static void fmradio_i2c_stop(void)
64 /* Generate ACK or NACK */
65 static void fmradio_i2c_ack(bool nack
)
67 /* Here's the deal. The slave is slow, and sometimes needs to wait
68 before it can receive the acknowledge. Therefore it forces the clock
69 low until it is ready. We need to poll the clock line until it goes
70 high before we release the ack.
72 In their infinite wisdom, iriver didn't pull up the SCL line, so
73 we have to drive the SCL high repeatedly to simulate a pullup. */
84 SCL_OUTPUT
; /* Set the clock to output */
85 SCL_INPUT
; /* Set the clock to input */
88 while(!SCL
); /* and wait for the slave to release it */
94 static int fmradio_i2c_getack(void)
98 /* Here's the deal. The slave is slow, and sometimes needs to wait
99 before it can send the acknowledge. Therefore it forces the clock
100 low until it is ready. We need to poll the clock line until it goes
101 high before we read the ack.
103 In their infinite wisdom, iriver didn't pull up the SCL line, so
104 we have to drive the SCL high repeatedly to simulate a pullup. */
109 SCL_HI
; /* set clock to high */
112 SCL_OUTPUT
; /* Set the clock to output */
113 SCL_INPUT
; /* Set the clock to input */
116 while(!SCL
); /* and wait for the slave to release it */
119 ret
= 0; /* ack failed */
127 static void fmradio_i2c_outb(unsigned char byte
)
131 /* clock out each bit, MSB first */
132 for ( i
=0x80; i
; i
>>=1 ) {
146 static unsigned char fmradio_i2c_inb(void)
149 unsigned char byte
= 0;
152 /* clock in each bit, MSB first */
153 for ( i
=0x80; i
; i
>>=1 ) {
165 int fmradio_i2c_write(unsigned char address
, const unsigned char* buf
, int count
)
170 fmradio_i2c_outb(address
& 0xfe);
171 if (fmradio_i2c_getack())
173 for (i
=0; i
<count
; i
++)
175 fmradio_i2c_outb(buf
[i
]);
176 if (!fmradio_i2c_getack())
185 logf("fmradio_i2c_write() - no ack\n");
192 int fmradio_i2c_read(unsigned char address
, unsigned char* buf
, int count
)
197 fmradio_i2c_outb(address
| 1);
199 if (fmradio_i2c_getack())
201 for (i
=count
; i
>0; i
--)
203 *buf
++ = fmradio_i2c_inb();
204 fmradio_i2c_ack(i
== 1);