xref: /dragonfly/sys/bus/iicbus/pcf/pcf.c (revision 2267fd784e8a7d1ca13e6d3541caa91f36c9e9fb)
1 /*-
2  * Copyright (c) 1998 Nicolas Souchu, Marc Bouget
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
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
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  * $FreeBSD: src/sys/dev/pcf/pcf.c,v 1.21 2003/06/20 07:22:54 jmg Exp $
27  *
28  */
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/kernel.h>
32 #include <sys/module.h>
33 #include <sys/bus.h>
34 
35 #include <sys/rman.h>
36 
37 #include <bus/isa/isareg.h>
38 #include <bus/isa/isavar.h>
39 
40 #include <bus/isa/isa_device.h>
41 
42 #include "../iiconf.h"
43 #include "iicbus_if.h"
44 
45 #define IO_PCFSIZE  2
46 
47 #define TIMEOUT     9999                                              /* XXX */
48 
49 /* Status bits of S1 register (read only) */
50 #define nBB         0x01                /* busy when low set/reset by STOP/START*/
51 #define LAB         0x02                /* lost arbitration bit in multi-master mode */
52 #define AAS         0x04                /* addressed as slave */
53 #define LRB         0x08                /* last received byte when not AAS */
54 #define AD0         0x08                /* general call received when AAS */
55 #define BER         0x10                /* bus error, misplaced START or STOP */
56 #define STS         0x20                /* STOP detected in slave receiver mode */
57 #define PIN         0x80                /* pending interrupt not (r/w) */
58 
59 /* Control bits of S1 register (write only) */
60 #define ACK         0x01
61 #define STO         0x02
62 #define STA         0x04
63 #define ENI         0x08
64 #define ES2         0x10
65 #define ES1         0x20
66 #define ES0         0x40
67 
68 #define BUFSIZE 2048
69 
70 #define SLAVE_TRANSMITTER     0x1
71 #define SLAVE_RECEIVER                  0x2
72 
73 #define PCF_DEFAULT_ADDR      0xaa
74 
75 struct pcf_softc {
76 
77           int pcf_base;                           /* isa port */
78           int pcf_flags;
79           u_char pcf_addr;              /* interface I2C address */
80 
81           int pcf_slave_mode;           /* receiver or transmitter */
82           int pcf_started;              /* 1 if start condition sent */
83 
84           device_t iicbus;              /* the corresponding iicbus */
85 
86           int rid_irq, rid_ioport;
87           struct resource *res_irq, *res_ioport;
88           void *intr_cookie;
89 };
90 
91 static int pcf_probe(device_t);
92 static int pcf_attach(device_t);
93 static void pcfintr(void *arg);
94 
95 static int pcf_print_child(device_t, device_t);
96 
97 static int pcf_repeated_start(device_t, u_char, int);
98 static int pcf_start(device_t, u_char, int);
99 static int pcf_stop(device_t);
100 static int pcf_write(device_t, const char *, int, int *, int);
101 static int pcf_read(device_t, char *, int, int *, int, int);
102 static int pcf_rst_card(device_t, u_char, u_char, u_char *);
103 
104 static device_method_t pcf_methods[] = {
105           /* device interface */
106           DEVMETHOD(device_probe,                 pcf_probe),
107           DEVMETHOD(device_attach,      pcf_attach),
108 
109           /* bus interface */
110           DEVMETHOD(bus_print_child,    pcf_print_child),
111 
112           /* iicbus interface */
113           DEVMETHOD(iicbus_callback,    iicbus_null_callback),
114           DEVMETHOD(iicbus_repeated_start, pcf_repeated_start),
115           DEVMETHOD(iicbus_start,                 pcf_start),
116           DEVMETHOD(iicbus_stop,                  pcf_stop),
117           DEVMETHOD(iicbus_write,                 pcf_write),
118           DEVMETHOD(iicbus_read,                  pcf_read),
119           DEVMETHOD(iicbus_reset,                 pcf_rst_card),
120 
121           DEVMETHOD_END
122 };
123 
124 static driver_t pcf_driver = {
125           "pcf",
126           pcf_methods,
127           sizeof(struct pcf_softc),
128 };
129 
130 static devclass_t pcf_devclass;
131 
132 #define DEVTOSOFTC(dev) ((struct pcf_softc *)device_get_softc(dev))
133 
134 static int
pcf_probe(device_t pcfdev)135 pcf_probe(device_t pcfdev)
136 {
137           struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
138           device_t parent = device_get_parent(pcfdev);
139           uintptr_t base;
140 
141           device_set_desc(pcfdev, "PCF8584 I2C bus controller");
142 
143           bzero(pcf, sizeof(struct pcf_softc));
144 
145           pcf->rid_irq = pcf->rid_ioport = 0;
146           pcf->res_irq = pcf->res_ioport = NULL;
147 
148           /* IO port is mandatory */
149           pcf->res_ioport = bus_alloc_resource(pcfdev, SYS_RES_IOPORT,
150                                                        &pcf->rid_ioport, 0ul, ~0ul,
151                                                        IO_PCFSIZE, RF_ACTIVE);
152           if (pcf->res_ioport == NULL) {
153                     device_printf(pcfdev, "cannot reserve I/O port range\n");
154                     goto error;
155           }
156           BUS_READ_IVAR(parent, pcfdev, ISA_IVAR_PORT, &base);
157           pcf->pcf_base = base;
158 
159           pcf->pcf_flags = device_get_flags(pcfdev);
160 
161           if (!(pcf->pcf_flags & IIC_POLLED)) {
162                     pcf->res_irq = bus_alloc_resource(pcfdev, SYS_RES_IRQ, &pcf->rid_irq,
163                                                               0ul, ~0ul, 1, RF_ACTIVE);
164                     if (pcf->res_irq == NULL) {
165                               device_printf(pcfdev, "can't reserve irq, polled mode.\n");
166                               pcf->pcf_flags |= IIC_POLLED;
167                     }
168           }
169 
170           /* reset the chip */
171           pcf_rst_card(pcfdev, IIC_FASTEST, PCF_DEFAULT_ADDR, NULL);
172 
173           return (0);
174 error:
175           if (pcf->res_ioport != NULL) {
176                     bus_deactivate_resource(pcfdev, SYS_RES_IOPORT, pcf->rid_ioport,
177                                                   pcf->res_ioport);
178                     bus_release_resource(pcfdev, SYS_RES_IOPORT, pcf->rid_ioport,
179                                              pcf->res_ioport);
180           }
181           return (ENXIO);
182 }
183 
184 static int
pcf_attach(device_t pcfdev)185 pcf_attach(device_t pcfdev)
186 {
187           struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
188           device_t parent = device_get_parent(pcfdev);
189           int error = 0;
190 
191           if (pcf->res_irq) {
192                     /* default to the tty mask for registration */    /* XXX */
193                     error = BUS_SETUP_INTR(parent, pcfdev, pcf->res_irq,
194                                                   0, pcfintr, pcfdev,
195                                                   &pcf->intr_cookie, NULL, NULL);
196                     if (error)
197                               return (error);
198           }
199 
200           pcf->iicbus = device_add_child(pcfdev, "iicbus", -1);
201 
202           /* probe and attach the iicbus */
203           bus_generic_attach(pcfdev);
204 
205           return (0);
206 }
207 
208 static int
pcf_print_child(device_t bus,device_t dev)209 pcf_print_child(device_t bus, device_t dev)
210 {
211           struct pcf_softc *pcf = (struct pcf_softc *)device_get_softc(bus);
212           int retval = 0;
213 
214           retval += bus_print_child_header(bus, dev);
215           retval += kprintf(" on %s addr 0x%x\n", device_get_nameunit(bus),
216                                (int)pcf->pcf_addr);
217 
218           return (retval);
219 }
220 
221 /*
222  * PCF8584 datasheet : when operate at 8 MHz or more, a minimun time of
223  * 6 clocks cycles must be left between two consecutives access
224  */
225 #define pcf_nops()  DELAY(10)
226 
227 #define dummy_read(pcf)                 PCF_GET_S0(pcf)
228 #define dummy_write(pcf)      PCF_SET_S0(pcf, 0)
229 
230 /*
231  * Specific register access to PCF8584
232  */
233 static void
PCF_SET_S0(struct pcf_softc * pcf,int data)234 PCF_SET_S0(struct pcf_softc *pcf, int data)
235 {
236           outb(pcf->pcf_base, data);
237           pcf_nops();
238 }
239 
240 static void
PCF_SET_S1(struct pcf_softc * pcf,int data)241 PCF_SET_S1(struct pcf_softc *pcf, int data)
242 {
243           outb(pcf->pcf_base+1, data);
244           pcf_nops();
245 }
246 
247 static char
PCF_GET_S0(struct pcf_softc * pcf)248 PCF_GET_S0(struct pcf_softc *pcf)
249 {
250           char data;
251 
252           data = inb(pcf->pcf_base);
253           pcf_nops();
254 
255           return (data);
256 }
257 
258 static char
PCF_GET_S1(struct pcf_softc * pcf)259 PCF_GET_S1(struct pcf_softc *pcf)
260 {
261           char data;
262 
263           data = inb(pcf->pcf_base+1);
264           pcf_nops();
265 
266           return (data);
267 }
268 
269 /*
270  * Polling mode for master operations wait for a new
271  * byte incomming or outgoing
272  */
273 static int
pcf_wait_byte(struct pcf_softc * pcf)274 pcf_wait_byte(struct pcf_softc *pcf)
275 {
276           int counter = TIMEOUT;
277 
278           while (counter--) {
279 
280                     if ((PCF_GET_S1(pcf) & PIN) == 0)
281                               return (0);
282           }
283 
284           return (IIC_ETIMEOUT);
285 }
286 
287 static int
pcf_stop(device_t pcfdev)288 pcf_stop(device_t pcfdev)
289 {
290           struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
291 
292           /*
293            * Send STOP condition iff the START condition was previously sent.
294            * STOP is sent only once even if an iicbus_stop() is called after
295            * an iicbus_read()... see pcf_read(): the pcf needs to send the stop
296            * before the last char is read.
297            */
298           if (pcf->pcf_started) {
299                     /* set stop condition and enable IT */
300                     PCF_SET_S1(pcf, PIN|ES0|ENI|STO|ACK);
301 
302                     pcf->pcf_started = 0;
303           }
304 
305           return (0);
306 }
307 
308 
309 static int
pcf_noack(struct pcf_softc * pcf,int timeout)310 pcf_noack(struct pcf_softc *pcf, int timeout)
311 {
312           int noack;
313           int k = timeout/10;
314 
315           do {
316                     noack = PCF_GET_S1(pcf) & LRB;
317                     if (!noack)
318                               break;
319                     DELAY(10);                                        /* XXX wait 10 us */
320           } while (k--);
321 
322           return (noack);
323 }
324 
325 static int
pcf_repeated_start(device_t pcfdev,u_char slave,int timeout)326 pcf_repeated_start(device_t pcfdev, u_char slave, int timeout)
327 {
328           struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
329           int error = 0;
330 
331           /* repeated start */
332           PCF_SET_S1(pcf, ES0|STA|STO|ACK);
333 
334           /* set slave address to PCF. Last bit (LSB) must be set correctly
335            * according to transfer direction */
336           PCF_SET_S0(pcf, slave);
337 
338           /* wait for address sent, polling */
339           if ((error = pcf_wait_byte(pcf)))
340                     goto error;
341 
342           /* check for ack */
343           if (pcf_noack(pcf, timeout)) {
344                     error = IIC_ENOACK;
345                     goto error;
346           }
347 
348           return (0);
349 
350 error:
351           pcf_stop(pcfdev);
352           return (error);
353 }
354 
355 static int
pcf_start(device_t pcfdev,u_char slave,int timeout)356 pcf_start(device_t pcfdev, u_char slave, int timeout)
357 {
358           struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
359           int error = 0;
360 
361           if ((PCF_GET_S1(pcf) & nBB) == 0)
362                     return (IIC_EBUSBSY);
363 
364           /* set slave address to PCF. Last bit (LSB) must be set correctly
365            * according to transfer direction */
366           PCF_SET_S0(pcf, slave);
367 
368           /* START only */
369           PCF_SET_S1(pcf, PIN|ES0|STA|ACK);
370 
371           pcf->pcf_started = 1;
372 
373           /* wait for address sent, polling */
374           if ((error = pcf_wait_byte(pcf)))
375                     goto error;
376 
377           /* check for ACK */
378           if (pcf_noack(pcf, timeout)) {
379                     error = IIC_ENOACK;
380                     goto error;
381           }
382 
383           return (0);
384 
385 error:
386           pcf_stop(pcfdev);
387           return (error);
388 }
389 
390 static void
pcfintr(void * arg)391 pcfintr(void *arg)
392 {
393           device_t pcfdev = (device_t)arg;
394           struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
395 
396           char data, status, addr;
397           char error = 0;
398 
399           status = PCF_GET_S1(pcf);
400 
401           if (status & PIN) {
402                     device_printf(pcfdev, "spurious interrupt, status=0x%x\n", status & 0xff);
403 
404                     goto error;
405           }
406 
407           if (status & LAB)
408                     device_printf(pcfdev, "bus arbitration lost!\n");
409 
410           if (status & BER) {
411                     error = IIC_EBUSERR;
412                     iicbus_intr(pcf->iicbus, INTR_ERROR, &error);
413 
414                     goto error;
415           }
416 
417           do {
418                     status = PCF_GET_S1(pcf);
419 
420                     switch(pcf->pcf_slave_mode) {
421 
422                     case SLAVE_TRANSMITTER:
423                               if (status & LRB) {
424                                         /* ack interrupt line */
425                                         dummy_write(pcf);
426 
427                                         /* no ack, don't send anymore */
428                                         pcf->pcf_slave_mode = SLAVE_RECEIVER;
429 
430                                         iicbus_intr(pcf->iicbus, INTR_NOACK, NULL);
431                                         break;
432                               }
433 
434                               /* get data from upper code */
435                               iicbus_intr(pcf->iicbus, INTR_TRANSMIT, &data);
436 
437                               PCF_SET_S0(pcf, data);
438                               break;
439 
440                     case SLAVE_RECEIVER:
441                               if (status & AAS) {
442                                         addr = PCF_GET_S0(pcf);
443 
444                                         if (status & AD0)
445                                                   iicbus_intr(pcf->iicbus, INTR_GENERAL, &addr);
446                                         else
447                                                   iicbus_intr(pcf->iicbus, INTR_START, &addr);
448 
449                                         if (addr & LSB) {
450                                                   pcf->pcf_slave_mode = SLAVE_TRANSMITTER;
451 
452                                                   /* get the first char from upper code */
453                                                   iicbus_intr(pcf->iicbus, INTR_TRANSMIT, &data);
454 
455                                                   /* send first data byte */
456                                                   PCF_SET_S0(pcf, data);
457                                         }
458 
459                                         break;
460                               }
461 
462                               /* stop condition received? */
463                               if (status & STS) {
464                                         /* ack interrupt line */
465                                         dummy_read(pcf);
466 
467                                         /* emulate intr stop condition */
468                                         iicbus_intr(pcf->iicbus, INTR_STOP, NULL);
469 
470                               } else {
471                                         /* get data, ack interrupt line */
472                                         data = PCF_GET_S0(pcf);
473 
474                                         /* deliver the character */
475                                         iicbus_intr(pcf->iicbus, INTR_RECEIVE, &data);
476                               }
477                               break;
478 
479                         default:
480                               panic("%s: unknown slave mode (%d)!", __func__,
481                                         pcf->pcf_slave_mode);
482                         }
483 
484           } while ((PCF_GET_S1(pcf) & PIN) == 0);
485 
486           return;
487 
488 error:
489           /* unknown event on bus...reset PCF */
490           PCF_SET_S1(pcf, PIN|ES0|ENI|ACK);
491 
492           pcf->pcf_slave_mode = SLAVE_RECEIVER;
493 
494           return;
495 }
496 
497 static int
pcf_rst_card(device_t pcfdev,u_char speed,u_char addr,u_char * oldaddr)498 pcf_rst_card(device_t pcfdev, u_char speed, u_char addr, u_char *oldaddr)
499 {
500           struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
501 
502           if (oldaddr)
503                     *oldaddr = pcf->pcf_addr;
504 
505           /* retrieve own address from bus level */
506           if (!addr)
507                     pcf->pcf_addr = PCF_DEFAULT_ADDR;
508           else
509                     pcf->pcf_addr = addr;
510 
511           PCF_SET_S1(pcf, PIN);                                       /* initialize S1 */
512 
513           /* own address S'O<>0 */
514           PCF_SET_S0(pcf, pcf->pcf_addr >> 1);
515 
516           /* select clock register */
517           PCF_SET_S1(pcf, PIN|ES1);
518 
519           /* select bus speed : 18=90kb, 19=45kb, 1A=11kb, 1B=1.5kb */
520           switch (speed) {
521           case IIC_SLOW:
522                     PCF_SET_S0(pcf,  0x1b);
523                     break;
524 
525           case IIC_FAST:
526                     PCF_SET_S0(pcf,  0x19);
527                     break;
528 
529           case IIC_UNKNOWN:
530           case IIC_FASTEST:
531           default:
532                     PCF_SET_S0(pcf,  0x18);
533                     break;
534           }
535 
536           /* set bus on, ack=yes, INT=yes */
537           PCF_SET_S1(pcf, PIN|ES0|ENI|ACK);
538 
539           pcf->pcf_slave_mode = SLAVE_RECEIVER;
540 
541           return (0);
542 }
543 
544 static int
pcf_write(device_t pcfdev,const char * buf,int len,int * sent,int timeout)545 pcf_write(device_t pcfdev, const char *buf, int len, int *sent,
546             int timeout /* us */)
547 {
548           struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
549           int bytes, error = 0;
550 
551 #ifdef PCFDEBUG
552           kprintf("pcf%d: >> writing %d bytes\n", device_get_unit(pcfdev), len);
553 #endif
554 
555           bytes = 0;
556           while (len) {
557 
558                     PCF_SET_S0(pcf, *buf++);
559 
560                     /* wait for the byte to be send */
561                     if ((error = pcf_wait_byte(pcf)))
562                               goto error;
563 
564                     /* check if ack received */
565                     if (pcf_noack(pcf, timeout)) {
566                               error = IIC_ENOACK;
567                               goto error;
568                     }
569 
570                     len --;
571                     bytes ++;
572           }
573 
574 error:
575           *sent = bytes;
576 
577 #ifdef PCFDEBUG
578           kprintf("pcf%d: >> %d bytes written (%d)\n",
579                     device_get_unit(pcfdev), bytes, error);
580 #endif
581 
582           return (error);
583 }
584 
585 static int
pcf_read(device_t pcfdev,char * buf,int len,int * read,int last,int delay)586 pcf_read(device_t pcfdev, char *buf, int len, int *read, int last,
587                                                                       int delay /* us */)
588 {
589           struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
590           int bytes, error = 0;
591 
592 #ifdef PCFDEBUG
593           kprintf("pcf%d: << reading %d bytes\n", device_get_unit(pcfdev), len);
594 #endif
595 
596           /* trig the bus to get the first data byte in S0 */
597           if (len) {
598                     if (len == 1 && last)
599                               /* just one byte to read */
600                               PCF_SET_S1(pcf, ES0);                   /* no ack */
601 
602                     dummy_read(pcf);
603           }
604 
605           bytes = 0;
606           while (len) {
607 
608                     /* XXX delay needed here */
609 
610                     /* wait for trigged byte */
611                     if ((error = pcf_wait_byte(pcf))) {
612                               pcf_stop(pcfdev);
613                               goto error;
614                     }
615 
616                     if (len == 1 && last)
617                               /* ok, last data byte already in S0, no I2C activity
618                                * on next PCF_GET_S0() */
619                               pcf_stop(pcfdev);
620 
621                     else if (len == 2 && last)
622                               /* next trigged byte with no ack */
623                               PCF_SET_S1(pcf, ES0);
624 
625                     /* receive byte, trig next byte */
626                     *buf++ = PCF_GET_S0(pcf);
627 
628                     len --;
629                     bytes ++;
630           }
631 
632 error:
633           *read = bytes;
634 
635 #ifdef PCFDEBUG
636           kprintf("pcf%d: << %d bytes read (%d)\n",
637                     device_get_unit(pcfdev), bytes, error);
638 #endif
639 
640           return (error);
641 }
642 
643 DRIVER_MODULE(pcf, isa, pcf_driver, pcf_devclass, NULL, NULL);
644