summaryrefslogtreecommitdiff
path: root/firmware/target/arm/i2c-telechips.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/i2c-telechips.c')
-rw-r--r--firmware/target/arm/i2c-telechips.c187
1 files changed, 187 insertions, 0 deletions
diff --git a/firmware/target/arm/i2c-telechips.c b/firmware/target/arm/i2c-telechips.c
new file mode 100644
index 0000000000..e3e8fd3d33
--- /dev/null
+++ b/firmware/target/arm/i2c-telechips.c
@@ -0,0 +1,187 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by Rob Purchase
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
21#include "system.h"
22#include "i2c.h"
23#include "i2c-target.h"
24
25/* arbitrary delay loop */
26#define DELAY do { int _x; for(_x=0;_x<20;_x++);} while (0)
27
28static struct mutex i2c_mtx;
29
30void i2c_init(void)
31{
32 /* nothing to do */
33}
34
35void i2c_start(void)
36{
37 SDA_OUTPUT;
38
39 SCL_HI;
40 SDA_HI;
41 DELAY;
42
43 SDA_LO;
44 DELAY;
45 SCL_LO;
46 DELAY;
47}
48
49void i2c_stop(void)
50{
51 SDA_OUTPUT;
52
53 SDA_LO;
54 DELAY;
55
56 SCL_HI;
57 DELAY;
58 SDA_HI;
59 DELAY;
60}
61
62void i2c_outb(unsigned char byte)
63{
64 int bit;
65
66 SDA_OUTPUT;
67
68 for (bit = 0; bit < 8; bit++)
69 {
70 if ((byte<<bit) & 0x80)
71 SDA_HI;
72 else
73 SDA_LO;
74
75 DELAY;
76
77 SCL_HI;
78 DELAY;
79 SCL_LO;
80 DELAY;
81 }
82}
83
84unsigned char i2c_inb(int ack)
85{
86 int i;
87 unsigned char byte = 0;
88
89 SDA_INPUT;
90
91 /* clock in each bit, MSB first */
92 for ( i=0x80; i; i>>=1 )
93 {
94 SCL_HI;
95 DELAY;
96
97 if ( SDA ) byte |= i;
98
99 SCL_LO;
100 DELAY;
101 }
102
103 i2c_ack(ack);
104 return byte;
105}
106
107void i2c_ack(int bit)
108{
109 SDA_OUTPUT;
110
111 if (bit)
112 SDA_HI;
113 else
114 SDA_LO;
115
116 SCL_HI;
117 DELAY;
118 SCL_LO;
119 DELAY;
120}
121
122int i2c_getack(void)
123{
124 bool ack_bit;
125
126 SDA_INPUT;
127
128 SCL_HI;
129 DELAY;
130
131 ack_bit = SDA;
132 DELAY;
133
134 SCL_LO;
135 DELAY;
136
137 return ack_bit;
138}
139
140/* device = 8 bit slave address */
141int i2c_write(int device, unsigned char* buf, int count )
142{
143 int i = 0;
144 mutex_lock(&i2c_mtx);
145
146 i2c_start();
147 i2c_outb(device & 0xfe);
148
149 while (!i2c_getack() && i < count)
150 {
151 i2c_outb(buf[i++]);
152 }
153
154 i2c_stop();
155 mutex_unlock(&i2c_mtx);
156 return 0;
157}
158
159
160/* device = 8 bit slave address */
161int i2c_readmem(int device, int address, unsigned char* buf, int count )
162{
163 int i = 0;
164 mutex_lock(&i2c_mtx);
165
166 i2c_start();
167 i2c_outb(device & 0xfe);
168 if (i2c_getack()) goto exit;
169
170 i2c_outb(address);
171 if (i2c_getack()) goto exit;
172
173 i2c_start();
174 i2c_outb(device | 1);
175 if (i2c_getack()) goto exit;
176
177 while (i < count)
178 {
179 buf[i] = i2c_inb(i == (count-1));
180 i++;
181 }
182
183exit:
184 i2c_stop();
185 mutex_unlock(&i2c_mtx);
186 return 0;
187}