diff options
Diffstat (limited to 'drivers/pcmcia/ti113x.h')
-rw-r--r-- | drivers/pcmcia/ti113x.h | 115 |
1 files changed, 105 insertions, 10 deletions
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h index fbe233e19ceb..da0b404561c9 100644 --- a/drivers/pcmcia/ti113x.h +++ b/drivers/pcmcia/ti113x.h | |||
@@ -59,6 +59,7 @@ | |||
59 | 59 | ||
60 | #define TI122X_SCR_SER_STEP 0xc0000000 | 60 | #define TI122X_SCR_SER_STEP 0xc0000000 |
61 | #define TI122X_SCR_INTRTIE 0x20000000 | 61 | #define TI122X_SCR_INTRTIE 0x20000000 |
62 | #define TIXX21_SCR_TIEALL 0x10000000 | ||
62 | #define TI122X_SCR_CBRSVD 0x00400000 | 63 | #define TI122X_SCR_CBRSVD 0x00400000 |
63 | #define TI122X_SCR_MRBURSTDN 0x00008000 | 64 | #define TI122X_SCR_MRBURSTDN 0x00008000 |
64 | #define TI122X_SCR_MRBURSTUP 0x00004000 | 65 | #define TI122X_SCR_MRBURSTUP 0x00004000 |
@@ -153,6 +154,12 @@ | |||
153 | /* EnE test register */ | 154 | /* EnE test register */ |
154 | #define ENE_TEST_C9 0xc9 /* 8bit */ | 155 | #define ENE_TEST_C9 0xc9 /* 8bit */ |
155 | #define ENE_TEST_C9_TLTENABLE 0x02 | 156 | #define ENE_TEST_C9_TLTENABLE 0x02 |
157 | #define ENE_TEST_C9_PFENABLE_F0 0x04 | ||
158 | #define ENE_TEST_C9_PFENABLE_F1 0x08 | ||
159 | #define ENE_TEST_C9_PFENABLE (ENE_TEST_C9_PFENABLE_F0 | ENE_TEST_C9_PFENABLE_F0) | ||
160 | #define ENE_TEST_C9_WPDISALBLE_F0 0x40 | ||
161 | #define ENE_TEST_C9_WPDISALBLE_F1 0x80 | ||
162 | #define ENE_TEST_C9_WPDISALBLE (ENE_TEST_C9_WPDISALBLE_F0 | ENE_TEST_C9_WPDISALBLE_F1) | ||
156 | 163 | ||
157 | /* | 164 | /* |
158 | * Texas Instruments CardBus controller overrides. | 165 | * Texas Instruments CardBus controller overrides. |
@@ -618,6 +625,7 @@ static int ti12xx_2nd_slot_empty(struct yenta_socket *socket) | |||
618 | int devfn; | 625 | int devfn; |
619 | unsigned int state; | 626 | unsigned int state; |
620 | int ret = 1; | 627 | int ret = 1; |
628 | u32 sysctl; | ||
621 | 629 | ||
622 | /* catch the two-slot controllers */ | 630 | /* catch the two-slot controllers */ |
623 | switch (socket->dev->device) { | 631 | switch (socket->dev->device) { |
@@ -640,6 +648,24 @@ static int ti12xx_2nd_slot_empty(struct yenta_socket *socket) | |||
640 | */ | 648 | */ |
641 | break; | 649 | break; |
642 | 650 | ||
651 | case PCI_DEVICE_ID_TI_X515: | ||
652 | case PCI_DEVICE_ID_TI_X420: | ||
653 | case PCI_DEVICE_ID_TI_X620: | ||
654 | case PCI_DEVICE_ID_TI_XX21_XX11: | ||
655 | case PCI_DEVICE_ID_TI_7410: | ||
656 | case PCI_DEVICE_ID_TI_7610: | ||
657 | /* | ||
658 | * those are either single or dual slot CB with additional functions | ||
659 | * like 1394, smartcard reader, etc. check the TIEALL flag for them | ||
660 | * the TIEALL flag binds the IRQ of all functions toghether. | ||
661 | * we catch the single slot variants later. | ||
662 | */ | ||
663 | sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL); | ||
664 | if (sysctl & TIXX21_SCR_TIEALL) | ||
665 | return 0; | ||
666 | |||
667 | break; | ||
668 | |||
643 | /* single-slot controllers have the 2nd slot empty always :) */ | 669 | /* single-slot controllers have the 2nd slot empty always :) */ |
644 | default: | 670 | default: |
645 | return 1; | 671 | return 1; |
@@ -652,6 +678,15 @@ static int ti12xx_2nd_slot_empty(struct yenta_socket *socket) | |||
652 | if (!func) | 678 | if (!func) |
653 | return 1; | 679 | return 1; |
654 | 680 | ||
681 | /* | ||
682 | * check that the device id of both slots match. this is needed for the | ||
683 | * XX21 and the XX11 controller that share the same device id for single | ||
684 | * and dual slot controllers. return '2nd slot empty'. we already checked | ||
685 | * if the interrupt is tied to another function. | ||
686 | */ | ||
687 | if (socket->dev->device != func->device) | ||
688 | goto out; | ||
689 | |||
655 | slot2 = pci_get_drvdata(func); | 690 | slot2 = pci_get_drvdata(func); |
656 | if (!slot2) | 691 | if (!slot2) |
657 | goto out; | 692 | goto out; |
@@ -791,16 +826,6 @@ static int ti12xx_override(struct yenta_socket *socket) | |||
791 | config_writel(socket, TI113X_SYSTEM_CONTROL, val); | 826 | config_writel(socket, TI113X_SYSTEM_CONTROL, val); |
792 | 827 | ||
793 | /* | 828 | /* |
794 | * for EnE bridges only: clear testbit TLTEnable. this makes the | ||
795 | * RME Hammerfall DSP sound card working. | ||
796 | */ | ||
797 | if (socket->dev->vendor == PCI_VENDOR_ID_ENE) { | ||
798 | u8 test_c9 = config_readb(socket, ENE_TEST_C9); | ||
799 | test_c9 &= ~ENE_TEST_C9_TLTENABLE; | ||
800 | config_writeb(socket, ENE_TEST_C9, test_c9); | ||
801 | } | ||
802 | |||
803 | /* | ||
804 | * Yenta expects controllers to use CSCINT to route | 829 | * Yenta expects controllers to use CSCINT to route |
805 | * CSC interrupts to PCI rather than INTVAL. | 830 | * CSC interrupts to PCI rather than INTVAL. |
806 | */ | 831 | */ |
@@ -841,5 +866,75 @@ static int ti1250_override(struct yenta_socket *socket) | |||
841 | return ti12xx_override(socket); | 866 | return ti12xx_override(socket); |
842 | } | 867 | } |
843 | 868 | ||
869 | |||
870 | /** | ||
871 | * EnE specific part. EnE bridges are register compatible with TI bridges but | ||
872 | * have their own test registers and more important their own little problems. | ||
873 | * Some fixup code to make everybody happy (TM). | ||
874 | */ | ||
875 | |||
876 | /** | ||
877 | * set/clear various test bits: | ||
878 | * Defaults to clear the bit. | ||
879 | * - mask (u8) defines what bits to change | ||
880 | * - bits (u8) is the values to change them to | ||
881 | * -> it's | ||
882 | * current = (current & ~mask) | bits | ||
883 | */ | ||
884 | /* pci ids of devices that wants to have the bit set */ | ||
885 | #define DEVID(_vend,_dev,_subvend,_subdev,mask,bits) { \ | ||
886 | .vendor = _vend, \ | ||
887 | .device = _dev, \ | ||
888 | .subvendor = _subvend, \ | ||
889 | .subdevice = _subdev, \ | ||
890 | .driver_data = ((mask) << 8 | (bits)), \ | ||
891 | } | ||
892 | static struct pci_device_id ene_tune_tbl[] = { | ||
893 | /* Echo Audio products based on motorola DSP56301 and DSP56361 */ | ||
894 | DEVID(PCI_VENDOR_ID_MOTOROLA, 0x1801, 0xECC0, PCI_ANY_ID, | ||
895 | ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE), | ||
896 | DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID, | ||
897 | ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE), | ||
898 | |||
899 | {} | ||
900 | }; | ||
901 | |||
902 | static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus) | ||
903 | { | ||
904 | struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); | ||
905 | struct pci_dev *dev; | ||
906 | struct pci_device_id *id = NULL; | ||
907 | u8 test_c9, old_c9, mask, bits; | ||
908 | |||
909 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
910 | id = (struct pci_device_id *) pci_match_id(ene_tune_tbl, dev); | ||
911 | if (id) | ||
912 | break; | ||
913 | } | ||
914 | |||
915 | test_c9 = old_c9 = config_readb(socket, ENE_TEST_C9); | ||
916 | if (id) { | ||
917 | mask = (id->driver_data >> 8) & 0xFF; | ||
918 | bits = id->driver_data & 0xFF; | ||
919 | |||
920 | test_c9 = (test_c9 & ~mask) | bits; | ||
921 | } | ||
922 | else | ||
923 | /* default to clear TLTEnable bit, old behaviour */ | ||
924 | test_c9 &= ~ENE_TEST_C9_TLTENABLE; | ||
925 | |||
926 | printk(KERN_INFO "yenta EnE: chaning testregister 0xC9, %02x -> %02x\n", old_c9, test_c9); | ||
927 | config_writeb(socket, ENE_TEST_C9, test_c9); | ||
928 | } | ||
929 | |||
930 | |||
931 | static int ene_override(struct yenta_socket *socket) | ||
932 | { | ||
933 | /* install tune_bridge() function */ | ||
934 | socket->socket.tune_bridge = ene_tune_bridge; | ||
935 | |||
936 | return ti1250_override(socket); | ||
937 | } | ||
938 | |||
844 | #endif /* _LINUX_TI113X_H */ | 939 | #endif /* _LINUX_TI113X_H */ |
845 | 940 | ||