YUV Dither: r12 saving was removed but stacked parameter load offset wasn't changed...
[kugel-rb.git] / firmware / target / arm / iriver / h10 / fmradio_i2c-h10.c
blobbee1c6ebfb429f5e7014e6ac971620458d933e60
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
22 #include "config.h"
23 #include "cpu.h"
24 #include "logf.h"
25 #include "system.h"
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)
45 SCL_HI;
46 SCL_OUTPUT;
47 SDA_HI_IN;
48 SDA_OUTINIT;
49 DELAY;
50 SDA_LO_OUT;
51 DELAY;
52 SCL_LO;
55 static void fmradio_i2c_stop(void)
57 SDA_LO_OUT;
58 DELAY;
59 SCL_HI;
60 DELAY;
61 SDA_HI_IN;
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. */
75 if (nack)
76 SDA_HI_IN;
77 else
78 SDA_LO_OUT;
79 DELAY;
81 SCL_HI;
84 SCL_OUTPUT; /* Set the clock to output */
85 SCL_INPUT; /* Set the clock to input */
86 DELAY;
88 while(!SCL); /* and wait for the slave to release it */
90 SCL_OUTPUT;
91 SCL_LO;
94 static int fmradio_i2c_getack(void)
96 int ret = 1;
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. */
106 SDA_HI_IN;
107 DELAY;
109 SCL_HI; /* set clock to high */
112 SCL_OUTPUT; /* Set the clock to output */
113 SCL_INPUT; /* Set the clock to input */
114 DELAY;
116 while(!SCL); /* and wait for the slave to release it */
118 if (SDA)
119 ret = 0; /* ack failed */
121 SCL_OUTPUT;
122 SCL_LO;
124 return ret;
127 static void fmradio_i2c_outb(unsigned char byte)
129 int i;
131 /* clock out each bit, MSB first */
132 for ( i=0x80; i; i>>=1 ) {
133 if ( i & byte )
134 SDA_HI_IN;
135 else
136 SDA_LO_OUT;
137 DELAY;
138 SCL_HI;
139 DELAY;
140 SCL_LO;
142 DELAY;
146 static unsigned char fmradio_i2c_inb(void)
148 int i;
149 unsigned char byte = 0;
151 SDA_HI_IN;
152 /* clock in each bit, MSB first */
153 for ( i=0x80; i; i>>=1 ) {
154 DELAY;
155 SCL_HI;
156 DELAY;
157 if ( SDA )
158 byte |= i;
159 SCL_LO;
162 return byte;
165 int fmradio_i2c_write(unsigned char address, const unsigned char* buf, int count)
167 int i,x=0;
169 fmradio_i2c_start();
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())
178 x=-2;
179 break;
183 else
185 logf("fmradio_i2c_write() - no ack\n");
186 x=-1;
188 fmradio_i2c_stop();
189 return x;
192 int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count)
194 int i,x=0;
196 fmradio_i2c_start();
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);
207 else
208 x=-1;
209 fmradio_i2c_stop();
210 return x;