summaryrefslogtreecommitdiff
path: root/firmware/target/sh
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/sh')
-rw-r--r--firmware/target/sh/archos/ondio/fmradio_i2c-ondio.c197
1 files changed, 197 insertions, 0 deletions
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