summaryrefslogtreecommitdiff
path: root/xhfc/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'xhfc/base.c')
-rw-r--r--xhfc/base.c123
1 files changed, 49 insertions, 74 deletions
diff --git a/xhfc/base.c b/xhfc/base.c
index 0d12d1f..6d3df56 100644
--- a/xhfc/base.c
+++ b/xhfc/base.c
@@ -25,6 +25,11 @@
*
* TODO: resource management strategy has been designed under influence,
* clean it
+ *
+ * TODO: hardware modif to ensure terminations are not activated
+ * while the xhfc is in reset.
+ *
+ * TODO: we might want to remove the ntte module param?
*/
#include <linux/acpi.h>
@@ -53,48 +58,12 @@ MODULE_LICENSE("GPL");
#define GPIO_FROM_PLATFORM_DESC (-2)
#define GPIO_NONE (-1)
-#define XIOH_PROTO_MB_V4_RESET_GPIO 27 // XXX unused
static int reset_gpio = GPIO_FROM_PLATFORM_DESC;
-static int port1_ntte_gpio = GPIO_NONE;
-static int port2_ntte_gpio = GPIO_NONE;
-static int port3_ntte_gpio = GPIO_NONE;
-static int port4_ntte_gpio = GPIO_NONE;
-
-static int port1_term_gpio = GPIO_NONE;
-static int port2_term_gpio = GPIO_NONE;
-static int port3_term_gpio = GPIO_NONE;
-static int port4_term_gpio = GPIO_NONE;
-
module_param(reset_gpio, int, S_IRUGO);
-module_param(port1_ntte_gpio, int, S_IRUGO);
-module_param(port2_ntte_gpio, int, S_IRUGO);
-module_param(port3_ntte_gpio, int, S_IRUGO);
-module_param(port4_ntte_gpio, int, S_IRUGO);
-module_param(port1_term_gpio, int, S_IRUGO);
-module_param(port2_term_gpio, int, S_IRUGO);
-module_param(port3_term_gpio, int, S_IRUGO);
-module_param(port4_term_gpio, int, S_IRUGO);
MODULE_PARM_DESC(reset_gpio, "Reset the XHFC using this GPIO"
"(override ACPI platform description)");
-
-MODULE_PARM_DESC(port1_ntte_gpio, "GPIO used for setting port 1 as NT/TE "
- "(default: -1 = none)");
-MODULE_PARM_DESC(port2_ntte_gpio, "GPIO used for setting port 2 as NT/TE "
- "(default: -1 = none)");
-MODULE_PARM_DESC(port3_ntte_gpio, "GPIO used for setting port 3 as NT/TE "
- "(default: -1 = none)");
-MODULE_PARM_DESC(port4_ntte_gpio, "GPIO used for setting port 4 as NT/TE "
- "(default: -1 = none)");
-MODULE_PARM_DESC(port1_term_gpio, "GPIO used for line termination on port 1 "
- "(default: -1 = none)");
-MODULE_PARM_DESC(port2_term_gpio, "GPIO used for line termination on port 2 "
- "(default: -1 = none)");
-MODULE_PARM_DESC(port3_term_gpio, "GPIO used for line termination on port 3 "
- "(default: -1 = none)");
-MODULE_PARM_DESC(port4_term_gpio, "GPIO used for line termination on port 4 "
- "(default: -1 = none)");
#endif
static struct xhfc_pi *g_pi;
@@ -102,7 +71,7 @@ static struct xhfc_pi *g_pi;
uint debug = 0;
uint dbg_spanfilter = 0xFFFFFFFF;
static int exit_after_reset = 0;
-static uint ntte = 0x3;
+static uint ntte = 0x3; // XXX we might want to remove that
module_param(debug, uint, S_IRUGO | S_IWUSR);
module_param(dbg_spanfilter, uint, S_IRUGO | S_IWUSR);
@@ -796,47 +765,49 @@ static void xhfc_hard_reset(void)
#endif
}
-static void configure_ntte(int port, int nt)
+static inline int lebcs1_bit_nt(int port)
{
- static int *ntte_gpio[] = {
- &port1_ntte_gpio,
- &port2_ntte_gpio,
- &port3_ntte_gpio,
- &port4_ntte_gpio,
- };
+ return (3 - port) * 2 + 1;
+}
- if (*ntte_gpio[port] == GPIO_NONE) {
- printk(KERN_WARNING DRIVER_NAME ": Can't configure "
- "port %d as %s (no GPIO configured)\n",
- port + 1, nt ? "NT" : "TE");
- return;
- }
+/* on the leb, cs1 */
+static inline int lebcs1_bit_term(int port)
+{
+ return (3 - port) * 2;
+}
- gpio_set_direction(*ntte_gpio[port], GPIO_OUTPUT);
- gpio_set_to_gpio(*ntte_gpio[port]);
- gpio_set_level(*ntte_gpio[port], nt);
+static inline u8 byte_replace_bit(u8 byte, int nr, bool value)
+{
+ return (byte & ~(1 << nr)) | (value << nr);
}
-static void configure_term(int port, int lineterm)
+static void configure_ntte(struct xhfc_span *xhfc_span, int nt)
{
- static int *term_gpio[] = {
- &port1_term_gpio,
- &port2_term_gpio,
- &port3_term_gpio,
- &port4_term_gpio,
- };
+ struct xhfc *xhfc = xhfc_span->xhfc;
+ u8 newb;
+ newb = byte_replace_bit(xhfc->pi->soft_conf_byte,
+ lebcs1_bit_nt(xhfc_span->port),
+ !!nt);
+ xhfc->pi->soft_conf_byte = newb;
+ write_xhfc_soft_conf(xhfc, newb);
+}
- if (*term_gpio[port] == GPIO_NONE) {
- printk(KERN_WARNING DRIVER_NAME ": Can't configure "
- "line termination on port %d "
- "(no GPIO configured)\n",
- port + 1);
- return;
- }
+static void configure_term(struct xhfc_span *xhfc_span, int lineterm)
+{
+ struct xhfc *xhfc = xhfc_span->xhfc;
+ u8 newb;
+ newb = byte_replace_bit(xhfc->pi->soft_conf_byte,
+ lebcs1_bit_term(xhfc_span->port),
+ !!lineterm);
+ xhfc->pi->soft_conf_byte = newb;
+ write_xhfc_soft_conf(xhfc, xhfc->pi->soft_conf_byte);
+}
- gpio_set_direction(*term_gpio[port], GPIO_OUTPUT);
- gpio_set_to_gpio(*term_gpio[port]);
- gpio_set_level(*term_gpio[port], lineterm);
+static void __devinit
+xhfc_preset_all_te_noterm(struct xhfc *xhfc)
+{
+ xhfc->pi->soft_conf_byte = 0; // te: 0 / noterm: 0
+ write_xhfc_soft_conf(xhfc, 0);
}
static void xhfc_init_and_configure(struct xhfc* x)
@@ -883,8 +854,8 @@ static int xhfc_spanconfig(struct dahdi_span *span, struct dahdi_lineconfig *lc)
term ? "ENABLED" : "DISABLED");
xhfc_config_st(xhfc, xhfc_span->port, xhfc_span->nt);
- configure_ntte(xhfc_span->port, xhfc_span->nt);
- configure_term(xhfc_span->port, term);
+ configure_ntte(xhfc_span, xhfc_span->nt);
+ configure_term(xhfc_span, term);
if (lc->sync < 0) {
printk(KERN_INFO DRIVER_NAME
@@ -1126,6 +1097,8 @@ static int __devinit xhfc_init_one(struct pci_dev *pdev,
* see [Intel 320066] 42.4.1.1 Chip Select Address Allocation */
pi->cs_n1 = pi->cs_n0 + 16 * 1024 * 1024;
+ /* WARNING: don't use cs_n0 / cs_n1 before leb_init() */
+
pci_set_drvdata(pdev, pi);
@@ -1133,6 +1106,10 @@ static int __devinit xhfc_init_one(struct pci_dev *pdev,
* Hard init *
*************/
+ leb_init(pi); // XXX maybe we should disable the CS on exit?
+
+ xhfc_preset_all_te_noterm(&pi->xhfc);
+
xhfc_hard_reset();
if (exit_after_reset) {
@@ -1140,8 +1117,6 @@ static int __devinit xhfc_init_one(struct pci_dev *pdev,
goto exit_after_reset;
}
- leb_init(pi);
-
#ifdef AUDIO
/*************