37#define DRIVERNAME "dev9"
41#define M_PRINTF(format, args...) \
42 printf(MODNAME ": " format, ##args)
45#define BANNER "\nDEV9 device driver v%s - Copyright (c) 2003 Marcus R. Brown\n\n"
48#define SSBUS_R_1418 0xbf801418
49#define SSBUS_R_141c 0xbf80141c
50#define SSBUS_R_1420 0xbf801420
52static int semaAttrGlobal;
53static const char *mod_name;
54static int dev9type = -1;
55static int using_aif = 0;
57static int dma_lock_sem;
60 PC_CARD_TYPE_NONE = 0,
66 PC_CARD_VOLTAGE_INVALID = 0,
72static int pcic_cardtype;
73static int pcic_voltage;
75static s16 eeprom_data[5];
79typedef int (*dev9IntrDispatchCb_t)(
int flag);
80static dev9IntrDispatchCb_t p_dev9_intr_cb = NULL;
81static void dev9RegisterIntrDispatchCb(dev9IntrDispatchCb_t callback);
85static dev9_intr_cb_t dev9_intr_cbs[16];
87static aif_intr_cb_t aif_intr_cbs[AIF_INUM_COUNT];
90static dev9_shutdown_cb_t dev9_shutdown_cbs[16];
92static dev9_shutdown_cb_t aif_shutdown_cbs[AIF_INUM_COUNT];
95static dev9_dma_cb_t dev9_predma_cbs[4], dev9_postdma_cbs[4];
97static u8 dev9_has_dvr_capability = 0;
99static int dev9_intr_dispatch(
int flag);
101static void dev9_set_stat(
int stat);
102static int dev9_ssbus_mode(
int mode);
103static int dev9_device_probe(
void);
104static int dev9_device_reset(
void);
105static int dev9_card_find_manfid(u32 manfid);
107static int read_eeprom_data(
void);
108static int dev9_init(
int sema_attr);
109static int speed_device_init(
void);
111static void pcmcia_set_stat(
int stat);
112static int pcic_ssbus_mode(
int mode);
113static int pcmcia_device_probe(
void);
114static int pcmcia_device_reset(
void);
115static int card_find_manfid(u32 manfid);
116static int pcmcia_init(
int sema_attr);
118static void expbay_set_stat(
int stat);
119static int expbay_device_probe(
void);
120static int expbay_device_reset(
void);
121static int expbay_init(
int sema_attr);
125static int dev9x_dummy(
void)
130static int dev9x_devctl(
iop_file_t *f,
const char *name,
int cmd,
void *args,
unsigned int arglen,
void *buf,
unsigned int buflen)
144 dev9ControlPIO3(((u32 *)args)[0]);
147 dev9LED2Ctl(((u32 *)args)[0]);
156 (
void *)&dev9x_dummy,
157 (
void *)&dev9x_dummy,
158 (
void *)&dev9x_dummy,
159 (
void *)&dev9x_dummy,
160 (
void *)&dev9x_dummy,
161 (
void *)&dev9x_dummy,
162 (
void *)&dev9x_dummy,
163 (
void *)&dev9x_dummy,
164 (
void *)&dev9x_dummy,
165 (
void *)&dev9x_dummy,
166 (
void *)&dev9x_dummy,
167 (
void *)&dev9x_dummy,
168 (
void *)&dev9x_dummy,
169 (
void *)&dev9x_dummy,
170 (
void *)&dev9x_dummy,
171 (
void *)&dev9x_dummy,
172 (
void *)&dev9x_dummy,
173 (
void *)&dev9x_dummy,
174 (
void *)&dev9x_dummy,
175 (
void *)&dev9x_dummy,
176 (
void *)&dev9x_dummy,
177 (
void *)&dev9x_dummy,
178 (
void *)&dev9x_dummy,
180 (
void *)&dev9x_dummy,
181 (
void *)&dev9x_dummy,
182 (
void *)&dev9x_dummy,
194static int print_help(
void)
197 " %s [-sa] <attribute>]\n"
198 " -sa You can specify attibute of sempahore for queuing thread.\n"
199 " List of possible <attribute>:\n"
200 " SA_THPRI(default), SA_THFIFO\n",
203 return MODULE_NO_RESIDENT_END;
206int _start(
int argc,
char *argv[])
209 const char *pModName;
213 semaAttrGlobal = SA_THPRI;
215 printf(BANNER, VERSION);
217 mod_name = (pModName = strrchr(argv[0],
'/')) != NULL ? pModName + 1 : argv[0];
219 for (--argc, ++argv; argc > 0; argc--, argv++) {
220 if ((*argv)[0] !=
'-')
223 if (strcmp(
"-sa", *argv) == 0) {
227 if (strcmp(
"SA_THFIFO", *argv) == 0) {
228 semaAttrGlobal = SA_THFIFO;
229 }
else if (strcmp(
"SA_THPRI", *argv) == 0) {
230 semaAttrGlobal = SA_THPRI;
242 for (idx = 0; idx < 16; idx++)
243 dev9_shutdown_cbs[idx] = NULL;
245#ifdef DEV9_ENABLE_AIF
246 for (idx = 0; idx < AIF_INUM_COUNT; idx++)
247 aif_shutdown_cbs[idx] = NULL;
250 dev9hw = DEV9_REG(DEV9_R_REV) & 0xf0;
251 if (dev9hw == 0x20) {
252 dev9type = DEV9_TYPE_PCMCIA;
253 M_PRINTF(
"CXD9566 detected.\n");
254 res = pcmcia_init(semaAttrGlobal);
255 }
else if (dev9hw == 0x30) {
256 dev9type = DEV9_TYPE_EXPBAY;
257 M_PRINTF(
"CXD9611 detected.\n");
258 res = expbay_init(semaAttrGlobal);
260 M_PRINTF(
"unknown dev9 hardware.\n");
261 res = MODULE_NO_RESIDENT_END;
267 DelDrv(dev9x_device.name);
268 if (AddDrv(&dev9x_device) != 0) {
269 return MODULE_NO_RESIDENT_END;
272 return MODULE_RESIDENT_END;
275int _exit(
void) {
return MODULE_RESIDENT_END; }
278void SpdRegisterIntrHandler(
int intr, dev9_intr_cb_t cb)
280 dev9_intr_cbs[intr] = cb;
284void dev9RegisterPreDmaCb(
int ctrl, dev9_dma_cb_t cb)
286 dev9_predma_cbs[ctrl] = cb;
290void dev9RegisterPostDmaCb(
int ctrl, dev9_dma_cb_t cb)
292 dev9_postdma_cbs[ctrl] = cb;
296static int dev9_intr_dispatch(
int flag)
302 for (i = 0; i < 16; i++)
303 if (dev9_intr_cbs[i] != NULL)
304 dev9_intr_cbs[i](flag);
307 while (SPD_REG16(SPD_R_INTR_STAT) & SPD_REG16(SPD_R_INTR_MASK)) {
308 for (i = 0; i < 16; i++) {
309 if (dev9_intr_cbs[i] != NULL) {
310 bit = (SPD_REG16(SPD_R_INTR_STAT) &
311 SPD_REG16(SPD_R_INTR_MASK)) >>
314 dev9_intr_cbs[i](flag);
322static void dev9_set_stat(
int stat)
325 case DEV9_TYPE_PCMCIA:
326 pcmcia_set_stat(stat);
328 case DEV9_TYPE_EXPBAY:
329 expbay_set_stat(stat);
334static int dev9_ssbus_mode(
int mode)
337 case DEV9_TYPE_PCMCIA:
338 return pcic_ssbus_mode(mode);
339 case DEV9_TYPE_EXPBAY:
346static int dev9_device_probe(
void)
349 case DEV9_TYPE_PCMCIA:
350 return pcmcia_device_probe();
351 case DEV9_TYPE_EXPBAY:
352 return expbay_device_probe();
358static int dev9_device_reset(
void)
361 case DEV9_TYPE_PCMCIA:
362 return pcmcia_device_reset();
363 case DEV9_TYPE_EXPBAY:
364 return expbay_device_reset();
371void Dev9CardStop(
void)
376 for (idx = 0; idx < 16; idx++)
377 if (dev9_shutdown_cbs[idx])
378 dev9_shutdown_cbs[idx]();
380#ifdef DEV9_ENABLE_AIF
381 for (idx = 0; idx < AIF_INUM_COUNT; idx++)
382 if (aif_shutdown_cbs[idx])
383 aif_shutdown_cbs[idx]();
386 if (dev9type == DEV9_TYPE_PCMCIA) {
387 DEV9_REG(DEV9_R_POWER) = 0;
388 DEV9_REG(DEV9_R_1474) = 0;
389 }
else if (dev9type == DEV9_TYPE_EXPBAY) {
390 DEV9_REG(DEV9_R_1466) = 1;
391 DEV9_REG(DEV9_R_1464) = 0;
392 DEV9_REG(DEV9_R_1460) = DEV9_REG(DEV9_R_1464);
393 DEV9_REG(DEV9_R_POWER) = DEV9_REG(DEV9_R_POWER) & ~4;
394 DEV9_REG(DEV9_R_POWER) = DEV9_REG(DEV9_R_POWER) & ~1;
396 DelayThread(1000000);
399static int dev9_card_find_manfid(u32 manfid)
402 case DEV9_TYPE_PCMCIA:
403 return card_find_manfid(manfid);
404 case DEV9_TYPE_EXPBAY:
412void SpdIntrEnable(
int mask)
418 SPD_REG16(SPD_R_INTR_MASK) = SPD_REG16(SPD_R_INTR_MASK) | mask;
423void SpdIntrDisable(
int mask)
429 SPD_REG16(SPD_R_INTR_MASK) = SPD_REG16(SPD_R_INTR_MASK) & ~mask;
434int SpdDmaTransfer(
int device,
void *buf,
int bcr,
int dir)
438 int res, dmactrl, OldState;
442 }
else if (device >= 2) {
443 if (dev9_predma_cbs[device] == NULL)
445 if (dev9_postdma_cbs[device] == NULL)
449 if ((res = WaitSema(dma_lock_sem)) < 0)
459#ifdef DEV9_PSX_SUPPORT
472 SPD_REG16(SPD_R_DMA_CTRL) = (SPD_REG16(SPD_R_REV_1) < 17) ? (dmactrl & 0x03) | 0x04 : dmactrl | 0x06;
474 if (dev9_predma_cbs[device])
475 dev9_predma_cbs[device](bcr, dir);
477 dev9_chan->madr = (u32)buf;
481 dev9_chan->bcr = bcr;
488 if (dev9_postdma_cbs[device])
489 dev9_postdma_cbs[device](bcr, dir);
491 SignalSema(dma_lock_sem);
495static int read_eeprom_data(
void)
501 if (eeprom_data[0] < 0)
504 SPD_REG8(SPD_R_PIO_DIR) = 0xe0 | (dev9_has_dvr_capability ? 7 : 1);
506 SPD_REG8(SPD_R_PIO_DATA) = 0x80;
509 for (i = 0; i < 2; i++) {
510 SPD_REG8(SPD_R_PIO_DATA) = 0xa0;
512 SPD_REG8(SPD_R_PIO_DATA) = 0xe0;
515 for (i = 0; i < 7; i++) {
516 SPD_REG8(SPD_R_PIO_DATA) = 0x80;
518 SPD_REG8(SPD_R_PIO_DATA) = 0xc0;
521 SPD_REG8(SPD_R_PIO_DATA) = 0xc0;
524 val = SPD_REG8(SPD_R_PIO_DATA);
527 SPD_REG8(SPD_R_PIO_DATA) = 0;
534 SPD_REG8(SPD_R_PIO_DATA) = 0x80;
538 for (i = 0; i < 4; i++) {
539 eeprom_data[i + 1] = 0;
541 for (j = 15; j >= 0; j--) {
542 SPD_REG8(SPD_R_PIO_DATA) = 0xc0;
544 val = SPD_REG8(SPD_R_PIO_DATA);
546 eeprom_data[i + 1] |= (1 << j);
547 SPD_REG8(SPD_R_PIO_DATA) = 0x80;
552 SPD_REG8(SPD_R_PIO_DATA) = 0;
558 SPD_REG8(SPD_R_PIO_DIR) = dev9_has_dvr_capability ? 7 : 1;
563int SpdGetEthernetID(u16 *buf)
569 if (eeprom_data[0] < 0)
573 for (i = 0; i < 4; i++)
574 buf[i] = eeprom_data[i + 1];
591void SpdSetLED(
int ctl)
594 if (dev9_has_dvr_capability) {
595 SPD_REG8(SPD_R_PIO_DIR) |= 1;
596 SPD_REG8(SPD_R_PIO_DATA) = (SPD_REG8(SPD_R_PIO_DATA) & 0xE) | (ctl ? 0 : 1);
598 SPD_REG8(SPD_R_PIO_DATA) = (ctl == 0);
603void dev9LED2Ctl(
int ctl)
605 if (dev9_has_dvr_capability) {
607 SPD_REG8(SPD_R_PIO_DIR) |= 2;
609 SPD_REG8(SPD_R_PIO_DATA) = (SPD_REG8(SPD_R_PIO_DATA) & 0xD) | (ctl ? 0 : 2);
619void dev9ControlPIO3(
int ctl)
621 if (dev9_has_dvr_capability) {
623 SPD_REG8(SPD_R_PIO_DIR) |= 4;
625 SPD_REG8(SPD_R_PIO_DATA) = (SPD_REG8(SPD_R_PIO_DATA) & 0xB) | (ctl ? 0 : 4);
630static void dev9RegisterIntrDispatchCb(dev9IntrDispatchCb_t callback)
632 p_dev9_intr_cb = callback;
636int Dev9RegisterPowerOffHandler(
int idx, dev9_shutdown_cb_t cb)
639 dev9_shutdown_cbs[idx] = cb;
645static int dev9_init(
int sema_attr)
650 sema.attr = sema_attr;
653 if ((dma_lock_sem = CreateSema(&sema)) < 0)
658 dmac_set_dpcr2(dmac_get_dpcr2() | 0x80);
662 dev9_set_stat(0x103);
665 SpdIntrDisable(0xffff);
667#ifdef DEV9_ENABLE_AIF
669 aifIntrDisable(0xffff);
673 dev9RegisterIntrDispatchCb(&dev9_intr_dispatch);
676 for (i = 0; i < 16; i++)
677 dev9_intr_cbs[i] = NULL;
678#ifdef DEV9_ENABLE_AIF
679 for (i = 0; i < AIF_INUM_COUNT; i++)
680 aif_intr_cbs[i] = NULL;
683 for (i = 0; i < 4; i++) {
684 dev9_predma_cbs[i] = NULL;
685 dev9_postdma_cbs[i] = NULL;
699#ifndef DEV9_SKIP_SMAP_INIT
700static int dev9_smap_read_phy(
volatile u8 *emac3_regbase,
unsigned int address,
unsigned int *data)
702 unsigned int i, PHYRegisterValue;
705 PHYRegisterValue = (address & SMAP_E3_PHY_REG_ADDR_MSK) | SMAP_E3_PHY_READ | ((SMAP_DsPHYTER_ADDRESS & SMAP_E3_PHY_ADDR_MSK) << SMAP_E3_PHY_ADDR_BITSFT);
709 SMAP_EMAC3_SET(SMAP_R_EMAC3_STA_CTRL, PHYRegisterValue);
715 result >>= SMAP_E3_PHY_DATA_BITSFT;
733static int dev9_smap_write_phy(
volatile u8 *emac3_regbase,
unsigned char address,
unsigned short int value)
735 unsigned int i, PHYRegisterValue;
737 PHYRegisterValue = (address & SMAP_E3_PHY_REG_ADDR_MSK) | SMAP_E3_PHY_WRITE | ((SMAP_DsPHYTER_ADDRESS & SMAP_E3_PHY_ADDR_MSK) << SMAP_E3_PHY_ADDR_BITSFT);
738 PHYRegisterValue |= ((
unsigned int)value) << SMAP_E3_PHY_DATA_BITSFT;
741 SMAP_EMAC3_SET(SMAP_R_EMAC3_STA_CTRL, PHYRegisterValue);
749 return ((i >= 100) ? 1 : 0);
752static int dev9_smap_init(
void)
763 if (!(SPD_REG16(SPD_R_REV_3) & SPD_CAPS_SMAP)
764#ifdef DEV9_GAMESTAR_WORKAROUND
769 || (SPD_REG16(0x20) != 1)
774 SMAP_REG8(SMAP_R_TXFIFO_CTRL) = SMAP_TXFIFO_RESET;
775 for (i = 9; SMAP_REG8(SMAP_R_TXFIFO_CTRL) & SMAP_TXFIFO_RESET; i--) {
781 SMAP_REG8(SMAP_R_RXFIFO_CTRL) = SMAP_RXFIFO_RESET;
782 for (i = 9; SMAP_REG8(SMAP_R_RXFIFO_CTRL) & SMAP_RXFIFO_RESET; i--) {
788 SMAP_EMAC3_SET(SMAP_R_EMAC3_MODE0, SMAP_E3_SOFT_RESET);
789 for (i = 9; SMAP_EMAC3_GET(SMAP_R_EMAC3_MODE0) & SMAP_E3_SOFT_RESET; i--) {
796 if (SPD_REG16(SPD_R_REV_1) >= 0x11)
797 SMAP_REG8(SMAP_R_BD_MODE) = SMAP_BD_SWAP;
799 for (i = 0; i < SMAP_BD_MAX_ENTRY; i++) {
800 tx_bd[i].ctrl_stat = 0;
801 tx_bd[i].reserved = 0;
803 tx_bd[i].pointer = 0;
806 for (i = 0; i < SMAP_BD_MAX_ENTRY; i++) {
807 rx_bd[i].ctrl_stat = 0x80;
808 rx_bd[i].reserved = 0;
810 rx_bd[i].pointer = 0;
813 SMAP_REG16(SMAP_R_INTR_CLR) = SMAP_INTR_BITMSK;
814 if (SPD_REG16(SPD_R_REV_1) < 0x11)
817 SMAP_EMAC3_SET(SMAP_R_EMAC3_MODE1, SMAP_E3_FDX_ENABLE | SMAP_E3_IGNORE_SQE | SMAP_E3_MEDIA_100M | SMAP_E3_RXFIFO_2K | SMAP_E3_TXFIFO_1K | SMAP_E3_TXREQ0_MULTI | SMAP_E3_TXREQ1_SINGLE);
819 SMAP_EMAC3_SET(SMAP_R_EMAC3_RxMODE, SMAP_E3_RX_RX_RUNT_FRAME | SMAP_E3_RX_RX_FCS_ERR | SMAP_E3_RX_RX_TOO_LONG_ERR | SMAP_E3_RX_RX_IN_RANGE_ERR |
SMAP_E3_RX_PROP_PF | SMAP_E3_RX_PROMISC);
820 SMAP_EMAC3_SET(SMAP_R_EMAC3_INTR_STAT, SMAP_E3_INTR_TX_ERR_0 | SMAP_E3_INTR_SQE_ERR_0 | SMAP_E3_INTR_DEAD_0);
821 SMAP_EMAC3_SET(SMAP_R_EMAC3_INTR_ENABLE, SMAP_E3_INTR_TX_ERR_0 | SMAP_E3_INTR_SQE_ERR_0 | SMAP_E3_INTR_DEAD_0);
822 SMAP_EMAC3_SET(SMAP_R_EMAC3_ADDR_HI, 0);
823 SMAP_EMAC3_SET(SMAP_R_EMAC3_ADDR_LO, 0);
824 SMAP_EMAC3_SET(SMAP_R_EMAC3_PAUSE_TIMER, 0xFFFF);
825 SMAP_EMAC3_SET(SMAP_R_EMAC3_INTER_FRAME_GAP, 4);
826 SMAP_EMAC3_SET(SMAP_R_EMAC3_TX_THRESHOLD, 12 << SMAP_E3_TX_THRESHLD_BITSFT);
827 SMAP_EMAC3_SET(SMAP_R_EMAC3_RX_WATERMARK, 16 << SMAP_E3_RX_LO_WATER_BITSFT | 128 << SMAP_E3_RX_HI_WATER_BITSFT);
829 dev9_smap_write_phy(emac3_regbase, SMAP_DsPHYTER_BMCR, SMAP_PHY_BMCR_RST);
831 if (dev9_smap_read_phy(emac3_regbase, SMAP_DsPHYTER_BMCR, &value))
833 if (!(value & SMAP_PHY_BMCR_RST))
839 dev9_smap_write_phy(emac3_regbase, SMAP_DsPHYTER_BMCR, SMAP_PHY_BMCR_LPBK | SMAP_PHY_BMCR_100M | SMAP_PHY_BMCR_DUPM);
841 SMAP_EMAC3_SET(SMAP_R_EMAC3_MODE0, SMAP_E3_TXMAC_ENABLE | SMAP_E3_RXMAC_ENABLE);
842 value = SMAP_REG16(SMAP_R_TXFIFO_WR_PTR) + SMAP_TX_BASE;
844 for (i = 0; i < 0x5EA; i += 4)
845 SMAP_REG32(SMAP_R_TXFIFO_DATA) = i;
847 tx_bd[0].length = 0xEA05;
848 tx_bd[0].pointer = (value >> 8) | (value << 8);
849 SMAP_REG8(SMAP_R_TXFIFO_FRAME_INC) = 0;
850 tx_bd[0].ctrl_stat = 0x83;
854 value = SPD_REG16(SPD_R_INTR_STAT);
856 if ((value & (SMAP_INTR_RXEND | SMAP_INTR_TXEND | SMAP_INTR_TXDNV)) == (SMAP_INTR_RXEND | SMAP_INTR_TXEND | SMAP_INTR_TXDNV))
862 SMAP_EMAC3_SET(SMAP_R_EMAC3_MODE0, SMAP_E3_SOFT_RESET);
868static int speed_device_init(
void)
871 const char *spdnames[] = {
"(unknown)",
"TS",
"ES1",
"ES2"};
874#ifndef DEV9_SKIP_SMAP_INIT
880#ifndef DEV9_SKIP_SMAP_INIT
881 for (i = 0; i < 8; i++) {
883 if (dev9_device_probe() < 0) {
884 M_PRINTF(
"No device.\n");
885#ifdef DEV9_ENABLE_AIF
886 return (using_aif ? 0 : -1);
896 if ((res = dev9_card_find_manfid(0xf15300)))
897 M_PRINTF(
"SPEED Lite not found.\n");
899 if (!res && (res = dev9_ssbus_mode(5)))
900 M_PRINTF(
"Unable to change SSBUS mode.\n");
907#ifndef DEV9_SKIP_SMAP_INIT
908 if ((res = dev9_smap_init()) == 0) {
913 DelayThread(4500000);
917 M_PRINTF(
"SMAP initialization failed: %d\n", res);
923 spdrev = SPD_REG16(SPD_R_REV_1);
924 idx = (spdrev & 0xffff) - 14;
927 else if (spdrev < 9 || (spdrev < 16 || spdrev > 17))
930 M_PRINTF(
"SPEED chip '%s', revision %0x\n", spdnames[idx], spdrev);
934static int pcic_get_cardtype(
void)
937 u16 val = DEV9_REG(DEV9_R_1462) & 0x03;
940 return PC_CARD_TYPE_PCMCIA;
942 return PC_CARD_TYPE_CARDBUS;
943 return PC_CARD_TYPE_NONE;
946static int pcic_get_voltage(
void)
949 u16 val = DEV9_REG(DEV9_R_1462) & 0x0c;
952 return PC_CARD_VOLTAGE_04h;
953 if (val == 0 || val == 0x08)
954 return PC_CARD_VOLTAGE_3V;
956 return PC_CARD_VOLTAGE_5V;
957 return PC_CARD_VOLTAGE_INVALID;
960static int pcic_power(
int voltage,
int flag)
964 u16 val = (voltage == 1) << 2;
966 DEV9_REG(DEV9_R_POWER) = 0;
973 DEV9_REG(DEV9_R_POWER) = val;
976 if (DEV9_REG(DEV9_R_1462) & 0x100)
979 DEV9_REG(DEV9_R_POWER) = 0;
980 DEV9_REG(DEV9_R_1464) = cstc1 = DEV9_REG(DEV9_R_1464);
981 DEV9_REG(DEV9_R_1466) = cstc2 = DEV9_REG(DEV9_R_1466);
985static void pcmcia_set_stat(
int stat)
988 u16 val = stat & 0x01;
1008 DEV9_REG(DEV9_R_1476) = val & 0xff;
1011static int pcic_ssbus_mode(
int mode)
1015 u16 stat = DEV9_REG(DEV9_R_1474) & 7;
1017 if (mode != 3 && mode != 5)
1020 DEV9_REG(DEV9_R_1460) = 2;
1025 DEV9_REG(DEV9_R_1474) = 1;
1026 DEV9_REG(DEV9_R_1460) = 1;
1028 DEV9_REG(DEV9_R_1474) = mode;
1029 }
else if (mode == 5) {
1030 DEV9_REG(DEV9_R_1474) = mode;
1031 DEV9_REG(DEV9_R_1460) = 1;
1033 DEV9_REG(DEV9_R_1474) = 7;
1035 _sw(0xe01a3043, SSBUS_R_1418);
1038 DEV9_REG(DEV9_R_POWER) = DEV9_REG(DEV9_R_POWER) & ~1;
1042static int pcmcia_device_probe(
void)
1044 const char *pcic_ct_names[] = {
"No",
"16-bit",
"CardBus"};
1047 pcic_voltage = pcic_get_voltage();
1048 pcic_cardtype = pcic_get_cardtype();
1049 voltage = (pcic_voltage == PC_CARD_VOLTAGE_5V ? 5 : (pcic_voltage == PC_CARD_VOLTAGE_3V ? 3 : 0));
1051 M_PRINTF(
"%s PCMCIA card detected. Vcc = %dV\n",
1052 pcic_ct_names[pcic_cardtype], voltage);
1054 if (pcic_voltage == PC_CARD_VOLTAGE_04h || pcic_cardtype != PC_CARD_TYPE_PCMCIA)
1060static int pcmcia_device_reset(
void)
1066 if ((DEV9_REG(DEV9_R_1462) & 0x03) != 0)
1069 DEV9_REG(DEV9_R_147E) = 1;
1070 if (pcic_power(pcic_voltage, 1) < 0)
1073 DEV9_REG(DEV9_R_POWER) = DEV9_REG(DEV9_R_POWER) | 0x02;
1074 DelayThread(500000);
1076 DEV9_REG(DEV9_R_POWER) = DEV9_REG(DEV9_R_POWER) | 0x01;
1077 DEV9_REG(DEV9_R_1464) = cstc1 = DEV9_REG(DEV9_R_1464);
1078 DEV9_REG(DEV9_R_1466) = cstc2 = DEV9_REG(DEV9_R_1466);
1082static int card_find_manfid(u32 manfid)
1086 u32 spdaddr, spdend, next, tuple;
1089 DEV9_REG(DEV9_R_1460) = 2;
1090 _sw(0x1a00bb, SSBUS_R_1418);
1096 while (spdaddr < spdend) {
1097 hdr = SPD_REG8(spdaddr) & 0xff;
1103 if (spdaddr >= spdend)
1106 ofs = SPD_REG8(spdaddr) & 0xff;
1111 next = spdaddr + (ofs * 2);
1116 if ((spdaddr + 8) >= spdend)
1119 tuple = (SPD_REG8(spdaddr + 2) << 24) |
1120 (SPD_REG8(spdaddr) << 16) |
1121 (SPD_REG8(spdaddr + 6) << 8) |
1122 SPD_REG8(spdaddr + 4);
1123 if (manfid == tuple)
1125 M_PRINTF(
"MANFID 0x%08lx doesn't match expected 0x%08lx\n",
1132 M_PRINTF(
"MANFID 0x%08lx not found.\n", manfid);
1135 M_PRINTF(
"Invalid tuples at offset 0x%08lx.\n", spdaddr - SPD_REGBASE);
1139static int pcmcia_intr(
void *unused)
1147 cstc1 = DEV9_REG(DEV9_R_1464);
1148 cstc2 = DEV9_REG(DEV9_R_1466);
1151 if (aif_regs[AIF_INTSR] & AIF_INTR_PCMCIA)
1152 aif_regs[AIF_INTCL] = AIF_INTR_PCMCIA;
1158 DEV9_REG(DEV9_R_1464) = cstc1;
1159 DEV9_REG(DEV9_R_1466) = cstc2;
1160 if (cstc1 & 0x03 || cstc2 & 0x03) {
1165 DEV9_REG(DEV9_R_POWER) = 0;
1166 DEV9_REG(DEV9_R_1474) = 0;
1168 pcmcia_device_probe();
1170 if (cstc1 & 0x80 || cstc2 & 0x80) {
1175 DEV9_REG(DEV9_R_147E) = 1;
1176 DEV9_REG(DEV9_R_147E) = 0;
1180#ifdef DEV9_ENABLE_AIF
1181static int aif_pcmcia_intr_handler(
void)
1185 aif_regs[AIF_INTCL] = AIF_INTR_PCMCIA;
1191static int aif_intr(
void *unused)
1196 while ((aif_regs[AIF_INTSR] & aif_regs[AIF_INTEN]) != 0) {
1197 for (i = 0; i < AIF_INUM_COUNT; i++) {
1198 if ((aif_intr_cbs[i] != NULL) && ((aif_regs[AIF_INTSR] & aif_regs[AIF_INTEN]) & (1 << i))) {
1209static int pcmcia_init(
int sema_attr)
1217 _sw(0x51011, SSBUS_R_1420);
1218 _sw(0x1a00bb, SSBUS_R_1418);
1219 _sw(0xef1a3043, SSBUS_R_141c);
1222 if ((mode = QueryBootMode(6)) != NULL) {
1223 if ((*(u16 *)mode & 0xfe) == 0x60) {
1224 M_PRINTF(
"T10K detected.\n");
1226 if (aif_regs[AIF_IDENT] == 0xa1) {
1227#ifdef DEV9_ENABLE_AIF
1228 M_PRINTF(
"AIF controller revision: %d.\n", aif_regs[AIF_REVISION]);
1229 aif_regs[AIF_INTCL] = 7;
1231 aif_regs[AIF_INTEN] = AIF_INTR_PCMCIA;
1235 M_PRINTF(
"AIF not detected.\n");
1241 if (DEV9_REG(DEV9_R_POWER) == 0) {
1242 DEV9_REG(DEV9_R_POWER) = 0;
1243 DEV9_REG(DEV9_R_147E) = 1;
1244 DEV9_REG(DEV9_R_1460) = 0;
1245 DEV9_REG(DEV9_R_1474) = 0;
1246 DEV9_REG(DEV9_R_1464) = cstc1 = DEV9_REG(DEV9_R_1464);
1247 DEV9_REG(DEV9_R_1466) = cstc2 = DEV9_REG(DEV9_R_1466);
1248 DEV9_REG(DEV9_R_1468) = 0x10;
1249 DEV9_REG(DEV9_R_146A) = 0x90;
1250 DEV9_REG(DEV9_R_147C) = 1;
1251 DEV9_REG(DEV9_R_147A) = DEV9_REG(DEV9_R_147C);
1253 pcic_voltage = pcic_get_voltage();
1254 pcic_cardtype = pcic_get_cardtype();
1256 if (speed_device_init() != 0)
1259 _sw(0xe01a3043, SSBUS_R_1418);
1262 if (dev9_init(sema_attr) != 0)
1266#ifdef DEV9_ENABLE_AIF
1269 aifRegisterIntrCb(AIF_INUM_PCMCIA, &aif_pcmcia_intr_handler);
1270 aifIntrEnable(AIF_INTR_PCMCIA);
1279 DEV9_REG(DEV9_R_147E) = 0;
1281 if (RegisterLibraryEntries(&_exp_dev9) != 0)
1284 M_PRINTF(
"CXD9566 (PCMCIA) driver start.\n");
1288static void expbay_set_stat(
int stat)
1291 DEV9_REG(DEV9_R_1464) = stat & 0x3f;
1294static int expbay_device_probe(
void)
1297 return (DEV9_REG(DEV9_R_1462) & 0x01) ? -1 : 0;
1300static int expbay_device_reset(
void)
1304 if (expbay_device_probe() < 0)
1307 DEV9_REG(DEV9_R_POWER) = (DEV9_REG(DEV9_R_POWER) & ~1) | 0x04;
1308 DelayThread(500000);
1310 DEV9_REG(DEV9_R_1460) = DEV9_REG(DEV9_R_1460) | 0x01;
1311 DEV9_REG(DEV9_R_POWER) = DEV9_REG(DEV9_R_POWER) | 0x01;
1312 DelayThread(500000);
1316static int expbay_intr(
void *unused)
1325 if (!dev9_has_dvr_capability) {
1326 DEV9_REG(DEV9_R_1466) = 1;
1328 DEV9_REG(DEV9_R_1466) = 0;
1332static int expbay_init(
int sema_attr)
1338 _sw(0x51011, SSBUS_R_1420);
1339 _sw(0xe01a3043, SSBUS_R_1418);
1340 _sw(0xef1a3043, SSBUS_R_141c);
1342 if ((DEV9_REG(DEV9_R_POWER) & 0x04) == 0) {
1343 DEV9_REG(DEV9_R_1466) = 1;
1344 DEV9_REG(DEV9_R_1464) = 0;
1345 DEV9_REG(DEV9_R_1460) = DEV9_REG(DEV9_R_1464);
1347 if (speed_device_init() != 0)
1352 dev9_has_dvr_capability = (SPD_REG16(SPD_R_REV_3) & SPD_CAPS_DVR) ? 1 : 0;
1354 if (dev9_init(sema_attr) != 0)
1362 DEV9_REG(DEV9_R_1466) = 0;
1364 if (RegisterLibraryEntries(&_exp_dev9) != 0)
1367 M_PRINTF(
"CXD9611 (SSBUS Buffer) driver start.\n");
1371#ifdef DEV9_ENABLE_AIF
1372int aifIsDetected(
void)
1377void aifIntrEnable(
int mask)
1383 aif_regs[AIF_INTEN] |= mask;
1387void aifIntrDisable(
int mask)
1393 aif_regs[AIF_INTEN] &= ~mask;
1397void aifRegisterIntrCb(
int intr, aif_intr_cb_t cb)
1399 if (intr < AIF_INUM_COUNT) {
1400 aif_intr_cbs[intr] = cb;
1404int aifRegisterShutdownCb(
int idx, dev9_shutdown_cb_t cb)
1406 if (idx < AIF_INUM_COUNT) {
1407 aif_shutdown_cbs[idx] = cb;
1413unsigned char aifRTCReadData(
unsigned short int address)
1418 return aif_rtc_regs[address & 0x7F];
1421void aifRTCWriteData(
unsigned char data,
unsigned short int address)
1426 aif_rtc_regs[address & 0x7F] = data;
int CpuResumeIntr(int state)
int RegisterIntrHandler(int irq, int mode, int(*handler)(void *), void *arg)
int CpuSuspendIntr(int *state)
#define SMAP_E3_TX_URG_REQ_BITSFT
#define SMAP_E3_PHY_OP_COMP
#define SMAP_E3_TX_LOW_REQ_BITSFT
#define SMAP_E3_RX_PROP_PF