grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / devs / AHI / Drivers / Envy24 / I2C.c
blob9e1ba1cd7a44eb04f7130f48b4bfc93c6fe8e5d2
1 /*
2 Copyright © 2004-2014, Davy Wentzler. All rights reserved.
3 $Id$
4 */
6 #include <proto/exec.h>
7 #include "I2C.h"
8 #include "DriverData.h"
11 static int I2C_bit_sendbytes(struct CardData *card, struct I2C *device, unsigned char *bytes, int count);
12 static int I2C_bit_readbytes(struct CardData *card, struct I2C *device, unsigned char *bytes, int count);
13 static int I2C_bit_probeaddr(struct CardData *card, unsigned short addr);
16 struct I2C *AllocI2C(unsigned char addr)
18 struct I2C *device;
20 device = (struct I2C *) AllocVec(sizeof(struct I2C), MEMF_ANY);
21 if (device == NULL)
22 return NULL;
24 device->addr = addr;
25 device->flags = 0;
27 return device;
31 void FreeI2C(struct I2C *device)
33 FreeVec(device);
37 int WriteBytesI2C(struct CardData *card, struct I2C *device, unsigned char *bytes, int count)
39 return I2C_bit_sendbytes(card, device, bytes, count);
43 int ReadBytesI2C(struct CardData *card, struct I2C *device, unsigned char *bytes, int count)
45 return I2C_bit_readbytes(card, device, bytes, count);
49 int ProbeAddressI2C(struct CardData *card, unsigned short addr)
51 return I2C_bit_probeaddr(card, addr);
57 // Let the specific chip set up GPIO dir and mask for example
58 // before we start feeding bits and bytes...
59 static inline void I2C_bit_hw_start(struct CardData *card)
61 if (card->bit_ops->Start)
62 card->bit_ops->Start(card);
66 static inline void I2C_bit_hw_stop(struct CardData *card)
68 if (card->bit_ops->Stop)
69 card->bit_ops->Stop(card);
73 static void I2C_bit_direction(struct CardData *card, int clock, int data)
75 if (card->bit_ops->SetDir_CLK_SDA)
76 card->bit_ops->SetDir_CLK_SDA(card, clock, data);
80 static void I2C_bit_set(struct CardData *card, int clock, int data)
82 card->bit_ops->Write_CLK_SDA(card, clock, data);
86 static int I2C_bit_data(struct CardData *card, int ack)
88 return card->bit_ops->GetData(card, ack);
93 // See page 17 and 18 of the I2C spec, version 2.1 January 2000,
94 // especially, figure 18 (START byte procedure)
95 static void I2C_bit_start(struct CardData *card)
97 // chip-specific init
98 I2C_bit_hw_start(card);
100 // we're gonna write to both
101 I2C_bit_direction(card, 1, 1);
102 I2C_bit_set(card, 1, 1);
103 I2C_bit_set(card, 1, 0);
104 I2C_bit_set(card, 0, 0);
108 // see figure 10 and 19
109 static void I2C_bit_stop(struct CardData *card)
111 I2C_bit_set(card, 0, 0);
112 I2C_bit_set(card, 1, 0);
113 I2C_bit_set(card, 1, 1);
115 // chip-specific stop
116 I2C_bit_hw_stop(card);
120 // data gets send on high clock
121 static void I2C_bit_send(struct CardData *card, int data)
123 I2C_bit_set(card, 0, data);
124 I2C_bit_set(card, 1, data);
125 I2C_bit_set(card, 0, data);
129 static int I2C_bit_ack(struct CardData *card)
131 int ack;
133 // figure 7
134 I2C_bit_set(card, 0, 1);
135 I2C_bit_set(card, 1, 1);
137 // then read the ack bit
138 I2C_bit_direction(card, 1, 0);
139 ack = I2C_bit_data(card, 1);
142 I2C_bit_direction(card, 1, 1);
143 I2C_bit_set(card, 0, 1);
145 return ack;
149 static int I2C_bit_sendbyte(struct CardData *card, unsigned char data)
151 int i, err;
153 // send the byte bit for bit, MSB first
154 for (i = 7; i >= 0; i--)
155 I2C_bit_send(card, (data & (1 << i)));
157 if ((err = I2C_bit_ack(card)) < 0)
158 return err;
160 return 0;
164 static int I2C_bit_readbyte(struct CardData *card, int last)
166 int i;
167 unsigned char data = 0;
169 I2C_bit_set(card, 0, 1);
170 I2C_bit_direction(card, 1, 0);
172 for (i = 7; i >= 0; i--) {
173 I2C_bit_set(card, 1, 1);
175 if (I2C_bit_data(card, 0))
176 data |= (1 << i);
178 I2C_bit_set(card, 0, 1);
181 I2C_bit_direction(card, 1, 1);
182 I2C_bit_send(card, last);
184 return data;
188 static int I2C_bit_sendbytes(struct CardData *card, struct I2C *device, unsigned char *bytes, int count)
190 int err, res = 0;
192 I2C_bit_start(card);
194 // first send address of the I2C chip we want to reach
195 if ((err = I2C_bit_sendbyte(card, device->addr << 1)) < 0) {
196 I2C_bit_hw_stop(card);
197 return err;
200 // then send all consecutive bytes with an 'ack' in between
201 while (count-- > 0) {
202 if ((err = I2C_bit_sendbyte(card, *bytes++)) < 0) {
203 I2C_bit_hw_stop(card);
204 return err;
207 res++;
210 I2C_bit_stop(card);
212 return res;
216 static int I2C_bit_readbytes(struct CardData *card, struct I2C *device, unsigned char *bytes, int count)
218 int err, res = 0;
220 I2C_bit_start(card);
222 if ((err = I2C_bit_sendbyte(card, (device->addr << 1) | 1)) < 0) {
223 I2C_bit_hw_stop(card);
224 return err;
227 while (count-- > 0) {
228 if ((err = I2C_bit_readbyte(card, count == 0)) < 0) {
229 I2C_bit_hw_stop(card);
230 return err;
233 *bytes++ = (unsigned char)err;
234 res++;
237 I2C_bit_stop(card);
239 return res;
243 static int I2C_bit_probeaddr(struct CardData *card, unsigned short addr)
245 int err;
247 I2C_bit_start(card);
248 err = I2C_bit_sendbyte(card, addr << 1);
249 I2C_bit_stop(card);
251 return err;