[PATCH] yenta: add modparam to tune EnE bridges (was Re: ENE
CB1410 and Echo Indigo IO incompatibility)
Daniel Ritz
daniel.ritz at gmx.ch
Sat Aug 20 12:23:46 EDT 2005
On Saturday 20 August 2005 04.58, Andrew Morton wrote:
> Daniel Ritz <daniel.ritz at gmx.ch> wrote:
> >
> > [PATCH] yenta: add modparam to tune EnE bridges
> >
> > EnE bridges have various compatibility problems with different CB cards. Eg.
> > are the RME HDSP soundcard, some CD writers, Echo Audio products and the
> > audigy 2 zs. There's a test bit (TLTEnable) that helps. but for some CB
> > cards it has to be cleared (HDSP, cd writer) and for some set (Echo
> > soundcards). Turn it into a modparam, default to clear to not break working
> > setups).
> >
> > Also add some more EnE entries to pci_ids.h and use them.
>
> Sad. Is there no way in which we can do this automatically?
>
i knew you would ask.
something like the attached. it's completley untested...but there's a small
little problem. when reading the document from echo audio it seems that it's
not always the solution to set the bit...it's more try and error:
http://www.echoaudio.com/downloadfiles/Other/ENE_README.pdf
rgds
-daniel
----
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -228,6 +228,11 @@ int cb_alloc(struct pcmcia_socket * s)
pci_bus_size_bridges(bus);
pci_bus_assign_resources(bus);
cardbus_assign_irqs(bus, s->pci_irq);
+
+ /* socket specific tune function */
+ if (s->tune_bridge)
+ s->tune_bridge(s, bus);
+
pci_enable_bridges(bus);
pci_bus_add_devices(bus);
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -791,16 +791,6 @@ static int ti12xx_override(struct yenta_
config_writel(socket, TI113X_SYSTEM_CONTROL, val);
/*
- * for EnE bridges only: clear testbit TLTEnable. this makes the
- * RME Hammerfall DSP sound card working.
- */
- if (socket->dev->vendor == PCI_VENDOR_ID_ENE) {
- u8 test_c9 = config_readb(socket, ENE_TEST_C9);
- test_c9 &= ~ENE_TEST_C9_TLTENABLE;
- config_writeb(socket, ENE_TEST_C9, test_c9);
- }
-
- /*
* Yenta expects controllers to use CSCINT to route
* CSC interrupts to PCI rather than INTVAL.
*/
@@ -841,5 +831,64 @@ static int ti1250_override(struct yenta_
return ti12xx_override(socket);
}
+
+/**
+ * EnE specific part. EnE bridges are register compatible with TI bridges but
+ * have their own test registers and more important their own little problems.
+ * Some fixup code to make everybody happy (TM).
+ */
+
+/**
+ * set/clear TLTEnable testbit:
+ * - clearing it makes the RME Hammerfall DSP sound card working
+ * - setting it makes Echo Audio cards working
+ * Defaults to clear the bit.
+ */
+/* pci ids of devices that wants to have the bit set */
+#define DEVID(_vend,_dev,_subvend,_subdev) { \
+ .vendor = _vend, \
+ .device = _dev, \
+ .subvendor = _subvend, \
+ .subdevice = _subdev, \
+ }
+static struct pci_device_id ene_tltenable_tbl[] = {
+ /* Echo Audio products */
+ DEVID(PCI_VENDOR_ID_MOTOROLA, 0x1801, 0xECC0, PCI_ANY_ID), /* motorola DSP56301 */
+ DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID), /* motorola DSP56361 */
+
+ {}
+};
+
+static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
+{
+ struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+ struct pci_dev *dev;
+ unsigned int tltena = 0;
+ u8 test_c9;
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ if (pci_match_id(ene_tltenable_tbl, dev)) {
+ tltena = 1;
+ break;
+ }
+ }
+
+ test_c9 = config_readb(socket, ENE_TEST_C9);
+ if (tltena)
+ test_c9 |= ENE_TEST_C9_TLTENABLE;
+ else
+ test_c9 &= ~ENE_TEST_C9_TLTENABLE;
+ config_writeb(socket, ENE_TEST_C9, test_c9);
+}
+
+
+static int ene_override(struct yenta_socket *socket)
+{
+ /* install tune_bridge() function */
+ socket->socket.tune_bridge = ene_tune_bridge;
+
+ return ti1250_override(socket);
+}
+
#endif /* _LINUX_TI113X_H */
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -753,6 +753,7 @@ enum {
CARDBUS_TYPE_RICOH,
CARDBUS_TYPE_TOPIC97,
CARDBUS_TYPE_O2MICRO,
+ CARDBUS_TYPE_ENE,
};
/*
@@ -796,6 +797,12 @@ static struct cardbus_type cardbus_type[
.override = o2micro_override,
.restore_state = o2micro_restore_state,
},
+ [CARDBUS_TYPE_ENE] = {
+ .override = ene_override,
+ .save_state = ti_save_state,
+ .restore_state = ti_restore_state,
+ .sock_init = ti_init,
+ },
};
@@ -1185,10 +1192,14 @@ static struct pci_device_id yenta_table
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1250, TI1250),
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1410, TI1250),
- CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1211, TI12XX),
- CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1225, TI12XX),
- CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1410, TI1250),
- CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1420, TI12XX),
+ CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1211, ENE),
+ CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1225, ENE),
+ CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1410, ENE),
+ CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1420, ENE),
+ CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_710, ENE),
+ CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_712, ENE),
+ CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_720, ENE),
+ CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_722, ENE),
CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C465, RICOH),
CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C466, RICOH),
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -21,6 +21,9 @@
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/bulkmem.h>
+#ifdef CONFIG_CARDBUS
+#include <linux/pci.h>
+#endif
/* Definitions for card status flags for GetStatus */
#define SS_WRPROT 0x0001
@@ -233,7 +236,11 @@ struct pcmcia_socket {
/* so is power hook */
int (*power_hook)(struct pcmcia_socket *sock, int operation);
-
+#ifdef CONFIG_CARDBUS
+ /* allows tuning the CB bridge before loading driver for the CB card */
+ void (*tune_bridge)(struct pcmcia_socket *sock, struct pci_bus *bus);
+#endif
+
/* state thread */
struct semaphore skt_sem; /* protects socket h/w state */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2143,7 +2143,11 @@
#define PCI_DEVICE_ID_ENE_1211 0x1211
#define PCI_DEVICE_ID_ENE_1225 0x1225
#define PCI_DEVICE_ID_ENE_1410 0x1410
+#define PCI_DEVICE_ID_ENE_710 0x1411
+#define PCI_DEVICE_ID_ENE_712 0x1412
#define PCI_DEVICE_ID_ENE_1420 0x1420
+#define PCI_DEVICE_ID_ENE_720 0x1421
+#define PCI_DEVICE_ID_ENE_722 0x1422
#define PCI_VENDOR_ID_SYBA 0x1592
#define PCI_DEVICE_ID_SYBA_2P_EPP 0x0782
More information about the linux-pcmcia
mailing list