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.3/sys/i386/isa/pcf.c 169493 2007-05-12 06:10:11Z nyan $");
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_release_resource(pcfdev, SYS_RES_IOPORT, pcf->rid_ioport,
179 pcf->res_ioport);
180 }
181 return (ENXIO);
182 }
183
184 static int
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, INTR_TYPE_NET,
194 pcfintr, pcfdev, &pcf->intr_cookie);
195 if (error)
196 return (error);
197 }
198
199 pcf->iicbus = device_add_child(pcfdev, "iicbus", -1);
200
201 /* probe and attach the iicbus */
202 bus_generic_attach(pcfdev);
203
204 return (0);
205 }
206
207 static int
208 pcf_print_child(device_t bus, device_t dev)
209 {
210 struct pcf_softc *pcf = (struct pcf_softc *)device_get_softc(bus);
211 int retval = 0;
212
213 retval += bus_print_child_header(bus, dev);
214 retval += printf(" on %s addr 0x%x\n", device_get_nameunit(bus),
215 (int)pcf->pcf_addr);
216
217 return (retval);
218 }
219
220 /*
221 * PCF8584 datasheet : when operate at 8 MHz or more, a minimun time of
222 * 6 clocks cycles must be left between two consecutives access
223 */
224 #define pcf_nops() DELAY(10)
225
226 #define dummy_read(pcf) PCF_GET_S0(pcf)
227 #define dummy_write(pcf) PCF_SET_S0(pcf, 0)
228
229 /*
230 * Specific register access to PCF8584
231 */
232 static void PCF_SET_S0(struct pcf_softc *pcf, int data)
233 {
234 outb(pcf->pcf_base, data);
235 pcf_nops();
236 }
237
238 static void PCF_SET_S1(struct pcf_softc *pcf, int data)
239 {
240 outb(pcf->pcf_base+1, data);
241 pcf_nops();
242 }
243
244 static char PCF_GET_S0(struct pcf_softc *pcf)
245 {
246 char data;
247
248 data = inb(pcf->pcf_base);
249 pcf_nops();
250
251 return (data);
252 }
253
254 static char PCF_GET_S1(struct pcf_softc *pcf)
255 {
256 char data;
257
258 data = inb(pcf->pcf_base+1);
259 pcf_nops();
260
261 return (data);
262 }
263
264 /*
265 * Polling mode for master operations wait for a new
266 * byte incomming or outgoing
267 */
268 static int pcf_wait_byte(struct pcf_softc *pcf)
269 {
270 int counter = TIMEOUT;
271
272 while (counter--) {
273
274 if ((PCF_GET_S1(pcf) & PIN) == 0)
275 return (0);
276 }
277
278 return (IIC_ETIMEOUT);
279 }
280
281 static int pcf_stop(device_t pcfdev)
282 {
283 struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
284
285 /*
286 * Send STOP condition iff the START condition was previously sent.
287 * STOP is sent only once even if an iicbus_stop() is called after
288 * an iicbus_read()... see pcf_read(): the pcf needs to send the stop
289 * before the last char is read.
290 */
291 if (pcf->pcf_started) {
292 /* set stop condition and enable IT */
293 PCF_SET_S1(pcf, PIN|ES0|ENI|STO|ACK);
294
295 pcf->pcf_started = 0;
296 }
297
298 return (0);
299 }
300
301
302 static int pcf_noack(struct pcf_softc *pcf, int timeout)
303 {
304 int noack;
305 int k = timeout/10;
306
307 do {
308 noack = PCF_GET_S1(pcf) & LRB;
309 if (!noack)
310 break;
311 DELAY(10); /* XXX wait 10 us */
312 } while (k--);
313
314 return (noack);
315 }
316
317 static int pcf_repeated_start(device_t pcfdev, u_char slave, int timeout)
318 {
319 struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
320 int error = 0;
321
322 /* repeated start */
323 PCF_SET_S1(pcf, ES0|STA|STO|ACK);
324
325 /* set slave address to PCF. Last bit (LSB) must be set correctly
326 * according to transfer direction */
327 PCF_SET_S0(pcf, slave);
328
329 /* wait for address sent, polling */
330 if ((error = pcf_wait_byte(pcf)))
331 goto error;
332
333 /* check for ack */
334 if (pcf_noack(pcf, timeout)) {
335 error = IIC_ENOACK;
336 goto error;
337 }
338
339 return (0);
340
341 error:
342 pcf_stop(pcfdev);
343 return (error);
344 }
345
346 static int pcf_start(device_t pcfdev, u_char slave, int timeout)
347 {
348 struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
349 int error = 0;
350
351 if ((PCF_GET_S1(pcf) & nBB) == 0)
352 return (IIC_EBUSBSY);
353
354 /* set slave address to PCF. Last bit (LSB) must be set correctly
355 * according to transfer direction */
356 PCF_SET_S0(pcf, slave);
357
358 /* START only */
359 PCF_SET_S1(pcf, PIN|ES0|STA|ACK);
360
361 pcf->pcf_started = 1;
362
363 /* wait for address sent, polling */
364 if ((error = pcf_wait_byte(pcf)))
365 goto error;
366
367 /* check for ACK */
368 if (pcf_noack(pcf, timeout)) {
369 error = IIC_ENOACK;
370 goto error;
371 }
372
373 return (0);
374
375 error:
376 pcf_stop(pcfdev);
377 return (error);
378 }
379
380 static void
381 pcfintr(void *arg)
382 {
383 device_t pcfdev = (device_t)arg;
384 struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
385
386 char data, status, addr;
387 char error = 0;
388
389 status = PCF_GET_S1(pcf);
390
391 if (status & PIN) {
392 device_printf(pcfdev, "spurious interrupt, status=0x%x\n", status & 0xff);
393
394 goto error;
395 }
396
397 if (status & LAB)
398 device_printf(pcfdev, "bus arbitration lost!\n");
399
400 if (status & BER) {
401 error = IIC_EBUSERR;
402 iicbus_intr(pcf->iicbus, INTR_ERROR, &error);
403
404 goto error;
405 }
406
407 do {
408 status = PCF_GET_S1(pcf);
409
410 switch(pcf->pcf_slave_mode) {
411
412 case SLAVE_TRANSMITTER:
413 if (status & LRB) {
414 /* ack interrupt line */
415 dummy_write(pcf);
416
417 /* no ack, don't send anymore */
418 pcf->pcf_slave_mode = SLAVE_RECEIVER;
419
420 iicbus_intr(pcf->iicbus, INTR_NOACK, NULL);
421 break;
422 }
423
424 /* get data from upper code */
425 iicbus_intr(pcf->iicbus, INTR_TRANSMIT, &data);
426
427 PCF_SET_S0(pcf, data);
428 break;
429
430 case SLAVE_RECEIVER:
431 if (status & AAS) {
432 addr = PCF_GET_S0(pcf);
433
434 if (status & AD0)
435 iicbus_intr(pcf->iicbus, INTR_GENERAL, &addr);
436 else
437 iicbus_intr(pcf->iicbus, INTR_START, &addr);
438
439 if (addr & LSB) {
440 pcf->pcf_slave_mode = SLAVE_TRANSMITTER;
441
442 /* get the first char from upper code */
443 iicbus_intr(pcf->iicbus, INTR_TRANSMIT, &data);
444
445 /* send first data byte */
446 PCF_SET_S0(pcf, data);
447 }
448
449 break;
450 }
451
452 /* stop condition received? */
453 if (status & STS) {
454 /* ack interrupt line */
455 dummy_read(pcf);
456
457 /* emulate intr stop condition */
458 iicbus_intr(pcf->iicbus, INTR_STOP, NULL);
459
460 } else {
461 /* get data, ack interrupt line */
462 data = PCF_GET_S0(pcf);
463
464 /* deliver the character */
465 iicbus_intr(pcf->iicbus, INTR_RECEIVE, &data);
466 }
467 break;
468
469 default:
470 panic("%s: unknown slave mode (%d)!", __func__,
471 pcf->pcf_slave_mode);
472 }
473
474 } while ((PCF_GET_S1(pcf) & PIN) == 0);
475
476 return;
477
478 error:
479 /* unknown event on bus...reset PCF */
480 PCF_SET_S1(pcf, PIN|ES0|ENI|ACK);
481
482 pcf->pcf_slave_mode = SLAVE_RECEIVER;
483
484 return;
485 }
486
487 static int pcf_rst_card(device_t pcfdev, u_char speed, u_char addr, u_char *oldaddr)
488 {
489 struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
490
491 if (oldaddr)
492 *oldaddr = pcf->pcf_addr;
493
494 /* retrieve own address from bus level */
495 if (!addr)
496 pcf->pcf_addr = PCF_DEFAULT_ADDR;
497 else
498 pcf->pcf_addr = addr;
499
500 PCF_SET_S1(pcf, PIN); /* initialize S1 */
501
502 /* own address S'O<>0 */
503 PCF_SET_S0(pcf, pcf->pcf_addr >> 1);
504
505 /* select clock register */
506 PCF_SET_S1(pcf, PIN|ES1);
507
508 /* select bus speed : 18=90kb, 19=45kb, 1A=11kb, 1B=1.5kb */
509 switch (speed) {
510 case IIC_SLOW:
511 PCF_SET_S0(pcf, 0x1b);
512 break;
513
514 case IIC_FAST:
515 PCF_SET_S0(pcf, 0x19);
516 break;
517
518 case IIC_UNKNOWN:
519 case IIC_FASTEST:
520 default:
521 PCF_SET_S0(pcf, 0x18);
522 break;
523 }
524
525 /* set bus on, ack=yes, INT=yes */
526 PCF_SET_S1(pcf, PIN|ES0|ENI|ACK);
527
528 pcf->pcf_slave_mode = SLAVE_RECEIVER;
529
530 return (0);
531 }
532
533 static int
534 pcf_write(device_t pcfdev, char *buf, int len, int *sent, int timeout /* us */)
535 {
536 struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
537 int bytes, error = 0;
538
539 #ifdef PCFDEBUG
540 printf("pcf%d: >> writing %d bytes\n", device_get_unit(pcfdev), len);
541 #endif
542
543 bytes = 0;
544 while (len) {
545
546 PCF_SET_S0(pcf, *buf++);
547
548 /* wait for the byte to be send */
549 if ((error = pcf_wait_byte(pcf)))
550 goto error;
551
552 /* check if ack received */
553 if (pcf_noack(pcf, timeout)) {
554 error = IIC_ENOACK;
555 goto error;
556 }
557
558 len --;
559 bytes ++;
560 }
561
562 error:
563 *sent = bytes;
564
565 #ifdef PCFDEBUG
566 printf("pcf%d: >> %d bytes written (%d)\n",
567 device_get_unit(pcfdev), bytes, error);
568 #endif
569
570 return (error);
571 }
572
573 static int
574 pcf_read(device_t pcfdev, char *buf, int len, int *read, int last,
575 int delay /* us */)
576 {
577 struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);
578 int bytes, error = 0;
579
580 #ifdef PCFDEBUG
581 printf("pcf%d: << reading %d bytes\n", device_get_unit(pcfdev), len);
582 #endif
583
584 /* trig the bus to get the first data byte in S0 */
585 if (len) {
586 if (len == 1 && last)
587 /* just one byte to read */
588 PCF_SET_S1(pcf, ES0); /* no ack */
589
590 dummy_read(pcf);
591 }
592
593 bytes = 0;
594 while (len) {
595
596 /* XXX delay needed here */
597
598 /* wait for trigged byte */
599 if ((error = pcf_wait_byte(pcf))) {
600 pcf_stop(pcfdev);
601 goto error;
602 }
603
604 if (len == 1 && last)
605 /* ok, last data byte already in S0, no I2C activity
606 * on next PCF_GET_S0() */
607 pcf_stop(pcfdev);
608
609 else if (len == 2 && last)
610 /* next trigged byte with no ack */
611 PCF_SET_S1(pcf, ES0);
612
613 /* receive byte, trig next byte */
614 *buf++ = PCF_GET_S0(pcf);
615
616 len --;
617 bytes ++;
618 };
619
620 error:
621 *read = bytes;
622
623 #ifdef PCFDEBUG
624 printf("pcf%d: << %d bytes read (%d)\n",
625 device_get_unit(pcfdev), bytes, error);
626 #endif
627
628 return (error);
629 }
630
631 DRIVER_MODULE(pcf, isa, pcf_driver, pcf_devclass, 0, 0);
Cache object: 4ff1d2aa2f201707cda1147d1bc442c2
|