summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/coldfire/iaudio/x5/fmradio_i2c-x5.c37
-rw-r--r--firmware/target/coldfire/iriver/fmradio_i2c-iriver.c242
-rw-r--r--firmware/target/sh/archos/ondio/fmradio_i2c-ondio.c197
3 files changed, 476 insertions, 0 deletions
diff --git a/firmware/target/coldfire/iaudio/x5/fmradio_i2c-x5.c b/firmware/target/coldfire/iaudio/x5/fmradio_i2c-x5.c
new file mode 100644
index 0000000000..6ee670f9fe
--- /dev/null
+++ b/firmware/target/coldfire/iaudio/x5/fmradio_i2c-x5.c
@@ -0,0 +1,37 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 * Physical interface of the Philips TEA5767 in iAudio x5
10 *
11 * Copyright (C) 2002 by Linus Nielsen Feltzing
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20#include "config.h"
21
22#if (CONFIG_TUNER & TEA5767)
23
24#include "i2c-coldfire.h"
25
26int fmradio_i2c_write(unsigned char address, const unsigned char* buf,
27 int count)
28{
29 return i2c_write(I2C_IFACE_0, address, buf, count);
30}
31
32int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count)
33{
34 return i2c_read(I2C_IFACE_0, address, buf, count);
35}
36
37#endif
diff --git a/firmware/target/coldfire/iriver/fmradio_i2c-iriver.c b/firmware/target/coldfire/iriver/fmradio_i2c-iriver.c
new file mode 100644
index 0000000000..7c431dae2b
--- /dev/null
+++ b/firmware/target/coldfire/iriver/fmradio_i2c-iriver.c
@@ -0,0 +1,242 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 * Physical interface of the Philips TEA5767 in iriver H100/H300 series
10 *
11 * Copyright (C) 2002 by Linus Nielsen Feltzing
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20#include "config.h"
21#include "cpu.h"
22#include "logf.h"
23#include "system.h"
24
25#if (CONFIG_TUNER & TEA5767)
26
27/* cute little functions, atomic read-modify-write */
28/* SDA is GPIO1,23 */
29
30#ifdef IRIVER_H300_SERIES
31
32/* SDA is GPIO57 */
33#define SDA_OUTINIT and_l(~0x02000000, &GPIO1_OUT)
34#define SDA_HI_IN and_l(~0x02000000, &GPIO1_ENABLE)
35#define SDA_LO_OUT or_l( 0x02000000, &GPIO1_ENABLE)
36#define SDA ( 0x02000000 & GPIO1_READ)
37
38/* SCL is GPIO56 */
39#define SCL_INPUT and_l(~0x01000000, &GPIO1_ENABLE)
40#define SCL_OUTPUT or_l( 0x01000000, &GPIO1_ENABLE)
41#define SCL_LO and_l(~0x01000000, &GPIO1_OUT)
42#define SCL_HI or_l( 0x01000000, &GPIO1_OUT)
43#define SCL ( 0x01000000 & GPIO1_READ)
44
45#else
46
47/* SDA is GPIO55 */
48#define SDA_OUTINIT and_l(~0x00800000, &GPIO1_OUT)
49#define SDA_HI_IN and_l(~0x00800000, &GPIO1_ENABLE)
50#define SDA_LO_OUT or_l( 0x00800000, &GPIO1_ENABLE)
51#define SDA ( 0x00800000 & GPIO1_READ)
52
53/* SCL is GPIO3 */
54#define SCL_INPUT and_l(~0x00000008, &GPIO_ENABLE)
55#define SCL_OUTPUT or_l( 0x00000008, &GPIO_ENABLE)
56#define SCL_LO and_l(~0x00000008, &GPIO_OUT)
57#define SCL_HI or_l( 0x00000008, &GPIO_OUT)
58#define SCL ( 0x00000008 & GPIO_READ)
59#endif
60
61/* delay loop to achieve 400kHz at 120MHz CPU frequency */
62#define DELAY \
63 ({ \
64 int _x_; \
65 asm volatile ( \
66 "move.l #21, %[_x_] \r\n" \
67 "1: \r\n" \
68 "subq.l #1, %[_x_] \r\n" \
69 "bhi.b 1b \r\n" \
70 : [_x_]"=&d"(_x_) \
71 ); \
72 })
73
74static void fmradio_i2c_start(void)
75{
76 SCL_HI;
77 SCL_OUTPUT;
78 SDA_HI_IN;
79 SDA_OUTINIT;
80 DELAY;
81 SDA_LO_OUT;
82 DELAY;
83 SCL_LO;
84}
85
86static void fmradio_i2c_stop(void)
87{
88 SDA_LO_OUT;
89 DELAY;
90 SCL_HI;
91 DELAY;
92 SDA_HI_IN;
93}
94
95/* Generate ACK or NACK */
96static void fmradio_i2c_ack(bool nack)
97{
98 /* Here's the deal. The slave is slow, and sometimes needs to wait
99 before it can receive 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 release the ack.
102
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. */
105
106 if (nack)
107 SDA_HI_IN;
108 else
109 SDA_LO_OUT;
110 DELAY;
111
112 SCL_HI;
113 do
114 {
115 SCL_OUTPUT; /* Set the clock to output */
116 SCL_INPUT; /* Set the clock to input */
117 DELAY;
118 }
119 while(!SCL); /* and wait for the slave to release it */
120
121 SCL_OUTPUT;
122 SCL_LO;
123}
124
125static int fmradio_i2c_getack(void)
126{
127 int ret = 1;
128
129 /* Here's the deal. The slave is slow, and sometimes needs to wait
130 before it can send the acknowledge. Therefore it forces the clock
131 low until it is ready. We need to poll the clock line until it goes
132 high before we read the ack.
133
134 In their infinite wisdom, iriver didn't pull up the SCL line, so
135 we have to drive the SCL high repeatedly to simulate a pullup. */
136
137 SDA_HI_IN;
138 DELAY;
139
140 SCL_HI; /* set clock to high */
141 do
142 {
143 SCL_OUTPUT; /* Set the clock to output */
144 SCL_INPUT; /* Set the clock to input */
145 DELAY;
146 }
147 while(!SCL); /* and wait for the slave to release it */
148
149 if (SDA)
150 ret = 0; /* ack failed */
151
152 SCL_OUTPUT;
153 SCL_LO;
154
155 return ret;
156}
157
158static void fmradio_i2c_outb(unsigned char byte)
159{
160 int i;
161
162 /* clock out each bit, MSB first */
163 for ( i=0x80; i; i>>=1 ) {
164 if ( i & byte )
165 SDA_HI_IN;
166 else
167 SDA_LO_OUT;
168 DELAY;
169 SCL_HI;
170 DELAY;
171 SCL_LO;
172 }
173}
174
175static unsigned char fmradio_i2c_inb(void)
176{
177 int i;
178 unsigned char byte = 0;
179
180 SDA_HI_IN;
181 /* clock in each bit, MSB first */
182 for ( i=0x80; i; i>>=1 ) {
183 DELAY;
184 SCL_HI;
185 DELAY;
186 if ( SDA )
187 byte |= i;
188 SCL_LO;
189 }
190
191 return byte;
192}
193
194int fmradio_i2c_write(int address, const unsigned char* buf, int count)
195{
196 int i,x=0;
197
198 fmradio_i2c_start();
199 fmradio_i2c_outb(address & 0xfe);
200 if (fmradio_i2c_getack())
201 {
202 for (i=0; i<count; i++)
203 {
204 fmradio_i2c_outb(buf[i]);
205 if (!fmradio_i2c_getack())
206 {
207 x=-2;
208 break;
209 }
210 }
211 }
212 else
213 {
214 logf("fmradio_i2c_write() - no ack\n");
215 x=-1;
216 }
217 fmradio_i2c_stop();
218 return x;
219}
220
221int fmradio_i2c_read(int address, unsigned char* buf, int count)
222{
223 int i,x=0;
224
225 fmradio_i2c_start();
226 fmradio_i2c_outb(address | 1);
227
228 if (fmradio_i2c_getack())
229 {
230 for (i=count; i>0; i--)
231 {
232 *buf++ = fmradio_i2c_inb();
233 fmradio_i2c_ack(i == 1);
234 }
235 }
236 else
237 x=-1;
238 fmradio_i2c_stop();
239 return x;
240}
241
242#endif
diff --git a/firmware/target/sh/archos/ondio/fmradio_i2c-ondio.c b/firmware/target/sh/archos/ondio/fmradio_i2c-ondio.c
new file mode 100644
index 0000000000..f62797480a
--- /dev/null
+++ b/firmware/target/sh/archos/ondio/fmradio_i2c-ondio.c
@@ -0,0 +1,197 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 * Physical interface of the Philips TEA5767 in Archos Ondio
10 *
11 * Copyright (C) 2002 by Linus Nielsen Feltzing
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20#include "config.h"
21#include "cpu.h"
22#include "logf.h"
23#include "system.h"
24
25#if (CONFIG_TUNER & TEA5767)
26
27/* cute little functions, atomic read-modify-write */
28/* SDA is PB4 */
29#define SDA_LO and_b(~0x10, &PBDRL)
30#define SDA_HI or_b(0x10, &PBDRL)
31#define SDA_INPUT and_b(~0x10, &PBIORL)
32#define SDA_OUTPUT or_b(0x10, &PBIORL)
33#define SDA (PBDR & 0x0010)
34
35/* SCL is PB1 */
36#define SCL_INPUT and_b(~0x02, &PBIORL)
37#define SCL_OUTPUT or_b(0x02, &PBIORL)
38#define SCL_LO and_b(~0x02, &PBDRL)
39#define SCL_HI or_b(0x02, &PBDRL)
40#define SCL (PBDR & 0x0002)
41
42/* arbitrary delay loop */
43#define DELAY do { int _x; for(_x=0;_x<20;_x++);} while (0)
44
45static void fmradio_i2c_start(void)
46{
47 SDA_OUTPUT;
48 SDA_HI;
49 SCL_HI;
50 SDA_LO;
51 DELAY;
52 SCL_LO;
53}
54
55static void fmradio_i2c_stop(void)
56{
57 SDA_LO;
58 SCL_HI;
59 DELAY;
60 SDA_HI;
61}
62
63
64static void fmradio_i2c_ack(bool nack)
65{
66 /* Here's the deal. The slave is slow, and sometimes needs to wait
67 before it can receive the acknowledge. Therefore it forces the clock
68 low until it is ready. We need to poll the clock line until it goes
69 high before we release the ack. */
70
71 SCL_LO; /* Set the clock low */
72
73 if (nack)
74 SDA_HI;
75 else
76 SDA_LO;
77
78 SCL_INPUT; /* Set the clock to input */
79 while(!SCL) /* and wait for the slave to release it */
80 sleep_thread(0);
81
82 DELAY;
83 SCL_OUTPUT;
84 SCL_LO;
85}
86
87static int fmradio_i2c_getack(void)
88{
89 int ret = 1;
90
91 /* Here's the deal. The slave is slow, and sometimes needs to wait
92 before it can send the acknowledge. Therefore it forces the clock
93 low until it is ready. We need to poll the clock line until it goes
94 high before we read the ack. */
95
96 SDA_INPUT; /* And set to input */
97 SCL_INPUT; /* Set the clock to input */
98 while(!SCL) /* and wait for the slave to release it */
99 sleep_thread(0);
100
101 if (SDA)
102 /* ack failed */
103 ret = 0;
104
105 SCL_OUTPUT;
106 SCL_LO;
107 SDA_HI;
108 SDA_OUTPUT;
109 return ret;
110}
111
112static void fmradio_i2c_outb(unsigned char byte)
113{
114 int i;
115
116 /* clock out each bit, MSB first */
117 for ( i=0x80; i; i>>=1 ) {
118 if ( i & byte )
119 {
120 SDA_HI;
121 }
122 else
123 {
124 SDA_LO;
125 }
126 SCL_HI;
127 SCL_LO;
128 }
129
130 SDA_HI;
131}
132
133static unsigned char fmradio_i2c_inb(void)
134{
135 int i;
136 unsigned char byte = 0;
137
138 /* clock in each bit, MSB first */
139 for ( i=0x80; i; i>>=1 ) {
140 SDA_INPUT; /* And set to input */
141 SCL_HI;
142 if ( SDA )
143 byte |= i;
144 SCL_LO;
145 SDA_OUTPUT;
146 }
147
148 return byte;
149}
150
151int fmradio_i2c_write(int address, const unsigned char* buf, int count)
152{
153 int i,x=0;
154
155 fmradio_i2c_start();
156 fmradio_i2c_outb(address & 0xfe);
157 if (fmradio_i2c_getack())
158 {
159 for (i=0; i<count; i++)
160 {
161 fmradio_i2c_outb(buf[i]);
162 if (!fmradio_i2c_getack())
163 {
164 x=-2;
165 break;
166 }
167 }
168 }
169 else
170 {
171 logf("fmradio_i2c_write() - no ack\n");
172 x=-1;
173 }
174 fmradio_i2c_stop();
175 return x;
176}
177
178int fmradio_i2c_read(int address, unsigned char* buf, int count)
179{
180 int i,x=0;
181
182 fmradio_i2c_start();
183 fmradio_i2c_outb(address | 1);
184 if (fmradio_i2c_getack()) {
185 for (i=count; i>0; i--)
186 {
187 *buf++ = fmradio_i2c_inb();
188 fmradio_i2c_ack(i == 1);
189 }
190 }
191 else
192 x=-1;
193 fmradio_i2c_stop();
194 return x;
195}
196
197#endif