Deleted Added
full compact
iicbb.c (188461) iicbb.c (228728)
1/*-
2 * Copyright (c) 1998, 2001 Nicolas Souchu
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1998, 2001 Nicolas Souchu
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/dev/iicbus/iicbb.c 188461 2009-02-10 22:50:23Z imp $");
28__FBSDID("$FreeBSD: head/sys/dev/iicbus/iicbb.c 228728 2011-12-20 02:49:01Z adrian $");
29
30/*
31 * Generic I2C bit-banging code
32 *
33 * Example:
34 *
35 * iicbus
36 * / \

--- 19 unchanged lines hidden (view full) ---

56
57#include <dev/smbus/smbconf.h>
58
59#include "iicbus_if.h"
60#include "iicbb_if.h"
61
62struct iicbb_softc {
63 device_t iicbus;
29
30/*
31 * Generic I2C bit-banging code
32 *
33 * Example:
34 *
35 * iicbus
36 * / \

--- 19 unchanged lines hidden (view full) ---

56
57#include <dev/smbus/smbconf.h>
58
59#include "iicbus_if.h"
60#include "iicbb_if.h"
61
62struct iicbb_softc {
63 device_t iicbus;
64 int udelay; /* signal toggle delay in usec */
64};
65
66static int iicbb_attach(device_t);
67static void iicbb_child_detached(device_t, device_t);
68static int iicbb_detach(device_t);
69static int iicbb_print_child(device_t, device_t);
70static int iicbb_probe(device_t);
71

--- 46 unchanged lines hidden (view full) ---

118static int
119iicbb_attach(device_t dev)
120{
121 struct iicbb_softc *sc = (struct iicbb_softc *)device_get_softc(dev);
122
123 sc->iicbus = device_add_child(dev, "iicbus", -1);
124 if (!sc->iicbus)
125 return (ENXIO);
65};
66
67static int iicbb_attach(device_t);
68static void iicbb_child_detached(device_t, device_t);
69static int iicbb_detach(device_t);
70static int iicbb_print_child(device_t, device_t);
71static int iicbb_probe(device_t);
72

--- 46 unchanged lines hidden (view full) ---

