summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFinn Thain <fthain@telegraphics.com.au>2016-12-31 19:56:26 -0500
committerMichael Ellerman <mpe@ellerman.id.au>2017-02-07 00:56:25 -0500
commitf74faec6b3af9d88943a33ccd08de63b0dab8bc7 (patch)
tree94b4d0bbfaf5b319dec1e6186a4fd74589b9e556
parentd23eee88b56921a0bccd3b2355fc6feb4b5d343b (diff)
m68k/mac: Replace via-maciisi driver with via-cuda driver
Change the device probe test in the via-cuda.c driver so it will load on Egret-based machines too. Remove the now redundant via-maciisi.c driver. Tested-by: Stan Johnson <userm57@yahoo.com> Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Acked-by: Geert Uytterhoeven <geert@linux-m68k.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--arch/m68k/include/asm/macintosh.h2
-rw-r--r--arch/m68k/mac/config.c18
-rw-r--r--arch/m68k/mac/misc.c72
-rw-r--r--drivers/macintosh/Kconfig24
-rw-r--r--drivers/macintosh/Makefile1
-rw-r--r--drivers/macintosh/adb.c4
-rw-r--r--drivers/macintosh/via-cuda.c8
-rw-r--r--drivers/macintosh/via-maciisi.c677
8 files changed, 30 insertions, 776 deletions
diff --git a/arch/m68k/include/asm/macintosh.h b/arch/m68k/include/asm/macintosh.h
index 42235e7fbeed..5b81ab188aa5 100644
--- a/arch/m68k/include/asm/macintosh.h
+++ b/arch/m68k/include/asm/macintosh.h
@@ -38,7 +38,7 @@ struct mac_model
38 38
39#define MAC_ADB_NONE 0 39#define MAC_ADB_NONE 0
40#define MAC_ADB_II 1 40#define MAC_ADB_II 1
41#define MAC_ADB_IISI 2 41#define MAC_ADB_EGRET 2
42#define MAC_ADB_CUDA 3 42#define MAC_ADB_CUDA 3
43#define MAC_ADB_PB1 4 43#define MAC_ADB_PB1 4
44#define MAC_ADB_PB2 5 44#define MAC_ADB_PB2 5
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index e46895316eb0..9dc65a4c28d2 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -286,7 +286,7 @@ static struct mac_model mac_data_table[] = {
286 }, { 286 }, {
287 .ident = MAC_MODEL_IISI, 287 .ident = MAC_MODEL_IISI,
288 .name = "IIsi", 288 .name = "IIsi",
289 .adb_type = MAC_ADB_IISI, 289 .adb_type = MAC_ADB_EGRET,
290 .via_type = MAC_VIA_IICI, 290 .via_type = MAC_VIA_IICI,
291 .scsi_type = MAC_SCSI_OLD, 291 .scsi_type = MAC_SCSI_OLD,
292 .scc_type = MAC_SCC_II, 292 .scc_type = MAC_SCC_II,
@@ -295,7 +295,7 @@ static struct mac_model mac_data_table[] = {
295 }, { 295 }, {
296 .ident = MAC_MODEL_IIVI, 296 .ident = MAC_MODEL_IIVI,
297 .name = "IIvi", 297 .name = "IIvi",
298 .adb_type = MAC_ADB_IISI, 298 .adb_type = MAC_ADB_EGRET,
299 .via_type = MAC_VIA_IICI, 299 .via_type = MAC_VIA_IICI,
300 .scsi_type = MAC_SCSI_LC, 300 .scsi_type = MAC_SCSI_LC,
301 .scc_type = MAC_SCC_II, 301 .scc_type = MAC_SCC_II,
@@ -304,7 +304,7 @@ static struct mac_model mac_data_table[] = {
304 }, { 304 }, {
305 .ident = MAC_MODEL_IIVX, 305 .ident = MAC_MODEL_IIVX,
306 .name = "IIvx", 306 .name = "IIvx",
307 .adb_type = MAC_ADB_IISI, 307 .adb_type = MAC_ADB_EGRET,
308 .via_type = MAC_VIA_IICI, 308 .via_type = MAC_VIA_IICI,
309 .scsi_type = MAC_SCSI_LC, 309 .scsi_type = MAC_SCSI_LC,
310 .scc_type = MAC_SCC_II, 310 .scc_type = MAC_SCC_II,
@@ -319,7 +319,7 @@ static struct mac_model mac_data_table[] = {
319 { 319 {
320 .ident = MAC_MODEL_CLII, 320 .ident = MAC_MODEL_CLII,
321 .name = "Classic II", 321 .name = "Classic II",
322 .adb_type = MAC_ADB_IISI, 322 .adb_type = MAC_ADB_EGRET,
323 .via_type = MAC_VIA_IICI, 323 .via_type = MAC_VIA_IICI,
324 .scsi_type = MAC_SCSI_LC, 324 .scsi_type = MAC_SCSI_LC,
325 .scc_type = MAC_SCC_II, 325 .scc_type = MAC_SCC_II,
@@ -352,7 +352,7 @@ static struct mac_model mac_data_table[] = {
352 { 352 {
353 .ident = MAC_MODEL_LC, 353 .ident = MAC_MODEL_LC,
354 .name = "LC", 354 .name = "LC",
355 .adb_type = MAC_ADB_IISI, 355 .adb_type = MAC_ADB_EGRET,
356 .via_type = MAC_VIA_IICI, 356 .via_type = MAC_VIA_IICI,
357 .scsi_type = MAC_SCSI_LC, 357 .scsi_type = MAC_SCSI_LC,
358 .scc_type = MAC_SCC_II, 358 .scc_type = MAC_SCC_II,
@@ -361,7 +361,7 @@ static struct mac_model mac_data_table[] = {
361 }, { 361 }, {
362 .ident = MAC_MODEL_LCII, 362 .ident = MAC_MODEL_LCII,
363 .name = "LC II", 363 .name = "LC II",
364 .adb_type = MAC_ADB_IISI, 364 .adb_type = MAC_ADB_EGRET,
365 .via_type = MAC_VIA_IICI, 365 .via_type = MAC_VIA_IICI,
366 .scsi_type = MAC_SCSI_LC, 366 .scsi_type = MAC_SCSI_LC,
367 .scc_type = MAC_SCC_II, 367 .scc_type = MAC_SCC_II,
@@ -370,7 +370,7 @@ static struct mac_model mac_data_table[] = {
370 }, { 370 }, {
371 .ident = MAC_MODEL_LCIII, 371 .ident = MAC_MODEL_LCIII,
372 .name = "LC III", 372 .name = "LC III",
373 .adb_type = MAC_ADB_IISI, 373 .adb_type = MAC_ADB_EGRET,
374 .via_type = MAC_VIA_IICI, 374 .via_type = MAC_VIA_IICI,
375 .scsi_type = MAC_SCSI_LC, 375 .scsi_type = MAC_SCSI_LC,
376 .scc_type = MAC_SCC_II, 376 .scc_type = MAC_SCC_II,
@@ -498,7 +498,7 @@ static struct mac_model mac_data_table[] = {
498 { 498 {
499 .ident = MAC_MODEL_P460, 499 .ident = MAC_MODEL_P460,
500 .name = "Performa 460", 500 .name = "Performa 460",
501 .adb_type = MAC_ADB_IISI, 501 .adb_type = MAC_ADB_EGRET,
502 .via_type = MAC_VIA_IICI, 502 .via_type = MAC_VIA_IICI,
503 .scsi_type = MAC_SCSI_LC, 503 .scsi_type = MAC_SCSI_LC,
504 .scc_type = MAC_SCC_II, 504 .scc_type = MAC_SCC_II,
@@ -575,7 +575,7 @@ static struct mac_model mac_data_table[] = {
575 }, { 575 }, {
576 .ident = MAC_MODEL_P600, 576 .ident = MAC_MODEL_P600,
577 .name = "Performa 600", 577 .name = "Performa 600",
578 .adb_type = MAC_ADB_IISI, 578 .adb_type = MAC_ADB_EGRET,
579 .via_type = MAC_VIA_IICI, 579 .via_type = MAC_VIA_IICI,
580 .scsi_type = MAC_SCSI_LC, 580 .scsi_type = MAC_SCSI_LC,
581 .scc_type = MAC_SCC_II, 581 .scc_type = MAC_SCC_II,
diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c
index c6d351f5bd79..f4bb73fcb67a 100644
--- a/arch/m68k/mac/misc.c
+++ b/arch/m68k/mac/misc.c
@@ -142,54 +142,6 @@ static void pmu_write_pram(int offset, __u8 data)
142#define pmu_write_pram NULL 142#define pmu_write_pram NULL
143#endif 143#endif
144 144
145#if 0 /* def CONFIG_ADB_MACIISI */
146extern int maciisi_request(struct adb_request *req,
147 void (*done)(struct adb_request *), int nbytes, ...);
148
149static long maciisi_read_time(void)
150{
151 struct adb_request req;
152 long time;
153
154 if (maciisi_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME))
155 return 0;
156
157 time = (req.reply[3] << 24) | (req.reply[4] << 16)
158 | (req.reply[5] << 8) | req.reply[6];
159 return time - RTC_OFFSET;
160}
161
162static void maciisi_write_time(long data)
163{
164 struct adb_request req;
165 data += RTC_OFFSET;
166 maciisi_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
167 (data >> 24) & 0xFF, (data >> 16) & 0xFF,
168 (data >> 8) & 0xFF, data & 0xFF);
169}
170
171static __u8 maciisi_read_pram(int offset)
172{
173 struct adb_request req;
174 if (maciisi_request(&req, NULL, 4, CUDA_PACKET, CUDA_GET_PRAM,
175 (offset >> 8) & 0xFF, offset & 0xFF))
176 return 0;
177 return req.reply[3];
178}
179
180static void maciisi_write_pram(int offset, __u8 data)
181{
182 struct adb_request req;
183 maciisi_request(&req, NULL, 5, CUDA_PACKET, CUDA_SET_PRAM,
184 (offset >> 8) & 0xFF, offset & 0xFF, data);
185}
186#else
187#define maciisi_read_time() 0
188#define maciisi_write_time(n)
189#define maciisi_read_pram NULL
190#define maciisi_write_pram NULL
191#endif
192
193/* 145/*
194 * VIA PRAM/RTC access routines 146 * VIA PRAM/RTC access routines
195 * 147 *
@@ -458,11 +410,10 @@ void mac_pram_read(int offset, __u8 *buffer, int len)
458 int i; 410 int i;
459 411
460 switch(macintosh_config->adb_type) { 412 switch(macintosh_config->adb_type) {
461 case MAC_ADB_IISI:
462 func = maciisi_read_pram; break;
463 case MAC_ADB_PB1: 413 case MAC_ADB_PB1:
464 case MAC_ADB_PB2: 414 case MAC_ADB_PB2:
465 func = pmu_read_pram; break; 415 func = pmu_read_pram; break;
416 case MAC_ADB_EGRET:
466 case MAC_ADB_CUDA: 417 case MAC_ADB_CUDA:
467 func = cuda_read_pram; break; 418 func = cuda_read_pram; break;
468 default: 419 default:
@@ -481,11 +432,10 @@ void mac_pram_write(int offset, __u8 *buffer, int len)
481 int i; 432 int i;
482 433
483 switch(macintosh_config->adb_type) { 434 switch(macintosh_config->adb_type) {
484 case MAC_ADB_IISI:
485 func = maciisi_write_pram; break;
486 case MAC_ADB_PB1: 435 case MAC_ADB_PB1:
487 case MAC_ADB_PB2: 436 case MAC_ADB_PB2:
488 func = pmu_write_pram; break; 437 func = pmu_write_pram; break;
438 case MAC_ADB_EGRET:
489 case MAC_ADB_CUDA: 439 case MAC_ADB_CUDA:
490 func = cuda_write_pram; break; 440 func = cuda_write_pram; break;
491 default: 441 default:
@@ -500,17 +450,13 @@ void mac_pram_write(int offset, __u8 *buffer, int len)
500 450
501void mac_poweroff(void) 451void mac_poweroff(void)
502{ 452{
503 /*
504 * MAC_ADB_IISI may need to be moved up here if it doesn't actually
505 * work using the ADB packet method. --David Kilzer
506 */
507
508 if (oss_present) { 453 if (oss_present) {
509 oss_shutdown(); 454 oss_shutdown();
510 } else if (macintosh_config->adb_type == MAC_ADB_II) { 455 } else if (macintosh_config->adb_type == MAC_ADB_II) {
511 via_shutdown(); 456 via_shutdown();
512#ifdef CONFIG_ADB_CUDA 457#ifdef CONFIG_ADB_CUDA
513 } else if (macintosh_config->adb_type == MAC_ADB_CUDA) { 458 } else if (macintosh_config->adb_type == MAC_ADB_EGRET ||
459 macintosh_config->adb_type == MAC_ADB_CUDA) {
514 cuda_shutdown(); 460 cuda_shutdown();
515#endif 461#endif
516#ifdef CONFIG_ADB_PMU68K 462#ifdef CONFIG_ADB_PMU68K
@@ -550,7 +496,8 @@ void mac_reset(void)
550 local_irq_restore(flags); 496 local_irq_restore(flags);
551 } 497 }
552#ifdef CONFIG_ADB_CUDA 498#ifdef CONFIG_ADB_CUDA
553 } else if (macintosh_config->adb_type == MAC_ADB_CUDA) { 499 } else if (macintosh_config->adb_type == MAC_ADB_EGRET ||
500 macintosh_config->adb_type == MAC_ADB_CUDA) {
554 cuda_restart(); 501 cuda_restart();
555#endif 502#endif
556#ifdef CONFIG_ADB_PMU68K 503#ifdef CONFIG_ADB_PMU68K
@@ -699,13 +646,11 @@ int mac_hwclk(int op, struct rtc_time *t)
699 case MAC_ADB_IOP: 646 case MAC_ADB_IOP:
700 now = via_read_time(); 647 now = via_read_time();
701 break; 648 break;
702 case MAC_ADB_IISI:
703 now = maciisi_read_time();
704 break;
705 case MAC_ADB_PB1: 649 case MAC_ADB_PB1:
706 case MAC_ADB_PB2: 650 case MAC_ADB_PB2:
707 now = pmu_read_time(); 651 now = pmu_read_time();
708 break; 652 break;
653 case MAC_ADB_EGRET:
709 case MAC_ADB_CUDA: 654 case MAC_ADB_CUDA:
710 now = cuda_read_time(); 655 now = cuda_read_time();
711 break; 656 break;
@@ -737,6 +682,7 @@ int mac_hwclk(int op, struct rtc_time *t)
737 case MAC_ADB_IOP: 682 case MAC_ADB_IOP:
738 via_write_time(now); 683 via_write_time(now);
739 break; 684 break;
685 case MAC_ADB_EGRET:
740 case MAC_ADB_CUDA: 686 case MAC_ADB_CUDA:
741 cuda_write_time(now); 687 cuda_write_time(now);
742 break; 688 break;
@@ -744,8 +690,6 @@ int mac_hwclk(int op, struct rtc_time *t)
744 case MAC_ADB_PB2: 690 case MAC_ADB_PB2:
745 pmu_write_time(now); 691 pmu_write_time(now);
746 break; 692 break;
747 case MAC_ADB_IISI:
748 maciisi_write_time(now);
749 } 693 }
750 } 694 }
751 return 0; 695 return 0;
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index 5d80810934df..97a420c11eed 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -30,14 +30,6 @@ config ADB_MACII
30 Quadra 610, Quadra 650, Quadra 700, Quadra 800, Centris 610 and 30 Quadra 610, Quadra 650, Quadra 700, Quadra 800, Centris 610 and
31 Centris 650. 31 Centris 650.
32 32
33config ADB_MACIISI
34 bool "Include Mac IIsi ADB driver"
35 depends on ADB && MAC && BROKEN
36 help
37 Say Y here if want your kernel to support Macintosh systems that use
38 the Mac IIsi style ADB. This includes the IIsi, IIvi, IIvx, Classic
39 II, LC, LC II, LC III, Performa 460, and the Performa 600.
40
41config ADB_IOP 33config ADB_IOP
42 bool "Include IOP (IIfx/Quadra 9x0) ADB driver" 34 bool "Include IOP (IIfx/Quadra 9x0) ADB driver"
43 depends on ADB && MAC 35 depends on ADB && MAC
@@ -60,17 +52,15 @@ config ADB_PMU68K
60 52
61# we want to change this to something like CONFIG_SYSCTRL_CUDA/PMU 53# we want to change this to something like CONFIG_SYSCTRL_CUDA/PMU
62config ADB_CUDA 54config ADB_CUDA
63 bool "Support for CUDA based Macs and PowerMacs" 55 bool "Support for Cuda/Egret based Macs and PowerMacs"
64 depends on (ADB || PPC_PMAC) && !PPC_PMAC64 56 depends on (ADB || PPC_PMAC) && !PPC_PMAC64
65 help 57 help
66 This provides support for CUDA based Macintosh and Power Macintosh 58 This provides support for Cuda/Egret based Macintosh and
67 systems. This includes many m68k based Macs (Color Classic, Mac TV, 59 Power Macintosh systems. This includes most m68k based Macs,
68 Performa 475, Performa 520, Performa 550, Performa 575, 60 most Old World PowerMacs, the first generation iMacs, the
69 Performa 588, Quadra 605, Quadra 630, Quadra/Centris 660AV, and 61 Blue & White G3 and the "Yikes" G4 (PCI Graphics). All later
70 Quadra 840AV), most OldWorld PowerMacs, the first generation iMacs, 62 models should use CONFIG_ADB_PMU instead. It is safe to say Y
71 the Blue&White G3 and the "Yikes" G4 (PCI Graphics). All later 63 here even if your machine doesn't have a Cuda or Egret device.
72 models should use CONFIG_ADB_PMU instead. It is safe to say Y here
73 even if your machine doesn't have a CUDA.
74 64
75 If unsure say Y. 65 If unsure say Y.
76 66
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile
index 383ba920085b..516eb65bcacc 100644
--- a/drivers/macintosh/Makefile
+++ b/drivers/macintosh/Makefile
@@ -20,7 +20,6 @@ obj-$(CONFIG_PMAC_SMU) += smu.o
20 20
21obj-$(CONFIG_ADB) += adb.o 21obj-$(CONFIG_ADB) += adb.o
22obj-$(CONFIG_ADB_MACII) += via-macii.o 22obj-$(CONFIG_ADB_MACII) += via-macii.o
23obj-$(CONFIG_ADB_MACIISI) += via-maciisi.o
24obj-$(CONFIG_ADB_IOP) += adb-iop.o 23obj-$(CONFIG_ADB_IOP) += adb-iop.o
25obj-$(CONFIG_ADB_PMU68K) += via-pmu68k.o 24obj-$(CONFIG_ADB_PMU68K) += via-pmu68k.o
26obj-$(CONFIG_ADB_MACIO) += macio-adb.o 25obj-$(CONFIG_ADB_MACIO) += macio-adb.o
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index 226179b975a0..152414e6378a 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -48,7 +48,6 @@
48EXPORT_SYMBOL(adb_client_list); 48EXPORT_SYMBOL(adb_client_list);
49 49
50extern struct adb_driver via_macii_driver; 50extern struct adb_driver via_macii_driver;
51extern struct adb_driver via_maciisi_driver;
52extern struct adb_driver via_cuda_driver; 51extern struct adb_driver via_cuda_driver;
53extern struct adb_driver adb_iop_driver; 52extern struct adb_driver adb_iop_driver;
54extern struct adb_driver via_pmu_driver; 53extern struct adb_driver via_pmu_driver;
@@ -59,9 +58,6 @@ static struct adb_driver *adb_driver_list[] = {
59#ifdef CONFIG_ADB_MACII 58#ifdef CONFIG_ADB_MACII
60 &via_macii_driver, 59 &via_macii_driver,
61#endif 60#endif
62#ifdef CONFIG_ADB_MACIISI
63 &via_maciisi_driver,
64#endif
65#ifdef CONFIG_ADB_CUDA 61#ifdef CONFIG_ADB_CUDA
66 &via_cuda_driver, 62 &via_cuda_driver,
67#endif 63#endif
diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c
index 1a742bd9f612..c60415958dfe 100644
--- a/drivers/macintosh/via-cuda.c
+++ b/drivers/macintosh/via-cuda.c
@@ -205,12 +205,13 @@ int __init find_via_cuda(void)
205 struct adb_request req; 205 struct adb_request req;
206 int err; 206 int err;
207 207
208 if (macintosh_config->adb_type != MAC_ADB_CUDA) 208 if (macintosh_config->adb_type != MAC_ADB_CUDA &&
209 macintosh_config->adb_type != MAC_ADB_EGRET)
209 return 0; 210 return 0;
210 211
211 via = via1; 212 via = via1;
212 cuda_state = idle; 213 cuda_state = idle;
213 mcu_is_egret = false; 214 mcu_is_egret = macintosh_config->adb_type == MAC_ADB_EGRET;
214 215
215 err = cuda_init_via(); 216 err = cuda_init_via();
216 if (err) { 217 if (err) {
@@ -323,7 +324,8 @@ cuda_probe(void)
323 if (sys_ctrler != SYS_CTRLER_CUDA) 324 if (sys_ctrler != SYS_CTRLER_CUDA)
324 return -ENODEV; 325 return -ENODEV;
325#else 326#else
326 if (macintosh_config->adb_type != MAC_ADB_CUDA) 327 if (macintosh_config->adb_type != MAC_ADB_CUDA &&
328 macintosh_config->adb_type != MAC_ADB_EGRET)
327 return -ENODEV; 329 return -ENODEV;
328#endif 330#endif
329 if (via == NULL) 331 if (via == NULL)
diff --git a/drivers/macintosh/via-maciisi.c b/drivers/macintosh/via-maciisi.c
deleted file mode 100644
index 34d02a91b29f..000000000000
--- a/drivers/macintosh/via-maciisi.c
+++ /dev/null
@@ -1,677 +0,0 @@
1/*
2 * Device driver for the IIsi-style ADB on some Mac LC and II-class machines
3 *
4 * Based on via-cuda.c and via-macii.c, as well as the original
5 * adb-bus.c, which in turn is somewhat influenced by (but uses no
6 * code from) the NetBSD HWDIRECT ADB code. Original IIsi driver work
7 * was done by Robert Thompson and integrated into the old style
8 * driver by Michael Schmitz.
9 *
10 * Original sources (c) Alan Cox, Paul Mackerras, and others.
11 *
12 * Rewritten for Unified ADB by David Huggins-Daines <dhd@debian.org>
13 *
14 * 7/13/2000- extensive changes by Andrew McPherson <andrew@macduff.dhs.org>
15 * Works about 30% of the time now.
16 */
17
18#include <linux/types.h>
19#include <linux/errno.h>
20#include <linux/kernel.h>
21#include <linux/adb.h>
22#include <linux/cuda.h>
23#include <linux/delay.h>
24#include <linux/interrupt.h>
25#include <asm/macintosh.h>
26#include <asm/macints.h>
27#include <asm/mac_via.h>
28
29static volatile unsigned char *via;
30
31/* VIA registers - spaced 0x200 bytes apart - only the ones we actually use */
32#define RS 0x200 /* skip between registers */
33#define B 0 /* B-side data */
34#define A RS /* A-side data */
35#define DIRB (2*RS) /* B-side direction (1=output) */
36#define DIRA (3*RS) /* A-side direction (1=output) */
37#define SR (10*RS) /* Shift register */
38#define ACR (11*RS) /* Auxiliary control register */
39#define IFR (13*RS) /* Interrupt flag register */
40#define IER (14*RS) /* Interrupt enable register */
41
42/* Bits in B data register: all active low */
43#define TREQ 0x08 /* Transfer request (input) */
44#define TACK 0x10 /* Transfer acknowledge (output) */
45#define TIP 0x20 /* Transfer in progress (output) */
46#define ST_MASK 0x30 /* mask for selecting ADB state bits */
47
48/* Bits in ACR */
49#define SR_CTRL 0x1c /* Shift register control bits */
50#define SR_EXT 0x0c /* Shift on external clock */
51#define SR_OUT 0x10 /* Shift out if 1 */
52
53/* Bits in IFR and IER */
54#define IER_SET 0x80 /* set bits in IER */
55#define IER_CLR 0 /* clear bits in IER */
56#define SR_INT 0x04 /* Shift register full/empty */
57#define SR_DATA 0x08 /* Shift register data */
58#define SR_CLOCK 0x10 /* Shift register clock */
59
60#define ADB_DELAY 150
61
62#undef DEBUG_MACIISI_ADB
63
64static struct adb_request* current_req;
65static struct adb_request* last_req;
66static unsigned char maciisi_rbuf[16];
67static unsigned char *reply_ptr;
68static int data_index;
69static int reading_reply;
70static int reply_len;
71static int tmp;
72static int need_sync;
73
74static enum maciisi_state {
75 idle,
76 sending,
77 reading,
78} maciisi_state;
79
80static int maciisi_probe(void);
81static int maciisi_init(void);
82static int maciisi_send_request(struct adb_request* req, int sync);
83static void maciisi_sync(struct adb_request *req);
84static int maciisi_write(struct adb_request* req);
85static irqreturn_t maciisi_interrupt(int irq, void* arg);
86static void maciisi_input(unsigned char *buf, int nb);
87static int maciisi_init_via(void);
88static void maciisi_poll(void);
89static int maciisi_start(void);
90
91struct adb_driver via_maciisi_driver = {
92 "Mac IIsi",
93 maciisi_probe,
94 maciisi_init,
95 maciisi_send_request,
96 NULL, /* maciisi_adb_autopoll, */
97 maciisi_poll,
98 NULL /* maciisi_reset_adb_bus */
99};
100
101static int
102maciisi_probe(void)
103{
104 if (macintosh_config->adb_type != MAC_ADB_IISI)
105 return -ENODEV;
106
107 via = via1;
108 return 0;
109}
110
111static int
112maciisi_init(void)
113{
114 int err;
115
116 if (via == NULL)
117 return -ENODEV;
118
119 if ((err = maciisi_init_via())) {
120 printk(KERN_ERR "maciisi_init: maciisi_init_via() failed, code %d\n", err);
121 via = NULL;
122 return err;
123 }
124
125 if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, 0, "ADB",
126 maciisi_interrupt)) {
127 printk(KERN_ERR "maciisi_init: can't get irq %d\n", IRQ_MAC_ADB);
128 return -EAGAIN;
129 }
130
131 printk("adb: Mac IIsi driver v0.2 for Unified ADB.\n");
132 return 0;
133}
134
135/* Flush data from the ADB controller */
136static void
137maciisi_stfu(void)
138{
139 int status = via[B] & (TIP|TREQ);
140
141 if (status & TREQ) {
142#ifdef DEBUG_MACIISI_ADB
143 printk (KERN_DEBUG "maciisi_stfu called with TREQ high!\n");
144#endif
145 return;
146 }
147
148 udelay(ADB_DELAY);
149 via[ACR] &= ~SR_OUT;
150 via[IER] = IER_CLR | SR_INT;
151
152 udelay(ADB_DELAY);
153
154 status = via[B] & (TIP|TREQ);
155
156 if (!(status & TREQ))
157 {
158 via[B] |= TIP;
159
160 while(1)
161 {
162 int poll_timeout = ADB_DELAY * 5;
163 /* Poll for SR interrupt */
164 while (!(via[IFR] & SR_INT) && poll_timeout-- > 0)
165 status = via[B] & (TIP|TREQ);
166
167 tmp = via[SR]; /* Clear shift register */
168#ifdef DEBUG_MACIISI_ADB
169 printk(KERN_DEBUG "maciisi_stfu: status %x timeout %d data %x\n",
170 status, poll_timeout, tmp);
171#endif
172 if(via[B] & TREQ)
173 break;
174
175 /* ACK on-off */
176 via[B] |= TACK;
177 udelay(ADB_DELAY);
178 via[B] &= ~TACK;
179 }
180
181 /* end frame */
182 via[B] &= ~TIP;
183 udelay(ADB_DELAY);
184 }
185
186 via[IER] = IER_SET | SR_INT;
187}
188
189/* All specifically VIA-related initialization goes here */
190static int
191maciisi_init_via(void)
192{
193 int i;
194
195 /* Set the lines up. We want TREQ as input TACK|TIP as output */
196 via[DIRB] = (via[DIRB] | TACK | TIP) & ~TREQ;
197 /* Shift register on input */
198 via[ACR] = (via[ACR] & ~SR_CTRL) | SR_EXT;
199#ifdef DEBUG_MACIISI_ADB
200 printk(KERN_DEBUG "maciisi_init_via: initial status %x\n", via[B] & (TIP|TREQ));
201#endif
202 /* Wipe any pending data and int */
203 tmp = via[SR];
204 /* Enable keyboard interrupts */
205 via[IER] = IER_SET | SR_INT;
206 /* Set initial state: idle */
207 via[B] &= ~(TACK|TIP);
208 /* Clear interrupt bit */
209 via[IFR] = SR_INT;
210
211 for(i = 0; i < 60; i++) {
212 udelay(ADB_DELAY);
213 maciisi_stfu();
214 udelay(ADB_DELAY);
215 if(via[B] & TREQ)
216 break;
217 }
218 if (i == 60)
219 printk(KERN_ERR "maciisi_init_via: bus jam?\n");
220
221 maciisi_state = idle;
222 need_sync = 0;
223
224 return 0;
225}
226
227/* Send a request, possibly waiting for a reply */
228static int
229maciisi_send_request(struct adb_request* req, int sync)
230{
231 int i;
232
233#ifdef DEBUG_MACIISI_ADB
234 static int dump_packet = 0;
235#endif
236
237 if (via == NULL) {
238 req->complete = 1;
239 return -ENXIO;
240 }
241
242#ifdef DEBUG_MACIISI_ADB
243 if (dump_packet) {
244 printk(KERN_DEBUG "maciisi_send_request:");
245 for (i = 0; i < req->nbytes; i++) {
246 printk(" %.2x", req->data[i]);
247 }
248 printk(" sync %d\n", sync);
249 }
250#endif
251
252 req->reply_expected = 1;
253
254 i = maciisi_write(req);
255 if (i)
256 {
257 /* Normally, if a packet requires syncing, that happens at the end of
258 * maciisi_send_request. But if the transfer fails, it will be restarted
259 * by maciisi_interrupt(). We use need_sync to tell maciisi_interrupt
260 * when to sync a packet that it sends out.
261 *
262 * Suggestions on a better way to do this are welcome.
263 */
264 if(i == -EBUSY && sync)
265 need_sync = 1;
266 else
267 need_sync = 0;
268 return i;
269 }
270 if(sync)
271 maciisi_sync(req);
272
273 return 0;
274}
275
276/* Poll the ADB chip until the request completes */
277static void maciisi_sync(struct adb_request *req)
278{
279 int count = 0;
280
281#ifdef DEBUG_MACIISI_ADB
282 printk(KERN_DEBUG "maciisi_sync called\n");
283#endif
284
285 /* If for some reason the ADB chip shuts up on us, we want to avoid an endless loop. */
286 while (!req->complete && count++ < 50) {
287 maciisi_poll();
288 }
289 /* This could be BAD... when the ADB controller doesn't respond
290 * for this long, it's probably not coming back :-( */
291 if (count > 50) /* Hopefully shouldn't happen */
292 printk(KERN_ERR "maciisi_send_request: poll timed out!\n");
293}
294
295int
296maciisi_request(struct adb_request *req, void (*done)(struct adb_request *),
297 int nbytes, ...)
298{
299 va_list list;
300 int i;
301
302 req->nbytes = nbytes;
303 req->done = done;
304 req->reply_expected = 0;
305 va_start(list, nbytes);
306 for (i = 0; i < nbytes; i++)
307 req->data[i++] = va_arg(list, int);
308 va_end(list);
309
310 return maciisi_send_request(req, 1);
311}
312
313/* Enqueue a request, and run the queue if possible */
314static int
315maciisi_write(struct adb_request* req)
316{
317 unsigned long flags;
318 int i;
319
320 /* We will accept CUDA packets - the VIA sends them to us, so
321 it figures that we should be able to send them to it */
322 if (req->nbytes < 2 || req->data[0] > CUDA_PACKET) {
323 printk(KERN_ERR "maciisi_write: packet too small or not an ADB or CUDA packet\n");
324 req->complete = 1;
325 return -EINVAL;
326 }
327 req->next = NULL;
328 req->sent = 0;
329 req->complete = 0;
330 req->reply_len = 0;
331
332 local_irq_save(flags);
333
334 if (current_req) {
335 last_req->next = req;
336 last_req = req;
337 } else {
338 current_req = req;
339 last_req = req;
340 }
341 if (maciisi_state == idle)
342 {
343 i = maciisi_start();
344 if(i != 0)
345 {
346 local_irq_restore(flags);
347 return i;
348 }
349 }
350 else
351 {
352#ifdef DEBUG_MACIISI_ADB
353 printk(KERN_DEBUG "maciisi_write: would start, but state is %d\n", maciisi_state);
354#endif
355 local_irq_restore(flags);
356 return -EBUSY;
357 }
358
359 local_irq_restore(flags);
360
361 return 0;
362}
363
364static int
365maciisi_start(void)
366{
367 struct adb_request* req;
368 int status;
369
370#ifdef DEBUG_MACIISI_ADB
371 status = via[B] & (TIP | TREQ);
372
373 printk(KERN_DEBUG "maciisi_start called, state=%d, status=%x, ifr=%x\n", maciisi_state, status, via[IFR]);
374#endif
375
376 if (maciisi_state != idle) {
377 /* shouldn't happen */
378 printk(KERN_ERR "maciisi_start: maciisi_start called when driver busy!\n");
379 return -EBUSY;
380 }
381
382 req = current_req;
383 if (req == NULL)
384 return -EINVAL;
385
386 status = via[B] & (TIP|TREQ);
387 if (!(status & TREQ)) {
388#ifdef DEBUG_MACIISI_ADB
389 printk(KERN_DEBUG "maciisi_start: bus busy - aborting\n");
390#endif
391 return -EBUSY;
392 }
393
394 /* Okay, send */
395#ifdef DEBUG_MACIISI_ADB
396 printk(KERN_DEBUG "maciisi_start: sending\n");
397#endif
398 /* Set state to active */
399 via[B] |= TIP;
400 /* ACK off */
401 via[B] &= ~TACK;
402 /* Delay */
403 udelay(ADB_DELAY);
404 /* Shift out and send */
405 via[ACR] |= SR_OUT;
406 via[SR] = req->data[0];
407 data_index = 1;
408 /* ACK on */
409 via[B] |= TACK;
410 maciisi_state = sending;
411
412 return 0;
413}
414
415void
416maciisi_poll(void)
417{
418 unsigned long flags;
419
420 local_irq_save(flags);
421 if (via[IFR] & SR_INT) {
422 maciisi_interrupt(0, NULL);
423 }
424 else /* avoid calling this function too quickly in a loop */
425 udelay(ADB_DELAY);
426
427 local_irq_restore(flags);
428}
429
430/* Shift register interrupt - this is *supposed* to mean that the
431 register is either full or empty. In practice, I have no idea what
432 it means :( */
433static irqreturn_t
434maciisi_interrupt(int irq, void* arg)
435{
436 int status;
437 struct adb_request *req;
438#ifdef DEBUG_MACIISI_ADB
439 static int dump_reply = 0;
440#endif
441 int i;
442 unsigned long flags;
443
444 local_irq_save(flags);
445
446 status = via[B] & (TIP|TREQ);
447#ifdef DEBUG_MACIISI_ADB
448 printk(KERN_DEBUG "state %d status %x ifr %x\n", maciisi_state, status, via[IFR]);
449#endif
450
451 if (!(via[IFR] & SR_INT)) {
452 /* Shouldn't happen, we hope */
453 printk(KERN_ERR "maciisi_interrupt: called without interrupt flag set\n");
454 local_irq_restore(flags);
455 return IRQ_NONE;
456 }
457
458 /* Clear the interrupt */
459 /* via[IFR] = SR_INT; */
460
461 switch_start:
462 switch (maciisi_state) {
463 case idle:
464 if (status & TIP)
465 printk(KERN_ERR "maciisi_interrupt: state is idle but TIP asserted!\n");
466
467 if(!reading_reply)
468 udelay(ADB_DELAY);
469 /* Shift in */
470 via[ACR] &= ~SR_OUT;
471 /* Signal start of frame */
472 via[B] |= TIP;
473 /* Clear the interrupt (throw this value on the floor, it's useless) */
474 tmp = via[SR];
475 /* ACK adb chip, high-low */
476 via[B] |= TACK;
477 udelay(ADB_DELAY);
478 via[B] &= ~TACK;
479 reply_len = 0;
480 maciisi_state = reading;
481 if (reading_reply) {
482 reply_ptr = current_req->reply;
483 } else {
484 reply_ptr = maciisi_rbuf;
485 }
486 break;
487
488 case sending:
489 /* via[SR]; */
490 /* Set ACK off */
491 via[B] &= ~TACK;
492 req = current_req;
493
494 if (!(status & TREQ)) {
495 /* collision */
496 printk(KERN_ERR "maciisi_interrupt: send collision\n");
497 /* Set idle and input */
498 via[ACR] &= ~SR_OUT;
499 tmp = via[SR];
500 via[B] &= ~TIP;
501 /* Must re-send */
502 reading_reply = 0;
503 reply_len = 0;
504 maciisi_state = idle;
505 udelay(ADB_DELAY);
506 /* process this now, because the IFR has been cleared */
507 goto switch_start;
508 }
509
510 udelay(ADB_DELAY);
511
512 if (data_index >= req->nbytes) {
513 /* Sent the whole packet, put the bus back in idle state */
514 /* Shift in, we are about to read a reply (hopefully) */
515 via[ACR] &= ~SR_OUT;
516 tmp = via[SR];
517 /* End of frame */
518 via[B] &= ~TIP;
519 req->sent = 1;
520 maciisi_state = idle;
521 if (req->reply_expected) {
522 /* Note: only set this once we've
523 successfully sent the packet */
524 reading_reply = 1;
525 } else {
526 current_req = req->next;
527 if (req->done)
528 (*req->done)(req);
529 /* Do any queued requests now */
530 i = maciisi_start();
531 if(i == 0 && need_sync) {
532 /* Packet needs to be synced */
533 maciisi_sync(current_req);
534 }
535 if(i != -EBUSY)
536 need_sync = 0;
537 }
538 } else {
539 /* Sending more stuff */
540 /* Shift out */
541 via[ACR] |= SR_OUT;
542 /* Write */
543 via[SR] = req->data[data_index++];
544 /* Signal 'byte ready' */
545 via[B] |= TACK;
546 }
547 break;
548
549 case reading:
550 /* Shift in */
551 /* via[ACR] &= ~SR_OUT; */ /* Not in 2.2 */
552 if (reply_len++ > 16) {
553 printk(KERN_ERR "maciisi_interrupt: reply too long, aborting read\n");
554 via[B] |= TACK;
555 udelay(ADB_DELAY);
556 via[B] &= ~(TACK|TIP);
557 maciisi_state = idle;
558 i = maciisi_start();
559 if(i == 0 && need_sync) {
560 /* Packet needs to be synced */
561 maciisi_sync(current_req);
562 }
563 if(i != -EBUSY)
564 need_sync = 0;
565 break;
566 }
567 /* Read data */
568 *reply_ptr++ = via[SR];
569 status = via[B] & (TIP|TREQ);
570 /* ACK on/off */
571 via[B] |= TACK;
572 udelay(ADB_DELAY);
573 via[B] &= ~TACK;
574 if (!(status & TREQ))
575 break; /* more stuff to deal with */
576
577 /* end of frame */
578 via[B] &= ~TIP;
579 tmp = via[SR]; /* That's what happens in 2.2 */
580 udelay(ADB_DELAY); /* Give controller time to recover */
581
582 /* end of packet, deal with it */
583 if (reading_reply) {
584 req = current_req;
585 req->reply_len = reply_ptr - req->reply;
586 if (req->data[0] == ADB_PACKET) {
587 /* Have to adjust the reply from ADB commands */
588 if (req->reply_len <= 2 || (req->reply[1] & 2) != 0) {
589 /* the 0x2 bit indicates no response */
590 req->reply_len = 0;
591 } else {
592 /* leave just the command and result bytes in the reply */
593 req->reply_len -= 2;
594 memmove(req->reply, req->reply + 2, req->reply_len);
595 }
596 }
597#ifdef DEBUG_MACIISI_ADB
598 if (dump_reply) {
599 int i;
600 printk(KERN_DEBUG "maciisi_interrupt: reply is ");
601 for (i = 0; i < req->reply_len; ++i)
602 printk(" %.2x", req->reply[i]);
603 printk("\n");
604 }
605#endif
606 req->complete = 1;
607 current_req = req->next;
608 if (req->done)
609 (*req->done)(req);
610 /* Obviously, we got it */
611 reading_reply = 0;
612 } else {
613 maciisi_input(maciisi_rbuf, reply_ptr - maciisi_rbuf);
614 }
615 maciisi_state = idle;
616 status = via[B] & (TIP|TREQ);
617 if (!(status & TREQ)) {
618 /* Timeout?! More likely, another packet coming in already */
619#ifdef DEBUG_MACIISI_ADB
620 printk(KERN_DEBUG "extra data after packet: status %x ifr %x\n",
621 status, via[IFR]);
622#endif
623#if 0
624 udelay(ADB_DELAY);
625 via[B] |= TIP;
626
627 maciisi_state = reading;
628 reading_reply = 0;
629 reply_ptr = maciisi_rbuf;
630#else
631 /* Process the packet now */
632 reading_reply = 0;
633 goto switch_start;
634#endif
635 /* We used to do this... but the controller might actually have data for us */
636 /* maciisi_stfu(); */
637 }
638 else {
639 /* Do any queued requests now if possible */
640 i = maciisi_start();
641 if(i == 0 && need_sync) {
642 /* Packet needs to be synced */
643 maciisi_sync(current_req);
644 }
645 if(i != -EBUSY)
646 need_sync = 0;
647 }
648 break;
649
650 default:
651 printk("maciisi_interrupt: unknown maciisi_state %d?\n", maciisi_state);
652 }
653 local_irq_restore(flags);
654 return IRQ_HANDLED;
655}
656
657static void
658maciisi_input(unsigned char *buf, int nb)
659{
660#ifdef DEBUG_MACIISI_ADB
661 int i;
662#endif
663
664 switch (buf[0]) {
665 case ADB_PACKET:
666 adb_input(buf+2, nb-2, buf[1] & 0x40);
667 break;
668 default:
669#ifdef DEBUG_MACIISI_ADB
670 printk(KERN_DEBUG "data from IIsi ADB (%d bytes):", nb);
671 for (i = 0; i < nb; ++i)
672 printk(" %.2x", buf[i]);
673 printk("\n");
674#endif
675 break;
676 }
677}