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 | ||
