aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Ritz <daniel.ritz@gmx.ch>2005-08-22 01:29:26 -0400
committerDominik Brodowski <linux@dominikbrodowski.net>2005-09-26 07:09:20 -0400
commit8c3520d4eb3b1bbf2e45fbae8dcfb8db06d5e775 (patch)
treedf9b4f49e8f9ffa34657776be458fbd124b2e87b
parent8ddec7460d2f5db3ac35812c03676b1473d1d668 (diff)
[PATCH] yenta: auto-tune EnE bridges for CardBus cards
Echo Audio cardbus products are known to be incompatible with EnE bridges. in order to maybe solve the problem a EnE specific test bit has to be set, another cleared...but other setups have a good chance to break when just forcing the bits. so do the whole thingy automatically. The patch adds a hook in cb_alloc() that allows special tuning for the different chipsets. for ene just match the Echo products and set/clear the test bits, defaults to do the same thing as w/o the patch to not break working setups. Signed-off-by: Daniel Ritz <daniel.ritz@gmx.ch> Cc: Linus Torvalds <torvalds@osdl.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
-rw-r--r--drivers/pcmcia/cardbus.c5
-rw-r--r--drivers/pcmcia/ti113x.h86
-rw-r--r--drivers/pcmcia/yenta_socket.c15
-rw-r--r--include/linux/pci_ids.h5
-rw-r--r--include/pcmcia/ss.h9
5 files changed, 105 insertions, 15 deletions
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index 1d755e20880..3f6d51d1137 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -228,6 +228,11 @@ int cb_alloc(struct pcmcia_socket * s)
228 pci_bus_size_bridges(bus); 228 pci_bus_size_bridges(bus);
229 pci_bus_assign_resources(bus); 229 pci_bus_assign_resources(bus);
230 cardbus_assign_irqs(bus, s->pci_irq); 230 cardbus_assign_irqs(bus, s->pci_irq);
231
232 /* socket specific tune function */
233 if (s->tune_bridge)
234 s->tune_bridge(s, bus);
235
231 pci_enable_bridges(bus); 236 pci_enable_bridges(bus);
232 pci_bus_add_devices(bus); 237 pci_bus_add_devices(bus);
233 238
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index fbe233e19ce..d319f2e7d05 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -153,6 +153,12 @@
153/* EnE test register */ 153/* EnE test register */
154#define ENE_TEST_C9 0xc9 /* 8bit */ 154#define ENE_TEST_C9 0xc9 /* 8bit */
155#define ENE_TEST_C9_TLTENABLE 0x02 155#define ENE_TEST_C9_TLTENABLE 0x02
156#define ENE_TEST_C9_PFENABLE_F0 0x04
157#define ENE_TEST_C9_PFENABLE_F1 0x08
158#define ENE_TEST_C9_PFENABLE (ENE_TEST_C9_PFENABLE_F0 | ENE_TEST_C9_PFENABLE_F0)
159#define ENE_TEST_C9_WPDISALBLE_F0 0x40
160#define ENE_TEST_C9_WPDISALBLE_F1 0x80
161#define ENE_TEST_C9_WPDISALBLE (ENE_TEST_C9_WPDISALBLE_F0 | ENE_TEST_C9_WPDISALBLE_F1)
156 162
157/* 163/*
158 * Texas Instruments CardBus controller overrides. 164 * Texas Instruments CardBus controller overrides.
@@ -791,16 +797,6 @@ static int ti12xx_override(struct yenta_socket *socket)
791 config_writel(socket, TI113X_SYSTEM_CONTROL, val); 797 config_writel(socket, TI113X_SYSTEM_CONTROL, val);
792 798
793 /* 799 /*
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 800 * Yenta expects controllers to use CSCINT to route
805 * CSC interrupts to PCI rather than INTVAL. 801 * CSC interrupts to PCI rather than INTVAL.
806 */ 802 */
@@ -841,5 +837,75 @@ static int ti1250_override(struct yenta_socket *socket)
841 return ti12xx_override(socket); 837 return ti12xx_override(socket);
842} 838}
843 839
840
841/**
842 * EnE specific part. EnE bridges are register compatible with TI bridges but
843 * have their own test registers and more important their own little problems.
844 * Some fixup code to make everybody happy (TM).
845 */
846
847/**
848 * set/clear various test bits:
849 * Defaults to clear the bit.
850 * - mask (u8) defines what bits to change
851 * - bits (u8) is the values to change them to
852 * -> it's
853 * current = (current & ~mask) | bits
854 */
855/* pci ids of devices that wants to have the bit set */
856#define DEVID(_vend,_dev,_subvend,_subdev,mask,bits) { \
857 .vendor = _vend, \
858 .device = _dev, \
859 .subvendor = _subvend, \
860 .subdevice = _subdev, \
861 .driver_data = ((mask) << 8 | (bits)), \
862 }
863static struct pci_device_id ene_tune_tbl[] = {
864 /* Echo Audio products based on motorola DSP56301 and DSP56361 */
865 DEVID(PCI_VENDOR_ID_MOTOROLA, 0x1801, 0xECC0, PCI_ANY_ID,
866 ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
867 DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
868 ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
869
870 {}
871};
872
873static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
874{
875 struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
876 struct pci_dev *dev;
877 struct pci_device_id *id = NULL;
878 u8 test_c9, old_c9, mask, bits;
879
880 list_for_each_entry(dev, &bus->devices, bus_list) {
881 id = (struct pci_device_id *) pci_match_id(ene_tune_tbl, dev);
882 if (id)
883 break;
884 }
885
886 test_c9 = old_c9 = config_readb(socket, ENE_TEST_C9);
887 if (id) {
888 mask = (id->driver_data >> 8) & 0xFF;
889 bits = id->driver_data & 0xFF;
890
891 test_c9 = (test_c9 & ~mask) | bits;
892 }
893 else
894 /* default to clear TLTEnable bit, old behaviour */
895 test_c9 &= ~ENE_TEST_C9_TLTENABLE;
896
897 printk(KERN_INFO "yenta EnE: chaning testregister 0xC9, %02x -> %02x\n", old_c9, test_c9);
898 config_writeb(socket, ENE_TEST_C9, test_c9);
899}
900
901
902static int ene_override(struct yenta_socket *socket)
903{
904 /* install tune_bridge() function */
905 socket->socket.tune_bridge = ene_tune_bridge;
906
907 return ti1250_override(socket);
908}
909
844#endif /* _LINUX_TI113X_H */ 910#endif /* _LINUX_TI113X_H */
845 911
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index ba4d78e5b12..fd2a6f892c4 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -819,6 +819,7 @@ enum {
819 CARDBUS_TYPE_TOPIC95, 819 CARDBUS_TYPE_TOPIC95,
820 CARDBUS_TYPE_TOPIC97, 820 CARDBUS_TYPE_TOPIC97,
821 CARDBUS_TYPE_O2MICRO, 821 CARDBUS_TYPE_O2MICRO,
822 CARDBUS_TYPE_ENE,
822}; 823};
823 824
824/* 825/*
@@ -865,6 +866,12 @@ static struct cardbus_type cardbus_type[] = {
865 .override = o2micro_override, 866 .override = o2micro_override,
866 .restore_state = o2micro_restore_state, 867 .restore_state = o2micro_restore_state,
867 }, 868 },
869 [CARDBUS_TYPE_ENE] = {
870 .override = ene_override,
871 .save_state = ti_save_state,
872 .restore_state = ti_restore_state,
873 .sock_init = ti_init,
874 },
868}; 875};
869 876
870 877
@@ -1265,10 +1272,10 @@ static struct pci_device_id yenta_table [] = {
1265 CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1250, TI1250), 1272 CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1250, TI1250),
1266 CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1410, TI1250), 1273 CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1410, TI1250),
1267 1274
1268 CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1211, TI12XX), 1275 CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1211, ENE),
1269 CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1225, TI12XX), 1276 CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1225, ENE),
1270 CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1410, TI1250), 1277 CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1410, ENE),
1271 CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1420, TI12XX), 1278 CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1420, ENE),
1272 1279
1273 CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C465, RICOH), 1280 CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C465, RICOH),
1274 CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C466, RICOH), 1281 CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C466, RICOH),
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index b86a4b77007..92efb2c767f 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2187,7 +2187,12 @@
2187#define PCI_DEVICE_ID_ENE_1211 0x1211 2187#define PCI_DEVICE_ID_ENE_1211 0x1211
2188#define PCI_DEVICE_ID_ENE_1225 0x1225 2188#define PCI_DEVICE_ID_ENE_1225 0x1225
2189#define PCI_DEVICE_ID_ENE_1410 0x1410 2189#define PCI_DEVICE_ID_ENE_1410 0x1410
2190#define PCI_DEVICE_ID_ENE_710 0x1411
2191#define PCI_DEVICE_ID_ENE_712 0x1412
2190#define PCI_DEVICE_ID_ENE_1420 0x1420 2192#define PCI_DEVICE_ID_ENE_1420 0x1420
2193#define PCI_DEVICE_ID_ENE_720 0x1421
2194#define PCI_DEVICE_ID_ENE_722 0x1422
2195
2191#define PCI_VENDOR_ID_CHELSIO 0x1425 2196#define PCI_VENDOR_ID_CHELSIO 0x1425
2192 2197
2193#define PCI_VENDOR_ID_MIPS 0x153f 2198#define PCI_VENDOR_ID_MIPS 0x153f
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
index 0f7aacc33fe..c8592c7e8ea 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -21,6 +21,9 @@
21#include <pcmcia/cs_types.h> 21#include <pcmcia/cs_types.h>
22#include <pcmcia/cs.h> 22#include <pcmcia/cs.h>
23#include <pcmcia/bulkmem.h> 23#include <pcmcia/bulkmem.h>
24#ifdef CONFIG_CARDBUS
25#include <linux/pci.h>
26#endif
24 27
25/* Definitions for card status flags for GetStatus */ 28/* Definitions for card status flags for GetStatus */
26#define SS_WRPROT 0x0001 29#define SS_WRPROT 0x0001
@@ -233,7 +236,11 @@ struct pcmcia_socket {
233 236
234 /* so is power hook */ 237 /* so is power hook */
235 int (*power_hook)(struct pcmcia_socket *sock, int operation); 238 int (*power_hook)(struct pcmcia_socket *sock, int operation);
236 239#ifdef CONFIG_CARDBUS
240 /* allows tuning the CB bridge before loading driver for the CB card */
241 void (*tune_bridge)(struct pcmcia_socket *sock, struct pci_bus *bus);
242#endif
243
237 /* state thread */ 244 /* state thread */
238 struct semaphore skt_sem; /* protects socket h/w state */ 245 struct semaphore skt_sem; /* protects socket h/w state */
239 246