Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / AHI / Drivers / Envy24HT / I2C.c
blobe7e24f06741013d9673277d30ed5be6d94c57bbb
1 /*
2 Copyright © 2005-2013, Davy Wentzler. All rights reserved.
3 $Id$
4 */
6 #include <proto/exec.h>
7 #include "I2C.h"
8 #include "DriverData.h"
9 #include "pci_wrapper.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);
15 #ifdef __MORPHOS__
16 extern struct DriverBase* AHIsubBase;
17 #endif
19 struct I2C *AllocI2C(unsigned char addr)
21 struct I2C *device;
23 device = (struct I2C *) ALLOCVEC(sizeof(struct I2C), MEMF_CLEAR);
24 if (device == NULL)
25 return NULL;
27 device->addr = addr;
28 device->flags = 0;
30 return device;
34 void FreeI2C(struct I2C *device)
36 FREEVEC(device);
40 int WriteBytesI2C(struct CardData *card, struct I2C *device, unsigned char *bytes, int count)
42 return I2C_bit_sendbytes(card, device, bytes, count);
46 int ReadBytesI2C(struct CardData *card, struct I2C *device, unsigned char *bytes, int count)
48 return I2C_bit_readbytes(card, device, bytes, count);
52 int ProbeAddressI2C(struct CardData *card, unsigned short addr)
54 return I2C_bit_probeaddr(card, addr);
60 // Let the specific chip set up GPIO dir and mask for example
61 // before we start feeding bits and bytes...
62 static inline void I2C_bit_hw_start(struct CardData *card)
64 if (card->bit_ops->Start)
65 card->bit_ops->Start(card);
69 static inline void I2C_bit_hw_stop(struct CardData *card)
71 if (card->bit_ops->Stop)
72 card->bit_ops->Stop(card);
76 static void I2C_bit_direction(struct CardData *card, int clock, int data)
78 if (card->bit_ops->SetDir_CLK_SDA)
79 card->bit_ops->SetDir_CLK_SDA(card, clock, data);
83 static void I2C_bit_set(struct CardData *card, int clock, int data)
85 card->bit_ops->Write_CLK_SDA(card, clock, data);
90 static int I2C_bit_data(struct CardData *card, int ack)
92 return card->bit_ops->GetData(card, ack);
97 // See page 17 and 18 of the I2C spec, version 2.1 January 2000,
98 // especially, figure 18 (START byte procedure)
99 static void I2C_bit_start(struct CardData *card)
101 // chip-specific init
102 I2C_bit_hw_start(card);
104 // we're gonna write to both
105 I2C_bit_direction(card, 1, 1);
106 I2C_bit_set(card, 1, 1);
107 I2C_bit_set(card, 1, 0);
108 I2C_bit_set(card, 0, 0);
112 // see figure 10 and 19
113 static void I2C_bit_stop(struct CardData *card)
115 I2C_bit_set(card, 0, 0);
116 I2C_bit_set(card, 1, 0);
117 I2C_bit_set(card, 1, 1);
119 // chip-specific stop
120 I2C_bit_hw_stop(card);
124 // data gets send on high clock
125 static void I2C_bit_send(struct CardData *card, int data)
127 I2C_bit_set(card, 0, data);
128 I2C_bit_set(card, 1, data);
129 I2C_bit_set(card, 0, data);
133 static int I2C_bit_ack(struct CardData *card)
135 int ack;
137 // figure 7
138 I2C_bit_set(card, 0, 1);
139 I2C_bit_set(card, 1, 1);
141 // then read the ack bit
142 I2C_bit_direction(card, 1, 0);
143 ack = I2C_bit_data(card, 1);
146 I2C_bit_direction(card, 1, 1);
147 I2C_bit_set(card, 0, 1);
149 return ack;
153 static int I2C_bit_sendbyte(struct CardData *card, unsigned char data)
155 int i, err;
157 // send the byte bit for bit, MSB first
158 for (i = 7; i >= 0; i--)
159 I2C_bit_send(card, (data & (1 << i)));
161 if ((err = I2C_bit_ack(card)) < 0)
162 return err;
164 return 0;
168 static int I2C_bit_readbyte(struct CardData *card, int last)
170 int i;
171 unsigned char data = 0;
173 I2C_bit_set(card, 0, 1);
174 I2C_bit_direction(card, 1, 0);
176 for (i = 7; i >= 0; i--) {
177 I2C_bit_set(card, 1, 1);
179 if (I2C_bit_data(card, 0))
180 data |= (1 << i);
182 I2C_bit_set(card, 0, 1);
185 I2C_bit_direction(card, 1, 1);
186 I2C_bit_send(card, last);
188 return data;
192 static int I2C_bit_sendbytes(struct CardData *card, struct I2C *device, unsigned char *bytes, int count)
194 int err, res = 0;
196 I2C_bit_start(card);
198 // first send address of the I2C chip we want to reach
199 if ((err = I2C_bit_sendbyte(card, device->addr << 1)) < 0) {
200 I2C_bit_hw_stop(card);
201 return err;
204 // then send all consecutive bytes with an 'ack' in between
205 while (count-- > 0) {
206 if ((err = I2C_bit_sendbyte(card, *bytes++)) < 0) {
207 I2C_bit_hw_stop(card);
208 return err;
211 res++;
214 I2C_bit_stop(card);
216 return res;
220 static int I2C_bit_readbytes(struct CardData *card, struct I2C *device, unsigned char *bytes, int count)
222 int err, res = 0;
224 I2C_bit_start(card);
226 if ((err = I2C_bit_sendbyte(card, (device->addr << 1) | 1)) < 0) {
227 I2C_bit_hw_stop(card);
228 return err;
231 while (count-- > 0) {
232 if ((err = I2C_bit_readbyte(card, count == 0)) < 0) {
233 I2C_bit_hw_stop(card);
234 return err;
237 *bytes++ = (unsigned char)err;
238 res++;
241 I2C_bit_stop(card);
243 return res;
247 static int I2C_bit_probeaddr(struct CardData *card, unsigned short addr)
249 int err;
251 I2C_bit_start(card);
252 err = I2C_bit_sendbyte(card, addr << 1);
253 I2C_bit_stop(card);
255 return err;