119static int
120iicbb_attach(device_t dev)
121{
122 struct iicbb_softc *sc = (struct iicbb_softc *)device_get_softc(dev);
123
124 sc->iicbus = device_add_child(dev, "iicbus", -1);
125 if (!sc->iicbus)
126 return (ENXIO);
127 sc->udelay = 10; /* 10 uS default */
126 bus_generic_attach(dev);
127
128 return (0);
129}
130
131static int
132iicbb_detach(device_t dev)
133{

--- 45 unchanged lines hidden (view full) ---

179
180 retval += printf(" on %s addr 0x%x\n",
181 device_get_nameunit(bus), oldaddr & 0xff);
182 }
183
184 return (retval);
185}
186
128 bus_generic_attach(dev);
129
130 return (0);
131}
132
133static int
134iicbb_detach(device_t dev)
135{

--- 45 unchanged lines hidden (view full) ---

181
182 retval += printf(" on %s addr 0x%x\n",
183 device_get_nameunit(bus), oldaddr & 0xff);
184 }
185
186 return (retval);
187}
188
187#define IIC_DELAY 10
188
189#define I2C_SETSDA(dev,val) do { \
189#define I2C_SETSDA(sc,dev,val) do { \
190 IICBB_SETSDA(device_get_parent(dev), val); \
190 IICBB_SETSDA(device_get_parent(dev), val); \
191 DELAY(IIC_DELAY); \
191 DELAY(sc->udelay); \
192 } while (0)
193
194#define I2C_SETSCL(dev,val) do { \
195 iicbb_setscl(dev, val, 100); \
196 } while (0)
197
192 } while (0)
193
194#define I2C_SETSCL(dev,val) do { \
195 iicbb_setscl(dev, val, 100); \
196 } while (0)
197
198#define I2C_SET(dev,ctrl,data) do { \
198#define I2C_SET(sc,dev,ctrl,data) do { \
199 I2C_SETSCL(dev, ctrl); \
199 I2C_SETSCL(dev, ctrl); \
200 I2C_SETSDA(dev, data); \
200 I2C_SETSDA(sc, dev, data); \
201 } while (0)
202
203#define I2C_GETSDA(dev) (IICBB_GETSDA(device_get_parent(dev)))
204
205#define I2C_GETSCL(dev) (IICBB_GETSCL(device_get_parent(dev)))
206
207static int i2c_debug = 0;
208#define I2C_DEBUG(x) do { \
209 if (i2c_debug) (x); \
210 } while (0)
211
212#define I2C_LOG(format,args...) do { \
213 printf(format, args); \
214 } while (0)
215
216static void
217iicbb_setscl(device_t dev, int val, int timeout)
218{
201 } while (0)
202
203#define I2C_GETSDA(dev) (IICBB_GETSDA(device_get_parent(dev)))
204
205#define I2C_GETSCL(dev) (IICBB_GETSCL(device_get_parent(dev)))
206
207static int i2c_debug = 0;
208#define I2C_DEBUG(x) do { \
209 if (i2c_debug) (x); \
210 } while (0)
211
212#define I2C_LOG(format,args...) do { \
213 printf(format, args); \
214 } while (0)
215
216static void
217iicbb_setscl(device_t dev, int val, int timeout)
218{
219 struct iicbb_softc *sc = device_get_softc(dev);
219 int k = 0;
220
221 IICBB_SETSCL(device_get_parent(dev), val);
220 int k = 0;
221
222 IICBB_SETSCL(device_get_parent(dev), val);
222 DELAY(IIC_DELAY);
223 DELAY(sc->udelay);
223
224 while (val && !I2C_GETSCL(dev) && k++ < timeout) {
225 IICBB_SETSCL(device_get_parent(dev), val);
224
225 while (val && !I2C_GETSCL(dev) && k++ < timeout) {
226 IICBB_SETSCL(device_get_parent(dev), val);
226 DELAY(IIC_DELAY);
227 DELAY(sc->udelay);
227 }
228 }
228
229
229 return;
230}
231
232static void
233iicbb_one(device_t dev, int timeout)
234{
230 return;
231}
232
233static void
234iicbb_one(device_t dev, int timeout)
235{
235 I2C_SET(dev,0,1);
236 I2C_SET(dev,1,1);
237 I2C_SET(dev,0,1);
236 struct iicbb_softc *sc = device_get_softc(dev);
237
238 I2C_SET(sc,dev,0,1);
239 I2C_SET(sc,dev,1,1);
240 I2C_SET(sc,dev,0,1);
238 return;
239}
240
241static void
242iicbb_zero(device_t dev, int timeout)
243{
241 return;
242}
243
244static void
245iicbb_zero(device_t dev, int timeout)
246{
244 I2C_SET(dev,0,0);
245 I2C_SET(dev,1,0);
246 I2C_SET(dev,0,0);
247 struct iicbb_softc *sc = device_get_softc(dev);
248
249 I2C_SET(sc,dev,0,0);
250 I2C_SET(sc,dev,1,0);
251 I2C_SET(sc,dev,0,0);
247 return;
248}
249
250/*
251 * Waiting for ACKNOWLEDGE.
252 *
253 * When a chip is being addressed or has received data it will issue an
254 * ACKNOWLEDGE pulse. Therefore the MASTER must release the DATA line

--- 4 unchanged lines hidden (view full) ---

259 * nothing.
260 *
261 * When the SLAVE has pulled this line low the MASTER will take the CLOCK
262 * line low and then the SLAVE will release the SDA (data) line.
263 */
264static int
265iicbb_ack(device_t dev, int timeout)
266{
252 return;
253}
254
255/*
256 * Waiting for ACKNOWLEDGE.
257 *
258 * When a chip is being addressed or has received data it will issue an
259 * ACKNOWLEDGE pulse. Therefore the MASTER must release the DATA line

--- 4 unchanged lines hidden (view full) ---

264 * nothing.
265 *
266 * When the SLAVE has pulled this line low the MASTER will take the CLOCK
267 * line low and then the SLAVE will release the SDA (data) line.
268 */
269static int
270iicbb_ack(device_t dev, int timeout)
271{
272 struct iicbb_softc *sc = device_get_softc(dev);
267 int noack;
268 int k = 0;
273 int noack;
274 int k = 0;
269
270 I2C_SET(dev,0,1);
271 I2C_SET(dev,1,1);
275
276 I2C_SET(sc,dev,0,1);
277 I2C_SET(sc,dev,1,1);
272 do {
273 noack = I2C_GETSDA(dev);
274 if (!noack)
275 break;
278 do {
279 noack = I2C_GETSDA(dev);
280 if (!noack)
281 break;
276 DELAY(10);
277 k += 10;
282 DELAY(1);
283 k++;
278 } while (k < timeout);
279
284 } while (k < timeout);
285
280 I2C_SET(dev,0,1);
286 I2C_SET(sc,dev,0,1);
281 I2C_DEBUG(printf("%c ",noack?'-':'+'));
282
283 return (noack);
284}
285
286static void
287iicbb_sendbyte(device_t dev, u_char data, int timeout)
288{

--- 8 unchanged lines hidden (view full) ---

297 }
298 I2C_DEBUG(printf("w%02x",(int)data));
299 return;
300}
301
302static u_char
303iicbb_readbyte(device_t dev, int last, int timeout)
304{
287 I2C_DEBUG(printf("%c ",noack?'-':'+'));
288
289 return (noack);
290}
291
292static void
293iicbb_sendbyte(device_t dev, u_char data, int timeout)
294{

--- 8 unchanged lines hidden (view full) ---

303 }
304 I2C_DEBUG(printf("w%02x",(int)data));
305 return;
306}
307
308static u_char
309iicbb_readbyte(device_t dev, int last, int timeout)
310{
311 struct iicbb_softc *sc = device_get_softc(dev);
305 int i;
306 unsigned char data=0;
312 int i;
313 unsigned char data=0;
307
308 I2C_SET(dev,0,1);
314
315 I2C_SET(sc,dev,0,1);
309 for (i=7; i>=0; i--)
310 {
316 for (i=7; i>=0; i--)
317 {
311 I2C_SET(dev,1,1);
318 I2C_SET(sc,dev,1,1);
312 if (I2C_GETSDA(dev))
313 data |= (1<<i);
319 if (I2C_GETSDA(dev))
320 data |= (1<<i);
314 I2C_SET(dev,0,1);
321 I2C_SET(sc,dev,0,1);
315 }
316 if (last) {
317 iicbb_one(dev, timeout);
318 } else {
319 iicbb_zero(dev, timeout);
320 }
321 I2C_DEBUG(printf("r%02x%c ",(int)data,last?'-':'+'));
322 return data;

--- 9 unchanged lines hidden (view full) ---

332iicbb_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
333{
334 return (IICBB_RESET(device_get_parent(dev), speed, addr, oldaddr));
335}
336
337static int
338iicbb_start(device_t dev, u_char slave, int timeout)
339{
322 }
323 if (last) {
324 iicbb_one(dev, timeout);
325 } else {
326 iicbb_zero(dev, timeout);
327 }
328 I2C_DEBUG(printf("r%02x%c ",(int)data,last?'-':'+'));
329 return data;

--- 9 unchanged lines hidden (view full) ---

339iicbb_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
340{
341 return (IICBB_RESET(device_get_parent(dev), speed, addr, oldaddr));
342}
343
344static int
345iicbb_start(device_t dev, u_char slave, int timeout)
346{
347 struct iicbb_softc *sc = device_get_softc(dev);
340 int error;
341
342 I2C_DEBUG(printf("<"));
343
348 int error;
349
350 I2C_DEBUG(printf("<"));
351
344 I2C_SET(dev,1,1);
345 I2C_SET(dev,1,0);
346 I2C_SET(dev,0,0);
352 I2C_SET(sc,dev,1,1);
353 I2C_SET(sc,dev,1,0);
354 I2C_SET(sc,dev,0,0);
347
348 /* send address */
349 iicbb_sendbyte(dev, slave, timeout);
350
351 /* check for ack */
352 if (iicbb_ack(dev, timeout)) {
353 error = IIC_ENOACK;
354 goto error;

--- 4 unchanged lines hidden (view full) ---

359error:
360 iicbb_stop(dev);
361 return (error);
362}
363
364static int
365iicbb_stop(device_t dev)
366{
355
356 /* send address */
357 iicbb_sendbyte(dev, slave, timeout);
358
359 /* check for ack */
360 if (iicbb_ack(dev, timeout)) {
361 error = IIC_ENOACK;
362 goto error;

--- 4 unchanged lines hidden (view full) ---

367error:
368 iicbb_stop(dev);
369 return (error);
370}
371
372static int
373iicbb_stop(device_t dev)
374{
367 I2C_SET(dev,0,0);
368 I2C_SET(dev,1,0);
369 I2C_SET(dev,1,1);
375 struct iicbb_softc *sc = device_get_softc(dev);
376
377 I2C_SET(sc,dev,0,0);
378 I2C_SET(sc,dev,1,0);
379 I2C_SET(sc,dev,1,1);
370 I2C_DEBUG(printf(">"));
380 I2C_DEBUG(printf(">"));
381 I2C_DEBUG(printf("\n"));
371 return (0);
372}
373
374static int
375iicbb_write(device_t dev, const char *buf, int len, int *sent, int timeout)
376{
377 int bytes, error = 0;
378

--- 41 unchanged lines hidden ---
382 return (0);
383}
384
385static int
386iicbb_write(device_t dev, const char *buf, int len, int *sent, int timeout)
387{
388 int bytes, error = 0;
389

--- 41 unchanged lines hidden ---