]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/iicbus/iicbb.c
Merge bmake-20200517
[FreeBSD/FreeBSD.git] / sys / dev / iicbus / iicbb.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 1998, 2001 Nicolas Souchu
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 /*
33  * Generic I2C bit-banging code
34  *
35  * Example:
36  *
37  *      iicbus
38  *       /  \ 
39  *    iicbb pcf
40  *     |  \
41  *   bti2c lpbb
42  *
43  * From Linux I2C generic interface
44  * (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
45  *
46  */
47
48 #include "opt_platform.h"
49
50 #include <sys/param.h>
51 #include <sys/kernel.h>
52 #include <sys/systm.h>
53 #include <sys/module.h>
54 #include <sys/bus.h>
55 #include <sys/sysctl.h>
56 #include <sys/uio.h>
57
58 #ifdef FDT
59 #include <dev/ofw/ofw_bus.h>
60 #include <dev/ofw/ofw_bus_subr.h>
61 #include <dev/fdt/fdt_common.h>
62 #endif
63
64 #include <dev/iicbus/iiconf.h>
65 #include <dev/iicbus/iicbus.h>
66
67 #include <dev/smbus/smbconf.h>
68
69 #include "iicbus_if.h"
70 #include "iicbb_if.h"
71
72 /* Based on the SMBus specification. */
73 #define DEFAULT_SCL_LOW_TIMEOUT (25 * 1000)
74
75 struct iicbb_softc {
76         device_t iicbus;
77         u_int udelay;           /* signal toggle delay in usec */
78         u_int scl_low_timeout;
79 };
80
81 static int iicbb_attach(device_t);
82 static void iicbb_child_detached(device_t, device_t);
83 static int iicbb_detach(device_t);
84 static int iicbb_print_child(device_t, device_t);
85 static int iicbb_probe(device_t);
86
87 static int iicbb_callback(device_t, int, caddr_t);
88 static int iicbb_start(device_t, u_char, int);
89 static int iicbb_stop(device_t);
90 static int iicbb_write(device_t, const char *, int, int *, int);
91 static int iicbb_read(device_t, char *, int, int *, int, int);
92 static int iicbb_reset(device_t, u_char, u_char, u_char *);
93 static int iicbb_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs);
94 static void iicbb_set_speed(struct iicbb_softc *sc, u_char);
95 #ifdef FDT
96 static phandle_t iicbb_get_node(device_t, device_t);
97 #endif
98
99 static device_method_t iicbb_methods[] = {
100         /* device interface */
101         DEVMETHOD(device_probe,         iicbb_probe),
102         DEVMETHOD(device_attach,        iicbb_attach),
103         DEVMETHOD(device_detach,        iicbb_detach),
104
105         /* bus interface */
106         DEVMETHOD(bus_child_detached,   iicbb_child_detached),
107         DEVMETHOD(bus_print_child,      iicbb_print_child),
108
109         /* iicbus interface */
110         DEVMETHOD(iicbus_callback,      iicbb_callback),
111         DEVMETHOD(iicbus_start,         iicbb_start),
112         DEVMETHOD(iicbus_repeated_start, iicbb_start),
113         DEVMETHOD(iicbus_stop,          iicbb_stop),
114         DEVMETHOD(iicbus_write,         iicbb_write),
115         DEVMETHOD(iicbus_read,          iicbb_read),
116         DEVMETHOD(iicbus_reset,         iicbb_reset),
117         DEVMETHOD(iicbus_transfer,      iicbb_transfer),
118
119 #ifdef FDT
120         /* ofw_bus interface */
121         DEVMETHOD(ofw_bus_get_node,     iicbb_get_node),
122 #endif
123
124         { 0, 0 }
125 };
126
127 driver_t iicbb_driver = {
128         "iicbb",
129         iicbb_methods,
130         sizeof(struct iicbb_softc),
131 };
132
133 devclass_t iicbb_devclass;
134
135 static int
136 iicbb_probe(device_t dev)
137 {
138         device_set_desc(dev, "I2C bit-banging driver");
139
140         return (0);
141 }
142
143 static int
144 iicbb_attach(device_t dev)
145 {
146         struct iicbb_softc *sc = (struct iicbb_softc *)device_get_softc(dev);
147
148         sc->iicbus = device_add_child(dev, "iicbus", -1);
149         if (!sc->iicbus)
150                 return (ENXIO);
151
152         sc->scl_low_timeout = DEFAULT_SCL_LOW_TIMEOUT;
153
154         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
155             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
156             "delay", CTLFLAG_RD, &sc->udelay,
157             0, "Signal change delay controlled by bus frequency, microseconds");
158
159         SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
160             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
161             "scl_low_timeout", CTLFLAG_RWTUN, &sc->scl_low_timeout,
162             0, "SCL low timeout, microseconds");
163         bus_generic_attach(dev);
164         return (0);
165 }
166
167 static int
168 iicbb_detach(device_t dev)
169 {
170
171         bus_generic_detach(dev);
172         device_delete_children(dev);
173
174         return (0);
175 }
176
177 #ifdef FDT
178 static phandle_t
179 iicbb_get_node(device_t bus, device_t dev)
180 {
181
182         /* We only have one child, the I2C bus, which needs our own node. */
183         return (ofw_bus_get_node(bus));
184 }
185 #endif
186
187 static void
188 iicbb_child_detached( device_t dev, device_t child )
189 {
190         struct iicbb_softc *sc = (struct iicbb_softc *)device_get_softc(dev);
191
192         if (child == sc->iicbus)
193                 sc->iicbus = NULL;
194 }
195
196 static int
197 iicbb_print_child(device_t bus, device_t dev)
198 {
199         int error;
200         int retval = 0;
201         u_char oldaddr;
202
203         retval += bus_print_child_header(bus, dev);
204         /* retrieve the interface I2C address */
205         error = IICBB_RESET(device_get_parent(bus), IIC_FASTEST, 0, &oldaddr);
206         if (error == IIC_ENOADDR) {
207                 retval += printf(" on %s master-only\n",
208                                  device_get_nameunit(bus));
209         } else {
210                 /* restore the address */
211                 IICBB_RESET(device_get_parent(bus), IIC_FASTEST, oldaddr, NULL);
212
213                 retval += printf(" on %s addr 0x%x\n",
214                                  device_get_nameunit(bus), oldaddr & 0xff);
215         }
216
217         return (retval);
218 }
219
220 #define I2C_GETSDA(dev)         (IICBB_GETSDA(device_get_parent(dev)))
221 #define I2C_SETSDA(dev, x)      (IICBB_SETSDA(device_get_parent(dev), x))
222 #define I2C_GETSCL(dev)         (IICBB_GETSCL(device_get_parent(dev)))
223 #define I2C_SETSCL(dev, x)      (IICBB_SETSCL(device_get_parent(dev), x))
224
225 #define I2C_SET(sc, dev, ctrl, val) do {                \
226         iicbb_setscl(dev, ctrl);                        \
227         I2C_SETSDA(dev, val);                           \
228         DELAY(sc->udelay);                              \
229         } while (0)
230
231 static int i2c_debug = 0;
232 #define I2C_DEBUG(x)    do {                                    \
233                                 if (i2c_debug) (x);             \
234                         } while (0)
235
236 #define I2C_LOG(format,args...) do {                            \
237                                         printf(format, args);   \
238                                 } while (0)
239
240 static void
241 iicbb_setscl(device_t dev, int val)
242 {
243         struct iicbb_softc *sc = device_get_softc(dev);
244         sbintime_t now, end;
245         int fast_timeout;
246
247         I2C_SETSCL(dev, val);
248         DELAY(sc->udelay);
249
250         /* Pulling low cannot fail. */
251         if (!val)
252                 return;
253
254         /* Use DELAY for up to 1 ms, then switch to pause. */
255         end = sbinuptime() + sc->scl_low_timeout * SBT_1US;
256         fast_timeout = MIN(sc->scl_low_timeout, 1000);
257         while (fast_timeout > 0) {
258                 if (I2C_GETSCL(dev))
259                         return;
260                 I2C_SETSCL(dev, 1);     /* redundant ? */
261                 DELAY(sc->udelay);
262                 fast_timeout -= sc->udelay;
263         }
264
265         while (!I2C_GETSCL(dev)) {
266                 now = sbinuptime();
267                 if (now >= end)
268                         break;
269                 pause_sbt("iicbb-scl-low", SBT_1MS, C_PREL(8), 0);
270         }
271
272 }
273
274 static void
275 iicbb_one(device_t dev, int timeout)
276 {
277         struct iicbb_softc *sc = device_get_softc(dev);
278
279         I2C_SET(sc,dev,0,1);
280         I2C_SET(sc,dev,1,1);
281         I2C_SET(sc,dev,0,1);
282         return;
283 }
284
285 static void
286 iicbb_zero(device_t dev, int timeout)
287 {
288         struct iicbb_softc *sc = device_get_softc(dev);
289
290         I2C_SET(sc,dev,0,0);
291         I2C_SET(sc,dev,1,0);
292         I2C_SET(sc,dev,0,0);
293         return;
294 }
295
296 /*
297  * Waiting for ACKNOWLEDGE.
298  *
299  * When a chip is being addressed or has received data it will issue an
300  * ACKNOWLEDGE pulse. Therefore the MASTER must release the DATA line
301  * (set it to high level) and then release the CLOCK line.
302  * Now it must wait for the SLAVE to pull the DATA line low.
303  * Actually on the bus this looks like a START condition so nothing happens
304  * because of the fact that the IC's that have not been addressed are doing
305  * nothing.
306  *
307  * When the SLAVE has pulled this line low the MASTER will take the CLOCK
308  * line low and then the SLAVE will release the SDA (data) line.
309  */
310 static int
311 iicbb_ack(device_t dev, int timeout)
312 {
313         struct iicbb_softc *sc = device_get_softc(dev);
314         int noack;
315         int k = 0;
316
317         I2C_SET(sc,dev,0,1);
318         I2C_SET(sc,dev,1,1);
319
320         /* SCL must be high now. */
321         if (!I2C_GETSCL(dev))
322                 return (IIC_ETIMEOUT);
323
324         do {
325                 noack = I2C_GETSDA(dev);
326                 if (!noack)
327                         break;
328                 DELAY(1);
329                 k++;
330         } while (k < timeout);
331
332         I2C_SET(sc,dev,0,1);
333         I2C_DEBUG(printf("%c ",noack?'-':'+'));
334
335         return (noack ? IIC_ENOACK : 0);
336 }
337
338 static void
339 iicbb_sendbyte(device_t dev, u_char data, int timeout)
340 {
341         int i;
342
343         for (i=7; i>=0; i--) {
344                 if (data&(1<<i)) {
345                         iicbb_one(dev, timeout);
346                 } else {
347                         iicbb_zero(dev, timeout);
348                 }
349         }
350         I2C_DEBUG(printf("w%02x",(int)data));
351         return;
352 }
353
354 static u_char
355 iicbb_readbyte(device_t dev, int last, int timeout)
356 {
357         struct iicbb_softc *sc = device_get_softc(dev);
358         int i;
359         unsigned char data=0;
360
361         I2C_SET(sc,dev,0,1);
362         for (i=7; i>=0; i--) 
363         {
364                 I2C_SET(sc,dev,1,1);
365                 if (I2C_GETSDA(dev))
366                         data |= (1<<i);
367                 I2C_SET(sc,dev,0,1);
368         }
369         if (last) {
370                 iicbb_one(dev, timeout);
371         } else {
372                 iicbb_zero(dev, timeout);
373         }
374         I2C_DEBUG(printf("r%02x%c ",(int)data,last?'-':'+'));
375         return (data);
376 }
377
378 static int
379 iicbb_callback(device_t dev, int index, caddr_t data)
380 {
381         return (IICBB_CALLBACK(device_get_parent(dev), index, data));
382 }
383
384 static int
385 iicbb_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
386 {
387         iicbb_set_speed(device_get_softc(dev), speed);
388         return (IICBB_RESET(device_get_parent(dev), speed, addr, oldaddr));
389 }
390
391 static int
392 iicbb_start(device_t dev, u_char slave, int timeout)
393 {
394         struct iicbb_softc *sc = device_get_softc(dev);
395         int error;
396
397         I2C_DEBUG(printf("<"));
398
399         I2C_SET(sc,dev,1,1);
400
401         /* SCL must be high now. */
402         if (!I2C_GETSCL(dev))
403                 return (IIC_ETIMEOUT);
404
405         I2C_SET(sc,dev,1,0);
406         I2C_SET(sc,dev,0,0);
407
408         /* send address */
409         iicbb_sendbyte(dev, slave, timeout);
410
411         /* check for ack */
412         error = iicbb_ack(dev, timeout);
413         if (error == 0)
414                 return (0);
415
416         iicbb_stop(dev);
417         return (error);
418 }
419
420 static int
421 iicbb_stop(device_t dev)
422 {
423         struct iicbb_softc *sc = device_get_softc(dev);
424
425         I2C_SET(sc,dev,0,0);
426         I2C_SET(sc,dev,1,0);
427         I2C_SET(sc,dev,1,1);
428         I2C_DEBUG(printf(">"));
429         I2C_DEBUG(printf("\n"));
430
431         /* SCL must be high now. */
432         if (!I2C_GETSCL(dev))
433                 return (IIC_ETIMEOUT);
434         return (0);
435 }
436
437 static int
438 iicbb_write(device_t dev, const char *buf, int len, int *sent, int timeout)
439 {
440         int bytes, error = 0;
441
442         bytes = 0;
443         while (len) {
444                 /* send byte */
445                 iicbb_sendbyte(dev,(u_char)*buf++, timeout);
446
447                 /* check for ack */
448                 error = iicbb_ack(dev, timeout);
449                 if (error != 0)
450                         break;
451                 bytes++;
452                 len--;
453         }
454
455         *sent = bytes;
456         return (error);
457 }
458
459 static int
460 iicbb_read(device_t dev, char * buf, int len, int *read, int last, int delay)
461 {
462         int bytes;
463
464         bytes = 0;
465         while (len) {
466                 /* XXX should insert delay here */
467                 *buf++ = (char)iicbb_readbyte(dev, (len == 1) ? last : 0, delay);
468
469                 bytes ++;
470                 len --;
471         }
472
473         *read = bytes;
474         return (0);
475 }
476
477 static int
478 iicbb_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
479 {
480         int error;
481
482         error = IICBB_PRE_XFER(device_get_parent(dev));
483         if (error)
484                 return (error);
485
486         error = iicbus_transfer_gen(dev, msgs, nmsgs);
487
488         IICBB_POST_XFER(device_get_parent(dev));
489         return (error);
490 }
491
492 static void
493 iicbb_set_speed(struct iicbb_softc *sc, u_char speed)
494 {
495         u_int busfreq, period;
496
497         /*
498          * NB: the resulting frequency will be a quarter (even less) of the
499          * configured bus frequency.  This is for historic reasons.  The default
500          * bus frequency is 100 kHz.  And the historic default udelay is 10
501          * microseconds.  The cycle of sending a bit takes four udelay-s plus
502          * SCL is kept low for extra two udelay-s.  The actual I/O toggling also
503          * has an overhead.
504          */
505         busfreq = IICBUS_GET_FREQUENCY(sc->iicbus, speed);
506         period = 1000000 / busfreq;     /* Hz -> uS */
507         sc->udelay = MAX(period, 1);
508 }
509
510 DRIVER_MODULE(iicbus, iicbb, iicbus_driver, iicbus_devclass, 0, 0);
511
512 MODULE_DEPEND(iicbb, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
513 MODULE_VERSION(iicbb, IICBB_MODVER);