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