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_devctl(
iop_file_t *f,
const char *name,
int cmd,
void *args,
unsigned int arglen,
void *buf,
unsigned int buflen)
139 dev9ControlPIO3(((u32 *)args)[0]);
142 dev9LED2Ctl(((u32 *)args)[0]);
149IOMANX_RETURN_VALUE_IMPL(0);
153 IOMANX_RETURN_VALUE(0),
154 IOMANX_RETURN_VALUE(0),
155 IOMANX_RETURN_VALUE(0),
156 IOMANX_RETURN_VALUE(0),
157 IOMANX_RETURN_VALUE(0),
158 IOMANX_RETURN_VALUE(0),
159 IOMANX_RETURN_VALUE(0),
160 IOMANX_RETURN_VALUE(0),
161 IOMANX_RETURN_VALUE(0),
162 IOMANX_RETURN_VALUE(0),
163 IOMANX_RETURN_VALUE(0),
164 IOMANX_RETURN_VALUE(0),
165 IOMANX_RETURN_VALUE(0),
166 IOMANX_RETURN_VALUE(0),
167 IOMANX_RETURN_VALUE(0),
168 IOMANX_RETURN_VALUE(0),
169 IOMANX_RETURN_VALUE(0),
170 IOMANX_RETURN_VALUE(0),
171 IOMANX_RETURN_VALUE(0),
172 IOMANX_RETURN_VALUE(0),
173 IOMANX_RETURN_VALUE(0),
174 IOMANX_RETURN_VALUE(0),
175 IOMANX_RETURN_VALUE_S64(0),
177 IOMANX_RETURN_VALUE(0),
178 IOMANX_RETURN_VALUE(0),
179 IOMANX_RETURN_VALUE(0),
191static int print_help(
void)
194 " %s [-sa] <attribute>]\n"
195 " -sa You can specify attibute of sempahore for queuing thread.\n"
196 " List of possible <attribute>:\n"
197 " SA_THPRI(default), SA_THFIFO\n",
200 return MODULE_NO_RESIDENT_END;
203int _start(
int argc,
char *argv[])
206 const char *pModName;
210 semaAttrGlobal = SA_THPRI;
212 printf(BANNER, VERSION);
214 mod_name = (pModName = strrchr(argv[0],
'/')) != NULL ? pModName + 1 : argv[0];
216 for (--argc, ++argv; argc > 0; argc--, argv++) {
217 if ((*argv)[0] !=
'-')
220 if (strcmp(
"-sa", *argv) == 0) {
224 if (strcmp(
"SA_THFIFO", *argv) == 0) {
225 semaAttrGlobal = SA_THFIFO;
226 }
else if (strcmp(
"SA_THPRI", *argv) == 0) {
227 semaAttrGlobal = SA_THPRI;
239 for (idx = 0; idx < 16; idx++)
240 dev9_shutdown_cbs[idx] = NULL;
242#ifdef DEV9_ENABLE_AIF
243 for (idx = 0; idx < AIF_INUM_COUNT; idx++)
244 aif_shutdown_cbs[idx] = NULL;
247 dev9hw = DEV9_REG(DEV9_R_REV) & 0xf0;
248 if (dev9hw == 0x20) {
249 dev9type = DEV9_TYPE_PCMCIA;
250 M_PRINTF(
"CXD9566 detected.\n");
251 res = pcmcia_init(semaAttrGlobal);
252 }
else if (dev9hw == 0x30) {
253 dev9type = DEV9_TYPE_EXPBAY;
254 M_PRINTF(
"CXD9611 detected.\n");
255 res = expbay_init(semaAttrGlobal);
257 M_PRINTF(
"unknown dev9 hardware.\n");
258 res = MODULE_NO_RESIDENT_END;
264 DelDrv(dev9x_device.name);
265 if (AddDrv(&dev9x_device) != 0) {
266 return MODULE_NO_RESIDENT_END;
269 return MODULE_RESIDENT_END;
272int _exit(
void) {
return MODULE_RESIDENT_END; }
275void SpdRegisterIntrHandler(
int intr, dev9_intr_cb_t cb)
277 dev9_intr_cbs[intr] = cb;
281void dev9RegisterPreDmaCb(
int ctrl, dev9_dma_cb_t cb)
283 dev9_predma_cbs[ctrl] = cb;
287void dev9RegisterPostDmaCb(
int ctrl, dev9_dma_cb_t cb)
289 dev9_postdma_cbs[ctrl] = cb;
293static int dev9_intr_dispatch(
int flag)
299 for (i = 0; i < 16; i++)
300 if (dev9_intr_cbs[i] != NULL)
301 dev9_intr_cbs[i](flag);
304 while (SPD_REG16(SPD_R_INTR_STAT) & SPD_REG16(SPD_R_INTR_MASK)) {
305 for (i = 0; i < 16; i++) {
306 if (dev9_intr_cbs[i] != NULL) {
307 bit = (SPD_REG16(SPD_R_INTR_STAT) &
308 SPD_REG16(SPD_R_INTR_MASK)) >>
311 dev9_intr_cbs[i](flag);
319static void dev9_set_stat(
int stat)
322 case DEV9_TYPE_PCMCIA:
323 pcmcia_set_stat(stat);
325 case DEV9_TYPE_EXPBAY:
326 expbay_set_stat(stat);
331static int dev9_ssbus_mode(
int mode)
334 case DEV9_TYPE_PCMCIA:
335 return pcic_ssbus_mode(mode);
336 case DEV9_TYPE_EXPBAY:
343static int dev9_device_probe(
void)
346 case DEV9_TYPE_PCMCIA:
347 return pcmcia_device_probe();
348 case DEV9_TYPE_EXPBAY:
349 return expbay_device_probe();
355static int dev9_device_reset(
void)
358 case DEV9_TYPE_PCMCIA:
359 return pcmcia_device_reset();
360 case DEV9_TYPE_EXPBAY:
361 return expbay_device_reset();
368void Dev9CardStop(
void)
373 for (idx = 0; idx < 16; idx++)
374 if (dev9_shutdown_cbs[idx])
375 dev9_shutdown_cbs[idx]();
377#ifdef DEV9_ENABLE_AIF
378 for (idx = 0; idx < AIF_INUM_COUNT; idx++)
379 if (aif_shutdown_cbs[idx])
380 aif_shutdown_cbs[idx]();
383 if (dev9type == DEV9_TYPE_PCMCIA) {
384 DEV9_REG(DEV9_R_POWER) = 0;
385 DEV9_REG(DEV9_R_1474) = 0;
386 }
else if (dev9type == DEV9_TYPE_EXPBAY) {
387 DEV9_REG(DEV9_R_1466) = 1;
388 DEV9_REG(DEV9_R_1464) = 0;
389 DEV9_REG(DEV9_R_1460) = DEV9_REG(DEV9_R_1464);
390 DEV9_REG(DEV9_R_POWER) = DEV9_REG(DEV9_R_POWER) & ~4;
391 DEV9_REG(DEV9_R_POWER) = DEV9_REG(DEV9_R_POWER) & ~1;
393 DelayThread(1000000);
396static int dev9_card_find_manfid(u32 manfid)
399 case DEV9_TYPE_PCMCIA:
400 return card_find_manfid(manfid);
401 case DEV9_TYPE_EXPBAY:
409void SpdIntrEnable(
int mask)
415 SPD_REG16(SPD_R_INTR_MASK) = SPD_REG16(SPD_R_INTR_MASK) | mask;
420void SpdIntrDisable(
int mask)
426 SPD_REG16(SPD_R_INTR_MASK) = SPD_REG16(SPD_R_INTR_MASK) & ~mask;
431int SpdDmaTransfer(
int device,
void *buf,
int bcr,
int dir)
435 int res, dmactrl, OldState;
439 }
else if (device >= 2) {
440 if (dev9_predma_cbs[device] == NULL)
442 if (dev9_postdma_cbs[device] == NULL)
446 if ((res = WaitSema(dma_lock_sem)) < 0)
456#ifdef DEV9_PSX_SUPPORT
469 SPD_REG16(SPD_R_DMA_CTRL) = (SPD_REG16(SPD_R_REV_1) < 17) ? (dmactrl & 0x03) | 0x04 : dmactrl | 0x06;
471 if (dev9_predma_cbs[device])
472 dev9_predma_cbs[device](bcr, dir);
474 dev9_chan->madr = (u32)buf;
478 dev9_chan->bcr = bcr;
485 if (dev9_postdma_cbs[device])
486 dev9_postdma_cbs[device](bcr, dir);
488 SignalSema(dma_lock_sem);
492static int read_eeprom_data(
void)
498 if (eeprom_data[0] < 0)
501 SPD_REG8(SPD_R_PIO_DIR) = 0xe0 | (dev9_has_dvr_capability ? 7 : 1);
503 SPD_REG8(SPD_R_PIO_DATA) = 0x80;
506 for (i = 0; i < 2; i++) {
507 SPD_REG8(SPD_R_PIO_DATA) = 0xa0;
509 SPD_REG8(SPD_R_PIO_DATA) = 0xe0;
512 for (i = 0; i < 7; i++) {
513 SPD_REG8(SPD_R_PIO_DATA) = 0x80;
515 SPD_REG8(SPD_R_PIO_DATA) = 0xc0;
518 SPD_REG8(SPD_R_PIO_DATA) = 0xc0;
521 val = SPD_REG8(SPD_R_PIO_DATA);
524 SPD_REG8(SPD_R_PIO_DATA) = 0;
531 SPD_REG8(SPD_R_PIO_DATA) = 0x80;
535 for (i = 0; i < 4; i++) {
536 eeprom_data[i + 1] = 0;
538 for (j = 15; j >= 0; j--) {
539 SPD_REG8(SPD_R_PIO_DATA) = 0xc0;
541 val = SPD_REG8(SPD_R_PIO_DATA);
543 eeprom_data[i + 1] |= (1 << j);
544 SPD_REG8(SPD_R_PIO_DATA) = 0x80;
549 SPD_REG8(SPD_R_PIO_DATA) = 0;
555 SPD_REG8(SPD_R_PIO_DIR) = dev9_has_dvr_capability ? 7 : 1;
560int SpdGetEthernetID(u16 *buf)
566 if (eeprom_data[0] < 0)
570 for (i = 0; i < 4; i++)
571 buf[i] = eeprom_data[i + 1];
588void SpdSetLED(
int ctl)
591 if (dev9_has_dvr_capability) {
592 SPD_REG8(SPD_R_PIO_DIR) |= 1;
593 SPD_REG8(SPD_R_PIO_DATA) = (SPD_REG8(SPD_R_PIO_DATA) & 0xE) | (ctl ? 0 : 1);
595 SPD_REG8(SPD_R_PIO_DATA) = (ctl == 0);
600void dev9LED2Ctl(
int ctl)
602 if (dev9_has_dvr_capability) {
604 SPD_REG8(SPD_R_PIO_DIR) |= 2;
606 SPD_REG8(SPD_R_PIO_DATA) = (SPD_REG8(SPD_R_PIO_DATA) & 0xD) | (ctl ? 0 : 2);
616void dev9ControlPIO3(
int ctl)
618 if (dev9_has_dvr_capability) {
620 SPD_REG8(SPD_R_PIO_DIR) |= 4;
622 SPD_REG8(SPD_R_PIO_DATA) = (SPD_REG8(SPD_R_PIO_DATA) & 0xB) | (ctl ? 0 : 4);
627static void dev9RegisterIntrDispatchCb(dev9IntrDispatchCb_t callback)
629 p_dev9_intr_cb = callback;
633int Dev9RegisterPowerOffHandler(
int idx, dev9_shutdown_cb_t cb)
636 dev9_shutdown_cbs[idx] = cb;
642static int dev9_init(
int sema_attr)
647 sema.attr = sema_attr;
650 if ((dma_lock_sem = CreateSema(&sema)) < 0)
655 dmac_set_dpcr2(dmac_get_dpcr2() | 0x80);
659 dev9_set_stat(0x103);
662 SpdIntrDisable(0xffff);
664#ifdef DEV9_ENABLE_AIF
666 aifIntrDisable(0xffff);
670 dev9RegisterIntrDispatchCb(&dev9_intr_dispatch);
673 for (i = 0; i < 16; i++)
674 dev9_intr_cbs[i] = NULL;
675#ifdef DEV9_ENABLE_AIF
676 for (i = 0; i < AIF_INUM_COUNT; i++)
677 aif_intr_cbs[i] = NULL;
680 for (i = 0; i < 4; i++) {
681 dev9_predma_cbs[i] = NULL;
682 dev9_postdma_cbs[i] = NULL;
696#ifndef DEV9_SKIP_SMAP_INIT
697static int dev9_smap_read_phy(
volatile u8 *emac3_regbase,
unsigned int address,
unsigned int *data)
699 unsigned int i, PHYRegisterValue;
702 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);
706 SMAP_EMAC3_SET(SMAP_R_EMAC3_STA_CTRL, PHYRegisterValue);
712 result >>= SMAP_E3_PHY_DATA_BITSFT;
730static int dev9_smap_write_phy(
volatile u8 *emac3_regbase,
unsigned char address,
unsigned short int value)
732 unsigned int i, PHYRegisterValue;
734 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);
735 PHYRegisterValue |= ((
unsigned int)value) << SMAP_E3_PHY_DATA_BITSFT;
738 SMAP_EMAC3_SET(SMAP_R_EMAC3_STA_CTRL, PHYRegisterValue);
746 return ((i >= 100) ? 1 : 0);
749static int dev9_smap_init(
void)
760 if (!(SPD_REG16(SPD_R_REV_3) & SPD_CAPS_SMAP)
761#ifdef DEV9_GAMESTAR_WORKAROUND
766 || (SPD_REG16(0x20) != 1)
771 SMAP_REG8(SMAP_R_TXFIFO_CTRL) = SMAP_TXFIFO_RESET;
772 for (i = 9; SMAP_REG8(SMAP_R_TXFIFO_CTRL) & SMAP_TXFIFO_RESET; i--) {
778 SMAP_REG8(SMAP_R_RXFIFO_CTRL) = SMAP_RXFIFO_RESET;
779 for (i = 9; SMAP_REG8(SMAP_R_RXFIFO_CTRL) & SMAP_RXFIFO_RESET; i--) {
785 SMAP_EMAC3_SET(SMAP_R_EMAC3_MODE0, SMAP_E3_SOFT_RESET);
786 for (i = 9; SMAP_EMAC3_GET(SMAP_R_EMAC3_MODE0) & SMAP_E3_SOFT_RESET; i--) {
793 if (SPD_REG16(SPD_R_REV_1) >= 0x11)
794 SMAP_REG8(SMAP_R_BD_MODE) = SMAP_BD_SWAP;
796 for (i = 0; i < SMAP_BD_MAX_ENTRY; i++) {
797 tx_bd[i].ctrl_stat = 0;
798 tx_bd[i].reserved = 0;
800 tx_bd[i].pointer = 0;
803 for (i = 0; i < SMAP_BD_MAX_ENTRY; i++) {
804 rx_bd[i].ctrl_stat = 0x80;
805 rx_bd[i].reserved = 0;
807 rx_bd[i].pointer = 0;
810 SMAP_REG16(SMAP_R_INTR_CLR) = SMAP_INTR_BITMSK;
811 if (SPD_REG16(SPD_R_REV_1) < 0x11)
814 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);
816 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);
817 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);
818 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);
819 SMAP_EMAC3_SET(SMAP_R_EMAC3_ADDR_HI, 0);
820 SMAP_EMAC3_SET(SMAP_R_EMAC3_ADDR_LO, 0);
821 SMAP_EMAC3_SET(SMAP_R_EMAC3_PAUSE_TIMER, 0xFFFF);
822 SMAP_EMAC3_SET(SMAP_R_EMAC3_INTER_FRAME_GAP, 4);
823 SMAP_EMAC3_SET(SMAP_R_EMAC3_TX_THRESHOLD, 12 << SMAP_E3_TX_THRESHLD_BITSFT);
824 SMAP_EMAC3_SET(SMAP_R_EMAC3_RX_WATERMARK, 16 << SMAP_E3_RX_LO_WATER_BITSFT | 128 << SMAP_E3_RX_HI_WATER_BITSFT);
826 dev9_smap_write_phy(emac3_regbase, SMAP_DsPHYTER_BMCR, SMAP_PHY_BMCR_RST);
828 if (dev9_smap_read_phy(emac3_regbase, SMAP_DsPHYTER_BMCR, &value))
830 if (!(value & SMAP_PHY_BMCR_RST))
836 dev9_smap_write_phy(emac3_regbase, SMAP_DsPHYTER_BMCR, SMAP_PHY_BMCR_LPBK | SMAP_PHY_BMCR_100M | SMAP_PHY_BMCR_DUPM);
838 SMAP_EMAC3_SET(SMAP_R_EMAC3_MODE0, SMAP_E3_TXMAC_ENABLE | SMAP_E3_RXMAC_ENABLE);
839 value = SMAP_REG16(SMAP_R_TXFIFO_WR_PTR) + SMAP_TX_BASE;
841 for (i = 0; i < 0x5EA; i += 4)
842 SMAP_REG32(SMAP_R_TXFIFO_DATA) = i;
844 tx_bd[0].length = 0xEA05;
845 tx_bd[0].pointer = (value >> 8) | (value << 8);
846 SMAP_REG8(SMAP_R_TXFIFO_FRAME_INC) = 0;
847 tx_bd[0].ctrl_stat = 0x83;
851 value = SPD_REG16(SPD_R_INTR_STAT);
853 if ((value & (SMAP_INTR_RXEND | SMAP_INTR_TXEND | SMAP_INTR_TXDNV)) == (SMAP_INTR_RXEND | SMAP_INTR_TXEND | SMAP_INTR_TXDNV))
859 SMAP_EMAC3_SET(SMAP_R_EMAC3_MODE0, SMAP_E3_SOFT_RESET);
865static int speed_device_init(
void)
868 const char *spdnames[] = {
"(unknown)",
"TS",
"ES1",
"ES2"};
871#ifndef DEV9_SKIP_SMAP_INIT
877#ifndef DEV9_SKIP_SMAP_INIT
878 for (i = 0; i < 8; i++) {
880 if (dev9_device_probe() < 0) {
881 M_PRINTF(
"No device.\n");
882#ifdef DEV9_ENABLE_AIF
883 return (using_aif ? 0 : -1);
893 if ((res = dev9_card_find_manfid(0xf15300)))
894 M_PRINTF(
"SPEED Lite not found.\n");
896 if (!res && (res = dev9_ssbus_mode(5)))
897 M_PRINTF(
"Unable to change SSBUS mode.\n");
904#ifndef DEV9_SKIP_SMAP_INIT
905 if ((res = dev9_smap_init()) == 0) {
910 DelayThread(4500000);
914 M_PRINTF(
"SMAP initialization failed: %d\n", res);
920 spdrev = SPD_REG16(SPD_R_REV_1);
921 idx = (spdrev & 0xffff) - 14;
924 else if (spdrev < 9 || (spdrev < 16 || spdrev > 17))
927 M_PRINTF(
"SPEED chip '%s', revision %0x\n", spdnames[idx], spdrev);
931static int pcic_get_cardtype(
void)
934 u16 val = DEV9_REG(DEV9_R_1462) & 0x03;
937 return PC_CARD_TYPE_PCMCIA;
939 return PC_CARD_TYPE_CARDBUS;
940 return PC_CARD_TYPE_NONE;
943static int pcic_get_voltage(
void)
946 u16 val = DEV9_REG(DEV9_R_1462) & 0x0c;
949 return PC_CARD_VOLTAGE_04h;
950 if (val == 0 || val == 0x08)
951 return PC_CARD_VOLTAGE_3V;
953 return PC_CARD_VOLTAGE_5V;
954 return PC_CARD_VOLTAGE_INVALID;
957static int pcic_power(
int voltage,
int flag)
961 u16 val = (voltage == 1) << 2;
963 DEV9_REG(DEV9_R_POWER) = 0;
970 DEV9_REG(DEV9_R_POWER) = val;
973 if (DEV9_REG(DEV9_R_1462) & 0x100)
976 DEV9_REG(DEV9_R_POWER) = 0;
977 DEV9_REG(DEV9_R_1464) = cstc1 = DEV9_REG(DEV9_R_1464);
978 DEV9_REG(DEV9_R_1466) = cstc2 = DEV9_REG(DEV9_R_1466);
982static void pcmcia_set_stat(
int stat)
985 u16 val = stat & 0x01;
1005 DEV9_REG(DEV9_R_1476) = val & 0xff;
1008static int pcic_ssbus_mode(
int mode)
1012 u16 stat = DEV9_REG(DEV9_R_1474) & 7;
1014 if (mode != 3 && mode != 5)
1017 DEV9_REG(DEV9_R_1460) = 2;
1022 DEV9_REG(DEV9_R_1474) = 1;
1023 DEV9_REG(DEV9_R_1460) = 1;
1025 DEV9_REG(DEV9_R_1474) = mode;
1026 }
else if (mode == 5) {
1027 DEV9_REG(DEV9_R_1474) = mode;
1028 DEV9_REG(DEV9_R_1460) = 1;
1030 DEV9_REG(DEV9_R_1474) = 7;
1032 _sw(0xe01a3043, SSBUS_R_1418);
1035 DEV9_REG(DEV9_R_POWER) = DEV9_REG(DEV9_R_POWER) & ~1;
1039static int pcmcia_device_probe(
void)
1041 const char *pcic_ct_names[] = {
"No",
"16-bit",
"CardBus"};
1044 pcic_voltage = pcic_get_voltage();
1045 pcic_cardtype = pcic_get_cardtype();
1046 voltage = (pcic_voltage == PC_CARD_VOLTAGE_5V ? 5 : (pcic_voltage == PC_CARD_VOLTAGE_3V ? 3 : 0));
1048 M_PRINTF(
"%s PCMCIA card detected. Vcc = %dV\n",
1049 pcic_ct_names[pcic_cardtype], voltage);
1051 if (pcic_voltage == PC_CARD_VOLTAGE_04h || pcic_cardtype != PC_CARD_TYPE_PCMCIA)
1057static int pcmcia_device_reset(
void)
1063 if ((DEV9_REG(DEV9_R_1462) & 0x03) != 0)
1066 DEV9_REG(DEV9_R_147E) = 1;
1067 if (pcic_power(pcic_voltage, 1) < 0)
1070 DEV9_REG(DEV9_R_POWER) = DEV9_REG(DEV9_R_POWER) | 0x02;
1071 DelayThread(500000);
1073 DEV9_REG(DEV9_R_POWER) = DEV9_REG(DEV9_R_POWER) | 0x01;
1074 DEV9_REG(DEV9_R_1464) = cstc1 = DEV9_REG(DEV9_R_1464);
1075 DEV9_REG(DEV9_R_1466) = cstc2 = DEV9_REG(DEV9_R_1466);
1079static int card_find_manfid(u32 manfid)
1083 u32 spdaddr, spdend, next, tuple;
1086 DEV9_REG(DEV9_R_1460) = 2;
1087 _sw(0x1a00bb, SSBUS_R_1418);
1093 while (spdaddr < spdend) {
1094 hdr = SPD_REG8(spdaddr) & 0xff;
1100 if (spdaddr >= spdend)
1103 ofs = SPD_REG8(spdaddr) & 0xff;
1108 next = spdaddr + (ofs * 2);
1113 if ((spdaddr + 8) >= spdend)
1116 tuple = (SPD_REG8(spdaddr + 2) << 24) |
1117 (SPD_REG8(spdaddr) << 16) |
1118 (SPD_REG8(spdaddr + 6) << 8) |
1119 SPD_REG8(spdaddr + 4);
1120 if (manfid == tuple)
1122 M_PRINTF(
"MANFID 0x%08lx doesn't match expected 0x%08lx\n",
1129 M_PRINTF(
"MANFID 0x%08lx not found.\n", manfid);
1132 M_PRINTF(
"Invalid tuples at offset 0x%08lx.\n", spdaddr - SPD_REGBASE);
1136static int pcmcia_intr(
void *unused)
1144 cstc1 = DEV9_REG(DEV9_R_1464);
1145 cstc2 = DEV9_REG(DEV9_R_1466);
1148 if (aif_regs[AIF_INTSR] & AIF_INTR_PCMCIA)
1149 aif_regs[AIF_INTCL] = AIF_INTR_PCMCIA;
1155 DEV9_REG(DEV9_R_1464) = cstc1;
1156 DEV9_REG(DEV9_R_1466) = cstc2;
1157 if (cstc1 & 0x03 || cstc2 & 0x03) {
1162 DEV9_REG(DEV9_R_POWER) = 0;
1163 DEV9_REG(DEV9_R_1474) = 0;
1165 pcmcia_device_probe();
1167 if (cstc1 & 0x80 || cstc2 & 0x80) {
1172 DEV9_REG(DEV9_R_147E) = 1;
1173 DEV9_REG(DEV9_R_147E) = 0;
1177#ifdef DEV9_ENABLE_AIF
1178static int aif_pcmcia_intr_handler(
void)
1182 aif_regs[AIF_INTCL] = AIF_INTR_PCMCIA;
1188static int aif_intr(
void *unused)
1193 while ((aif_regs[AIF_INTSR] & aif_regs[AIF_INTEN]) != 0) {
1194 for (i = 0; i < AIF_INUM_COUNT; i++) {
1195 if ((aif_intr_cbs[i] != NULL) && ((aif_regs[AIF_INTSR] & aif_regs[AIF_INTEN]) & (1 << i))) {
1206static int pcmcia_init(
int sema_attr)
1214 _sw(0x51011, SSBUS_R_1420);
1215 _sw(0x1a00bb, SSBUS_R_1418);
1216 _sw(0xef1a3043, SSBUS_R_141c);
1219 if ((mode = QueryBootMode(6)) != NULL) {
1220 if ((*(u16 *)mode & 0xfe) == 0x60) {
1221 M_PRINTF(
"T10K detected.\n");
1223 if (aif_regs[AIF_IDENT] == 0xa1) {
1224#ifdef DEV9_ENABLE_AIF
1225 M_PRINTF(
"AIF controller revision: %d.\n", aif_regs[AIF_REVISION]);
1226 aif_regs[AIF_INTCL] = 7;
1228 aif_regs[AIF_INTEN] = AIF_INTR_PCMCIA;
1232 M_PRINTF(
"AIF not detected.\n");
1238 if (DEV9_REG(DEV9_R_POWER) == 0) {
1239 DEV9_REG(DEV9_R_POWER) = 0;
1240 DEV9_REG(DEV9_R_147E) = 1;
1241 DEV9_REG(DEV9_R_1460) = 0;
1242 DEV9_REG(DEV9_R_1474) = 0;
1243 DEV9_REG(DEV9_R_1464) = cstc1 = DEV9_REG(DEV9_R_1464);
1244 DEV9_REG(DEV9_R_1466) = cstc2 = DEV9_REG(DEV9_R_1466);
1245 DEV9_REG(DEV9_R_1468) = 0x10;
1246 DEV9_REG(DEV9_R_146A) = 0x90;
1247 DEV9_REG(DEV9_R_147C) = 1;
1248 DEV9_REG(DEV9_R_147A) = DEV9_REG(DEV9_R_147C);
1250 pcic_voltage = pcic_get_voltage();
1251 pcic_cardtype = pcic_get_cardtype();
1253 if (speed_device_init() != 0)
1256 _sw(0xe01a3043, SSBUS_R_1418);
1259 if (dev9_init(sema_attr) != 0)
1263#ifdef DEV9_ENABLE_AIF
1266 aifRegisterIntrCb(AIF_INUM_PCMCIA, &aif_pcmcia_intr_handler);
1267 aifIntrEnable(AIF_INTR_PCMCIA);
1276 DEV9_REG(DEV9_R_147E) = 0;
1278 if (RegisterLibraryEntries(&_exp_dev9) != 0)
1281 M_PRINTF(
"CXD9566 (PCMCIA) driver start.\n");
1285static void expbay_set_stat(
int stat)
1288 DEV9_REG(DEV9_R_1464) = stat & 0x3f;
1291static int expbay_device_probe(
void)
1294 return (DEV9_REG(DEV9_R_1462) & 0x01) ? -1 : 0;
1297static int expbay_device_reset(
void)
1301 if (expbay_device_probe() < 0)
1304 DEV9_REG(DEV9_R_POWER) = (DEV9_REG(DEV9_R_POWER) & ~1) | 0x04;
1305 DelayThread(500000);
1307 DEV9_REG(DEV9_R_1460) = DEV9_REG(DEV9_R_1460) | 0x01;
1308 DEV9_REG(DEV9_R_POWER) = DEV9_REG(DEV9_R_POWER) | 0x01;
1309 DelayThread(500000);
1313static int expbay_intr(
void *unused)
1322 if (!dev9_has_dvr_capability) {
1323 DEV9_REG(DEV9_R_1466) = 1;
1325 DEV9_REG(DEV9_R_1466) = 0;
1329static int expbay_init(
int sema_attr)
1335 _sw(0x51011, SSBUS_R_1420);
1336 _sw(0xe01a3043, SSBUS_R_1418);
1337 _sw(0xef1a3043, SSBUS_R_141c);
1339 if ((DEV9_REG(DEV9_R_POWER) & 0x04) == 0) {
1340 DEV9_REG(DEV9_R_1466) = 1;
1341 DEV9_REG(DEV9_R_1464) = 0;
1342 DEV9_REG(DEV9_R_1460) = DEV9_REG(DEV9_R_1464);
1344 if (speed_device_init() != 0)
1349 dev9_has_dvr_capability = (SPD_REG16(SPD_R_REV_3) & SPD_CAPS_DVR) ? 1 : 0;
1351 if (dev9_init(sema_attr) != 0)
1359 DEV9_REG(DEV9_R_1466) = 0;
1361 if (RegisterLibraryEntries(&_exp_dev9) != 0)
1364 M_PRINTF(
"CXD9611 (SSBUS Buffer) driver start.\n");
1368#ifdef DEV9_ENABLE_AIF
1369int aifIsDetected(
void)
1374void aifIntrEnable(
int mask)
1380 aif_regs[AIF_INTEN] |= mask;
1384void aifIntrDisable(
int mask)
1390 aif_regs[AIF_INTEN] &= ~mask;
1394void aifRegisterIntrCb(
int intr, aif_intr_cb_t cb)
1396 if (intr < AIF_INUM_COUNT) {
1397 aif_intr_cbs[intr] = cb;
1401int aifRegisterShutdownCb(
int idx, dev9_shutdown_cb_t cb)
1403 if (idx < AIF_INUM_COUNT) {
1404 aif_shutdown_cbs[idx] = cb;
1410unsigned char aifRTCReadData(
unsigned short int address)
1415 return aif_rtc_regs[address & 0x7F];
1418void aifRTCWriteData(
unsigned char data,
unsigned short int address)
1423 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