diff options
-rw-r--r-- | drivers/isdn/hardware/mISDN/Kconfig | 11 | ||||
-rw-r--r-- | drivers/isdn/hardware/mISDN/hfc_multi.h | 45 | ||||
-rw-r--r-- | drivers/isdn/hardware/mISDN/hfc_multi_8xx.h | 167 | ||||
-rw-r--r-- | drivers/isdn/hardware/mISDN/hfcmulti.c | 416 | ||||
-rw-r--r-- | drivers/isdn/mISDN/dsp_cmx.c | 4 | ||||
-rw-r--r-- | include/linux/mISDNdsp.h | 1 |
6 files changed, 500 insertions, 144 deletions
diff --git a/drivers/isdn/hardware/mISDN/Kconfig b/drivers/isdn/hardware/mISDN/Kconfig index fd112ae252cf..3024566dd099 100644 --- a/drivers/isdn/hardware/mISDN/Kconfig +++ b/drivers/isdn/hardware/mISDN/Kconfig | |||
@@ -13,7 +13,7 @@ config MISDN_HFCPCI | |||
13 | 13 | ||
14 | config MISDN_HFCMULTI | 14 | config MISDN_HFCMULTI |
15 | tristate "Support for HFC multiport cards (HFC-4S/8S/E1)" | 15 | tristate "Support for HFC multiport cards (HFC-4S/8S/E1)" |
16 | depends on PCI | 16 | depends on PCI || 8xx |
17 | depends on MISDN | 17 | depends on MISDN |
18 | help | 18 | help |
19 | Enable support for cards with Cologne Chip AG's HFC multiport | 19 | Enable support for cards with Cologne Chip AG's HFC multiport |
@@ -23,6 +23,15 @@ config MISDN_HFCMULTI | |||
23 | * HFC-8S (8 S/T interfaces on one chip) | 23 | * HFC-8S (8 S/T interfaces on one chip) |
24 | * HFC-E1 (E1 interface for 2Mbit ISDN) | 24 | * HFC-E1 (E1 interface for 2Mbit ISDN) |
25 | 25 | ||
26 | config MISDN_HFCMULTI_8xx | ||
27 | boolean "Support for XHFC embedded board in HFC multiport driver" | ||
28 | depends on MISDN | ||
29 | depends on MISDN_HFCMULTI | ||
30 | depends on 8xx | ||
31 | default 8xx | ||
32 | help | ||
33 | Enable support for the XHFC embedded solution from Speech Design. | ||
34 | |||
26 | config MISDN_HFCUSB | 35 | config MISDN_HFCUSB |
27 | tristate "Support for HFC-S USB based TAs" | 36 | tristate "Support for HFC-S USB based TAs" |
28 | depends on USB | 37 | depends on USB |
diff --git a/drivers/isdn/hardware/mISDN/hfc_multi.h b/drivers/isdn/hardware/mISDN/hfc_multi.h index c4878cc712c9..0c773866efc7 100644 --- a/drivers/isdn/hardware/mISDN/hfc_multi.h +++ b/drivers/isdn/hardware/mISDN/hfc_multi.h | |||
@@ -17,6 +17,16 @@ | |||
17 | #define PCI_ENA_REGIO 0x01 | 17 | #define PCI_ENA_REGIO 0x01 |
18 | #define PCI_ENA_MEMIO 0x02 | 18 | #define PCI_ENA_MEMIO 0x02 |
19 | 19 | ||
20 | #define XHFC_IRQ 4 /* SIU_IRQ2 */ | ||
21 | #define XHFC_MEMBASE 0xFE000000 | ||
22 | #define XHFC_MEMSIZE 0x00001000 | ||
23 | #define XHFC_OFFSET 0x00001000 | ||
24 | #define PA_XHFC_A0 0x0020 /* PA10 */ | ||
25 | #define PB_XHFC_IRQ1 0x00000100 /* PB23 */ | ||
26 | #define PB_XHFC_IRQ2 0x00000200 /* PB22 */ | ||
27 | #define PB_XHFC_IRQ3 0x00000400 /* PB21 */ | ||
28 | #define PB_XHFC_IRQ4 0x00000800 /* PB20 */ | ||
29 | |||
20 | /* | 30 | /* |
21 | * NOTE: some registers are assigned multiple times due to different modes | 31 | * NOTE: some registers are assigned multiple times due to different modes |
22 | * also registers are assigned differen for HFC-4s/8s and HFC-E1 | 32 | * also registers are assigned differen for HFC-4s/8s and HFC-E1 |
@@ -81,6 +91,11 @@ struct hfcm_hw { | |||
81 | #define HFC_CFG_CRC4 10 /* disable CRC-4 Multiframe mode, */ | 91 | #define HFC_CFG_CRC4 10 /* disable CRC-4 Multiframe mode, */ |
82 | /* use double frame instead. */ | 92 | /* use double frame instead. */ |
83 | 93 | ||
94 | #define HFC_TYPE_E1 1 /* controller is HFC-E1 */ | ||
95 | #define HFC_TYPE_4S 4 /* controller is HFC-4S */ | ||
96 | #define HFC_TYPE_8S 8 /* controller is HFC-8S */ | ||
97 | #define HFC_TYPE_XHFC 5 /* controller is XHFC */ | ||
98 | |||
84 | #define HFC_CHIP_EXRAM_128 0 /* external ram 128k */ | 99 | #define HFC_CHIP_EXRAM_128 0 /* external ram 128k */ |
85 | #define HFC_CHIP_EXRAM_512 1 /* external ram 256k */ | 100 | #define HFC_CHIP_EXRAM_512 1 /* external ram 256k */ |
86 | #define HFC_CHIP_REVISION0 2 /* old fifo handling */ | 101 | #define HFC_CHIP_REVISION0 2 /* old fifo handling */ |
@@ -88,19 +103,22 @@ struct hfcm_hw { | |||
88 | #define HFC_CHIP_PCM_MASTER 4 /* PCM is master */ | 103 | #define HFC_CHIP_PCM_MASTER 4 /* PCM is master */ |
89 | #define HFC_CHIP_RX_SYNC 5 /* disable pll sync for pcm */ | 104 | #define HFC_CHIP_RX_SYNC 5 /* disable pll sync for pcm */ |
90 | #define HFC_CHIP_DTMF 6 /* DTMF decoding is enabled */ | 105 | #define HFC_CHIP_DTMF 6 /* DTMF decoding is enabled */ |
91 | #define HFC_CHIP_ULAW 7 /* ULAW mode */ | 106 | #define HFC_CHIP_CONF 7 /* conference handling is enabled */ |
92 | #define HFC_CHIP_CLOCK2 8 /* double clock mode */ | 107 | #define HFC_CHIP_ULAW 8 /* ULAW mode */ |
93 | #define HFC_CHIP_E1CLOCK_GET 9 /* always get clock from E1 interface */ | 108 | #define HFC_CHIP_CLOCK2 9 /* double clock mode */ |
94 | #define HFC_CHIP_E1CLOCK_PUT 10 /* always put clock from E1 interface */ | 109 | #define HFC_CHIP_E1CLOCK_GET 10 /* always get clock from E1 interface */ |
95 | #define HFC_CHIP_WATCHDOG 11 /* whether we should send signals */ | 110 | #define HFC_CHIP_E1CLOCK_PUT 11 /* always put clock from E1 interface */ |
111 | #define HFC_CHIP_WATCHDOG 12 /* whether we should send signals */ | ||
96 | /* to the watchdog */ | 112 | /* to the watchdog */ |
97 | #define HFC_CHIP_B410P 12 /* whether we have a b410p with echocan in */ | 113 | #define HFC_CHIP_B410P 13 /* whether we have a b410p with echocan in */ |
98 | /* hw */ | 114 | /* hw */ |
99 | #define HFC_CHIP_PLXSD 13 /* whether we have a Speech-Design PLX */ | 115 | #define HFC_CHIP_PLXSD 14 /* whether we have a Speech-Design PLX */ |
116 | #define HFC_CHIP_EMBSD 15 /* whether we have a SD Embedded board */ | ||
100 | 117 | ||
101 | #define HFC_IO_MODE_PCIMEM 0x00 /* normal memory mapped IO */ | 118 | #define HFC_IO_MODE_PCIMEM 0x00 /* normal memory mapped IO */ |
102 | #define HFC_IO_MODE_REGIO 0x01 /* PCI io access */ | 119 | #define HFC_IO_MODE_REGIO 0x01 /* PCI io access */ |
103 | #define HFC_IO_MODE_PLXSD 0x02 /* access HFC via PLX9030 */ | 120 | #define HFC_IO_MODE_PLXSD 0x02 /* access HFC via PLX9030 */ |
121 | #define HFC_IO_MODE_EMBSD 0x03 /* direct access */ | ||
104 | 122 | ||
105 | /* table entry in the PCI devices list */ | 123 | /* table entry in the PCI devices list */ |
106 | struct hm_map { | 124 | struct hm_map { |
@@ -113,6 +131,7 @@ struct hm_map { | |||
113 | int opticalsupport; | 131 | int opticalsupport; |
114 | int dip_type; | 132 | int dip_type; |
115 | int io_mode; | 133 | int io_mode; |
134 | int irq; | ||
116 | }; | 135 | }; |
117 | 136 | ||
118 | struct hfc_multi { | 137 | struct hfc_multi { |
@@ -120,7 +139,7 @@ struct hfc_multi { | |||
120 | struct hm_map *mtyp; | 139 | struct hm_map *mtyp; |
121 | int id; | 140 | int id; |
122 | int pcm; /* id of pcm bus */ | 141 | int pcm; /* id of pcm bus */ |
123 | int type; | 142 | int ctype; /* controller type */ |
124 | int ports; | 143 | int ports; |
125 | 144 | ||
126 | u_int irq; /* irq used by card */ | 145 | u_int irq; /* irq used by card */ |
@@ -160,10 +179,16 @@ struct hfc_multi { | |||
160 | int len); | 179 | int len); |
161 | void (*write_fifo)(struct hfc_multi *hc, u_char *data, | 180 | void (*write_fifo)(struct hfc_multi *hc, u_char *data, |
162 | int len); | 181 | int len); |
163 | u_long pci_origmembase, plx_origmembase, dsp_origmembase; | 182 | u_long pci_origmembase, plx_origmembase; |
164 | void __iomem *pci_membase; /* PCI memory */ | 183 | void __iomem *pci_membase; /* PCI memory */ |
165 | void __iomem *plx_membase; /* PLX memory */ | 184 | void __iomem *plx_membase; /* PLX memory */ |
166 | u_char *dsp_membase; /* DSP on PLX */ | 185 | u_long xhfc_origmembase; |
186 | u_char *xhfc_membase; | ||
187 | u_long *xhfc_memaddr, *xhfc_memdata; | ||
188 | #ifdef CONFIG_MISDN_HFCMULTI_8xx | ||
189 | struct immap *immap; | ||
190 | #endif | ||
191 | u_long pb_irqmsk; /* Portbit mask to check the IRQ line */ | ||
167 | u_long pci_iobase; /* PCI IO */ | 192 | u_long pci_iobase; /* PCI IO */ |
168 | struct hfcm_hw hw; /* remember data of write-only-registers */ | 193 | struct hfcm_hw hw; /* remember data of write-only-registers */ |
169 | 194 | ||
diff --git a/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h b/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h new file mode 100644 index 000000000000..45ddced956d5 --- /dev/null +++ b/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h | |||
@@ -0,0 +1,167 @@ | |||
1 | /* | ||
2 | * For License see notice in hfc_multi.c | ||
3 | * | ||
4 | * special IO and init functions for the embedded XHFC board | ||
5 | * from Speech Design | ||
6 | * | ||
7 | */ | ||
8 | |||
9 | #include <asm/8xx_immap.h> | ||
10 | |||
11 | /* Change this to the value used by your board */ | ||
12 | #ifndef IMAP_ADDR | ||
13 | #define IMAP_ADDR 0xFFF00000 | ||
14 | #endif | ||
15 | |||
16 | static void | ||
17 | #ifdef HFC_REGISTER_DEBUG | ||
18 | HFC_outb_embsd(struct hfc_multi *hc, u_char reg, u_char val, | ||
19 | const char *function, int line) | ||
20 | #else | ||
21 | HFC_outb_embsd(struct hfc_multi *hc, u_char reg, u_char val) | ||
22 | #endif | ||
23 | { | ||
24 | hc->immap->im_ioport.iop_padat |= PA_XHFC_A0; | ||
25 | writeb(reg, hc->xhfc_memaddr); | ||
26 | hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0); | ||
27 | writeb(val, hc->xhfc_memdata); | ||
28 | } | ||
29 | static u_char | ||
30 | #ifdef HFC_REGISTER_DEBUG | ||
31 | HFC_inb_embsd(struct hfc_multi *hc, u_char reg, const char *function, int line) | ||
32 | #else | ||
33 | HFC_inb_embsd(struct hfc_multi *hc, u_char reg) | ||
34 | #endif | ||
35 | { | ||
36 | hc->immap->im_ioport.iop_padat |= PA_XHFC_A0; | ||
37 | writeb(reg, hc->xhfc_memaddr); | ||
38 | hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0); | ||
39 | return readb(hc->xhfc_memdata); | ||
40 | } | ||
41 | static u_short | ||
42 | #ifdef HFC_REGISTER_DEBUG | ||
43 | HFC_inw_embsd(struct hfc_multi *hc, u_char reg, const char *function, int line) | ||
44 | #else | ||
45 | HFC_inw_embsd(struct hfc_multi *hc, u_char reg) | ||
46 | #endif | ||
47 | { | ||
48 | hc->immap->im_ioport.iop_padat |= PA_XHFC_A0; | ||
49 | writeb(reg, hc->xhfc_memaddr); | ||
50 | hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0); | ||
51 | return readb(hc->xhfc_memdata); | ||
52 | } | ||
53 | static void | ||
54 | #ifdef HFC_REGISTER_DEBUG | ||
55 | HFC_wait_embsd(struct hfc_multi *hc, const char *function, int line) | ||
56 | #else | ||
57 | HFC_wait_embsd(struct hfc_multi *hc) | ||
58 | #endif | ||
59 | { | ||
60 | hc->immap->im_ioport.iop_padat |= PA_XHFC_A0; | ||
61 | writeb(R_STATUS, hc->xhfc_memaddr); | ||
62 | hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0); | ||
63 | while (readb(hc->xhfc_memdata) & V_BUSY) | ||
64 | cpu_relax(); | ||
65 | } | ||
66 | |||
67 | /* write fifo data (EMBSD) */ | ||
68 | void | ||
69 | write_fifo_embsd(struct hfc_multi *hc, u_char *data, int len) | ||
70 | { | ||
71 | hc->immap->im_ioport.iop_padat |= PA_XHFC_A0; | ||
72 | *hc->xhfc_memaddr = A_FIFO_DATA0; | ||
73 | hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0); | ||
74 | while (len) { | ||
75 | *hc->xhfc_memdata = *data; | ||
76 | data++; | ||
77 | len--; | ||
78 | } | ||
79 | } | ||
80 | |||
81 | /* read fifo data (EMBSD) */ | ||
82 | void | ||
83 | read_fifo_embsd(struct hfc_multi *hc, u_char *data, int len) | ||
84 | { | ||
85 | hc->immap->im_ioport.iop_padat |= PA_XHFC_A0; | ||
86 | *hc->xhfc_memaddr = A_FIFO_DATA0; | ||
87 | hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0); | ||
88 | while (len) { | ||
89 | *data = (u_char)(*hc->xhfc_memdata); | ||
90 | data++; | ||
91 | len--; | ||
92 | } | ||
93 | } | ||
94 | |||
95 | static int | ||
96 | setup_embedded(struct hfc_multi *hc, struct hm_map *m) | ||
97 | { | ||
98 | printk(KERN_INFO | ||
99 | "HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n", | ||
100 | m->vendor_name, m->card_name, m->clock2 ? "double" : "normal"); | ||
101 | |||
102 | hc->pci_dev = NULL; | ||
103 | if (m->clock2) | ||
104 | test_and_set_bit(HFC_CHIP_CLOCK2, &hc->chip); | ||
105 | |||
106 | hc->leds = m->leds; | ||
107 | hc->ledstate = 0xAFFEAFFE; | ||
108 | hc->opticalsupport = m->opticalsupport; | ||
109 | |||
110 | hc->pci_iobase = 0; | ||
111 | hc->pci_membase = 0; | ||
112 | hc->xhfc_membase = NULL; | ||
113 | hc->xhfc_memaddr = NULL; | ||
114 | hc->xhfc_memdata = NULL; | ||
115 | |||
116 | /* set memory access methods */ | ||
117 | if (m->io_mode) /* use mode from card config */ | ||
118 | hc->io_mode = m->io_mode; | ||
119 | switch (hc->io_mode) { | ||
120 | case HFC_IO_MODE_EMBSD: | ||
121 | test_and_set_bit(HFC_CHIP_EMBSD, &hc->chip); | ||
122 | hc->slots = 128; /* required */ | ||
123 | /* fall through */ | ||
124 | hc->HFC_outb = HFC_outb_embsd; | ||
125 | hc->HFC_inb = HFC_inb_embsd; | ||
126 | hc->HFC_inw = HFC_inw_embsd; | ||
127 | hc->HFC_wait = HFC_wait_embsd; | ||
128 | hc->read_fifo = read_fifo_embsd; | ||
129 | hc->write_fifo = write_fifo_embsd; | ||
130 | hc->xhfc_origmembase = XHFC_MEMBASE + XHFC_OFFSET * hc->id; | ||
131 | hc->xhfc_membase = (u_char *)ioremap(hc->xhfc_origmembase, | ||
132 | XHFC_MEMSIZE); | ||
133 | if (!hc->xhfc_membase) { | ||
134 | printk(KERN_WARNING | ||
135 | "HFC-multi: failed to remap xhfc address space. " | ||
136 | "(internal error)\n"); | ||
137 | return -EIO; | ||
138 | } | ||
139 | hc->xhfc_memaddr = (u_long *)(hc->xhfc_membase + 4); | ||
140 | hc->xhfc_memdata = (u_long *)(hc->xhfc_membase); | ||
141 | printk(KERN_INFO | ||
142 | "HFC-multi: xhfc_membase:%#lx xhfc_origmembase:%#lx " | ||
143 | "xhfc_memaddr:%#lx xhfc_memdata:%#lx\n", | ||
144 | (u_long)hc->xhfc_membase, hc->xhfc_origmembase, | ||
145 | (u_long)hc->xhfc_memaddr, (u_long)hc->xhfc_memdata); | ||
146 | break; | ||
147 | default: | ||
148 | printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n"); | ||
149 | return -EIO; | ||
150 | } | ||
151 | |||
152 | /* Prepare the MPC8XX PortA 10 as output (address/data selector) */ | ||
153 | hc->immap = (struct immap *)(IMAP_ADDR); | ||
154 | hc->immap->im_ioport.iop_papar &= ~(PA_XHFC_A0); | ||
155 | hc->immap->im_ioport.iop_paodr &= ~(PA_XHFC_A0); | ||
156 | hc->immap->im_ioport.iop_padir |= PA_XHFC_A0; | ||
157 | |||
158 | /* Prepare the MPC8xx PortB __X__ as input (ISDN__X__IRQ) */ | ||
159 | hc->pb_irqmsk = (PB_XHFC_IRQ1 << hc->id); | ||
160 | hc->immap->im_cpm.cp_pbpar &= ~(hc->pb_irqmsk); | ||
161 | hc->immap->im_cpm.cp_pbodr &= ~(hc->pb_irqmsk); | ||
162 | hc->immap->im_cpm.cp_pbdir &= ~(hc->pb_irqmsk); | ||
163 | |||
164 | /* At this point the needed config is done */ | ||
165 | /* fifos are still not enabled */ | ||
166 | return 0; | ||
167 | } | ||
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c index bc0d3efeb567..5be4edf631d9 100644 --- a/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/drivers/isdn/hardware/mISDN/hfcmulti.c | |||
@@ -139,6 +139,10 @@ | |||
139 | * Selects interface with clock source for mISDN and applications. | 139 | * Selects interface with clock source for mISDN and applications. |
140 | * Set to card number starting with 1. Set to -1 to disable. | 140 | * Set to card number starting with 1. Set to -1 to disable. |
141 | * By default, the first card is used as clock source. | 141 | * By default, the first card is used as clock source. |
142 | * | ||
143 | * hwid: | ||
144 | * NOTE: only one hwid value must be given once | ||
145 | * Enable special embedded devices with XHFC controllers. | ||
142 | */ | 146 | */ |
143 | 147 | ||
144 | /* | 148 | /* |
@@ -206,6 +210,11 @@ static int clock; | |||
206 | static uint timer; | 210 | static uint timer; |
207 | static uint clockdelay_te = CLKDEL_TE; | 211 | static uint clockdelay_te = CLKDEL_TE; |
208 | static uint clockdelay_nt = CLKDEL_NT; | 212 | static uint clockdelay_nt = CLKDEL_NT; |
213 | #define HWID_NONE 0 | ||
214 | #define HWID_MINIP4 1 | ||
215 | #define HWID_MINIP8 2 | ||
216 | #define HWID_MINIP16 3 | ||
217 | static uint hwid = HWID_NONE; | ||
209 | 218 | ||
210 | static int HFC_cnt, Port_cnt, PCM_cnt = 99; | 219 | static int HFC_cnt, Port_cnt, PCM_cnt = 99; |
211 | 220 | ||
@@ -223,6 +232,7 @@ module_param_array(pcm, int, NULL, S_IRUGO | S_IWUSR); | |||
223 | module_param_array(dslot, int, NULL, S_IRUGO | S_IWUSR); | 232 | module_param_array(dslot, int, NULL, S_IRUGO | S_IWUSR); |
224 | module_param_array(iomode, uint, NULL, S_IRUGO | S_IWUSR); | 233 | module_param_array(iomode, uint, NULL, S_IRUGO | S_IWUSR); |
225 | module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR); | 234 | module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR); |
235 | module_param(hwid, uint, S_IRUGO | S_IWUSR); /* The hardware ID */ | ||
226 | 236 | ||
227 | #ifdef HFC_REGISTER_DEBUG | 237 | #ifdef HFC_REGISTER_DEBUG |
228 | #define HFC_outb(hc, reg, val) \ | 238 | #define HFC_outb(hc, reg, val) \ |
@@ -252,6 +262,10 @@ module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR); | |||
252 | #define HFC_wait_nodebug(hc) (hc->HFC_wait_nodebug(hc)) | 262 | #define HFC_wait_nodebug(hc) (hc->HFC_wait_nodebug(hc)) |
253 | #endif | 263 | #endif |
254 | 264 | ||
265 | #ifdef CONFIG_MISDN_HFCMULTI_8xx | ||
266 | #include "hfc_multi_8xx.h" | ||
267 | #endif | ||
268 | |||
255 | /* HFC_IO_MODE_PCIMEM */ | 269 | /* HFC_IO_MODE_PCIMEM */ |
256 | static void | 270 | static void |
257 | #ifdef HFC_REGISTER_DEBUG | 271 | #ifdef HFC_REGISTER_DEBUG |
@@ -928,7 +942,7 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm) | |||
928 | writel(pv, plx_acc_32); | 942 | writel(pv, plx_acc_32); |
929 | if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) { | 943 | if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) { |
930 | pcmmaster = hc; | 944 | pcmmaster = hc; |
931 | if (hc->type == 1) { | 945 | if (hc->ctype == HFC_TYPE_E1) { |
932 | if (debug & DEBUG_HFCMULTI_PLXSD) | 946 | if (debug & DEBUG_HFCMULTI_PLXSD) |
933 | printk(KERN_DEBUG | 947 | printk(KERN_DEBUG |
934 | "Schedule SYNC_I\n"); | 948 | "Schedule SYNC_I\n"); |
@@ -949,7 +963,8 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm) | |||
949 | pv |= PLX_SYNC_O_EN; | 963 | pv |= PLX_SYNC_O_EN; |
950 | writel(pv, plx_acc_32); | 964 | writel(pv, plx_acc_32); |
951 | /* switch to jatt PLL, if not disabled by RX_SYNC */ | 965 | /* switch to jatt PLL, if not disabled by RX_SYNC */ |
952 | if (hc->type == 1 && !test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) { | 966 | if (hc->ctype == HFC_TYPE_E1 |
967 | && !test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) { | ||
953 | if (debug & DEBUG_HFCMULTI_PLXSD) | 968 | if (debug & DEBUG_HFCMULTI_PLXSD) |
954 | printk(KERN_DEBUG "Schedule jatt PLL\n"); | 969 | printk(KERN_DEBUG "Schedule jatt PLL\n"); |
955 | hc->e1_resync |= 2; /* switch to jatt */ | 970 | hc->e1_resync |= 2; /* switch to jatt */ |
@@ -961,7 +976,7 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm) | |||
961 | printk(KERN_DEBUG | 976 | printk(KERN_DEBUG |
962 | "id=%d (0x%p) = PCM master syncronized " | 977 | "id=%d (0x%p) = PCM master syncronized " |
963 | "with QUARTZ\n", hc->id, hc); | 978 | "with QUARTZ\n", hc->id, hc); |
964 | if (hc->type == 1) { | 979 | if (hc->ctype == HFC_TYPE_E1) { |
965 | /* Use the crystal clock for the PCM | 980 | /* Use the crystal clock for the PCM |
966 | master card */ | 981 | master card */ |
967 | if (debug & DEBUG_HFCMULTI_PLXSD) | 982 | if (debug & DEBUG_HFCMULTI_PLXSD) |
@@ -972,7 +987,7 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm) | |||
972 | if (debug & DEBUG_HFCMULTI_PLXSD) | 987 | if (debug & DEBUG_HFCMULTI_PLXSD) |
973 | printk(KERN_DEBUG | 988 | printk(KERN_DEBUG |
974 | "QUARTZ is automatically " | 989 | "QUARTZ is automatically " |
975 | "enabled by HFC-%dS\n", hc->type); | 990 | "enabled by HFC-%dS\n", hc->ctype); |
976 | } | 991 | } |
977 | plx_acc_32 = hc->plx_membase + PLX_GPIOC; | 992 | plx_acc_32 = hc->plx_membase + PLX_GPIOC; |
978 | pv = readl(plx_acc_32); | 993 | pv = readl(plx_acc_32); |
@@ -1060,13 +1075,16 @@ release_io_hfcmulti(struct hfc_multi *hc) | |||
1060 | 1075 | ||
1061 | /* disable memory mapped ports / io ports */ | 1076 | /* disable memory mapped ports / io ports */ |
1062 | test_and_clear_bit(HFC_CHIP_PLXSD, &hc->chip); /* prevent resync */ | 1077 | test_and_clear_bit(HFC_CHIP_PLXSD, &hc->chip); /* prevent resync */ |
1063 | pci_write_config_word(hc->pci_dev, PCI_COMMAND, 0); | 1078 | if (hc->pci_dev) |
1079 | pci_write_config_word(hc->pci_dev, PCI_COMMAND, 0); | ||
1064 | if (hc->pci_membase) | 1080 | if (hc->pci_membase) |
1065 | iounmap(hc->pci_membase); | 1081 | iounmap(hc->pci_membase); |
1066 | if (hc->plx_membase) | 1082 | if (hc->plx_membase) |
1067 | iounmap(hc->plx_membase); | 1083 | iounmap(hc->plx_membase); |
1068 | if (hc->pci_iobase) | 1084 | if (hc->pci_iobase) |
1069 | release_region(hc->pci_iobase, 8); | 1085 | release_region(hc->pci_iobase, 8); |
1086 | if (hc->xhfc_membase) | ||
1087 | iounmap((void *)hc->xhfc_membase); | ||
1070 | 1088 | ||
1071 | if (hc->pci_dev) { | 1089 | if (hc->pci_dev) { |
1072 | pci_disable_device(hc->pci_dev); | 1090 | pci_disable_device(hc->pci_dev); |
@@ -1100,8 +1118,9 @@ init_chip(struct hfc_multi *hc) | |||
1100 | /* revision check */ | 1118 | /* revision check */ |
1101 | if (debug & DEBUG_HFCMULTI_INIT) | 1119 | if (debug & DEBUG_HFCMULTI_INIT) |
1102 | printk(KERN_DEBUG "%s: entered\n", __func__); | 1120 | printk(KERN_DEBUG "%s: entered\n", __func__); |
1103 | val = HFC_inb(hc, R_CHIP_ID)>>4; | 1121 | val = HFC_inb(hc, R_CHIP_ID); |
1104 | if (val != 0x8 && val != 0xc && val != 0xe) { | 1122 | if ((val>>4) != 0x8 && (val>>4) != 0xc && (val>>4) != 0xe |
1123 | && (val>>1) != 0x31) { | ||
1105 | printk(KERN_INFO "HFC_multi: unknown CHIP_ID:%x\n", (u_int)val); | 1124 | printk(KERN_INFO "HFC_multi: unknown CHIP_ID:%x\n", (u_int)val); |
1106 | err = -EIO; | 1125 | err = -EIO; |
1107 | goto out; | 1126 | goto out; |
@@ -1109,8 +1128,9 @@ init_chip(struct hfc_multi *hc) | |||
1109 | rev = HFC_inb(hc, R_CHIP_RV); | 1128 | rev = HFC_inb(hc, R_CHIP_RV); |
1110 | printk(KERN_INFO | 1129 | printk(KERN_INFO |
1111 | "HFC_multi: detected HFC with chip ID=0x%lx revision=%ld%s\n", | 1130 | "HFC_multi: detected HFC with chip ID=0x%lx revision=%ld%s\n", |
1112 | val, rev, (rev == 0) ? " (old FIFO handling)" : ""); | 1131 | val, rev, (rev == 0 && (hc->ctype != HFC_TYPE_XHFC)) ? |
1113 | if (rev == 0) { | 1132 | " (old FIFO handling)" : ""); |
1133 | if (hc->ctype != HFC_TYPE_XHFC && rev == 0) { | ||
1114 | test_and_set_bit(HFC_CHIP_REVISION0, &hc->chip); | 1134 | test_and_set_bit(HFC_CHIP_REVISION0, &hc->chip); |
1115 | printk(KERN_WARNING | 1135 | printk(KERN_WARNING |
1116 | "HFC_multi: NOTE: Your chip is revision 0, " | 1136 | "HFC_multi: NOTE: Your chip is revision 0, " |
@@ -1152,6 +1172,12 @@ init_chip(struct hfc_multi *hc) | |||
1152 | hc->Zlen = 8000; | 1172 | hc->Zlen = 8000; |
1153 | hc->DTMFbase = 0x2000; | 1173 | hc->DTMFbase = 0x2000; |
1154 | } | 1174 | } |
1175 | if (hc->ctype == HFC_TYPE_XHFC) { | ||
1176 | hc->Flen = 0x8; | ||
1177 | hc->Zmin = 0x0; | ||
1178 | hc->Zlen = 64; | ||
1179 | hc->DTMFbase = 0x0; | ||
1180 | } | ||
1155 | hc->max_trans = poll << 1; | 1181 | hc->max_trans = poll << 1; |
1156 | if (hc->max_trans > hc->Zlen) | 1182 | if (hc->max_trans > hc->Zlen) |
1157 | hc->max_trans = hc->Zlen; | 1183 | hc->max_trans = hc->Zlen; |
@@ -1211,6 +1237,9 @@ init_chip(struct hfc_multi *hc) | |||
1211 | hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */ | 1237 | hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */ |
1212 | } | 1238 | } |
1213 | 1239 | ||
1240 | if (test_bit(HFC_CHIP_EMBSD, &hc->chip)) | ||
1241 | hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */ | ||
1242 | |||
1214 | /* we only want the real Z2 read-pointer for revision > 0 */ | 1243 | /* we only want the real Z2 read-pointer for revision > 0 */ |
1215 | if (!test_bit(HFC_CHIP_REVISION0, &hc->chip)) | 1244 | if (!test_bit(HFC_CHIP_REVISION0, &hc->chip)) |
1216 | hc->hw.r_ram_sz |= V_FZ_MD; | 1245 | hc->hw.r_ram_sz |= V_FZ_MD; |
@@ -1234,15 +1263,24 @@ init_chip(struct hfc_multi *hc) | |||
1234 | 1263 | ||
1235 | /* soft reset */ | 1264 | /* soft reset */ |
1236 | HFC_outb(hc, R_CTRL, hc->hw.r_ctrl); | 1265 | HFC_outb(hc, R_CTRL, hc->hw.r_ctrl); |
1237 | HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz); | 1266 | if (hc->ctype == HFC_TYPE_XHFC) |
1267 | HFC_outb(hc, 0x0C /* R_FIFO_THRES */, | ||
1268 | 0x11 /* 16 Bytes TX/RX */); | ||
1269 | else | ||
1270 | HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz); | ||
1238 | HFC_outb(hc, R_FIFO_MD, 0); | 1271 | HFC_outb(hc, R_FIFO_MD, 0); |
1239 | hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES | V_RLD_EPR; | 1272 | if (hc->ctype == HFC_TYPE_XHFC) |
1273 | hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES; | ||
1274 | else | ||
1275 | hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES | ||
1276 | | V_RLD_EPR; | ||
1240 | HFC_outb(hc, R_CIRM, hc->hw.r_cirm); | 1277 | HFC_outb(hc, R_CIRM, hc->hw.r_cirm); |
1241 | udelay(100); | 1278 | udelay(100); |
1242 | hc->hw.r_cirm = 0; | 1279 | hc->hw.r_cirm = 0; |
1243 | HFC_outb(hc, R_CIRM, hc->hw.r_cirm); | 1280 | HFC_outb(hc, R_CIRM, hc->hw.r_cirm); |
1244 | udelay(100); | 1281 | udelay(100); |
1245 | HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz); | 1282 | if (hc->ctype != HFC_TYPE_XHFC) |
1283 | HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz); | ||
1246 | 1284 | ||
1247 | /* Speech Design PLX bridge pcm and sync mode */ | 1285 | /* Speech Design PLX bridge pcm and sync mode */ |
1248 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { | 1286 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { |
@@ -1278,13 +1316,16 @@ init_chip(struct hfc_multi *hc) | |||
1278 | HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0xa0); | 1316 | HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0xa0); |
1279 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) | 1317 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) |
1280 | HFC_outb(hc, R_PCM_MD2, V_SYNC_SRC); /* sync via SYNC_I / O */ | 1318 | HFC_outb(hc, R_PCM_MD2, V_SYNC_SRC); /* sync via SYNC_I / O */ |
1319 | else if (test_bit(HFC_CHIP_EMBSD, &hc->chip)) | ||
1320 | HFC_outb(hc, R_PCM_MD2, 0x10); /* V_C2O_EN */ | ||
1281 | else | 1321 | else |
1282 | HFC_outb(hc, R_PCM_MD2, 0x00); /* sync from interface */ | 1322 | HFC_outb(hc, R_PCM_MD2, 0x00); /* sync from interface */ |
1283 | HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00); | 1323 | HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00); |
1284 | for (i = 0; i < 256; i++) { | 1324 | for (i = 0; i < 256; i++) { |
1285 | HFC_outb_nodebug(hc, R_SLOT, i); | 1325 | HFC_outb_nodebug(hc, R_SLOT, i); |
1286 | HFC_outb_nodebug(hc, A_SL_CFG, 0); | 1326 | HFC_outb_nodebug(hc, A_SL_CFG, 0); |
1287 | HFC_outb_nodebug(hc, A_CONF, 0); | 1327 | if (hc->ctype != HFC_TYPE_XHFC) |
1328 | HFC_outb_nodebug(hc, A_CONF, 0); | ||
1288 | hc->slot_owner[i] = -1; | 1329 | hc->slot_owner[i] = -1; |
1289 | } | 1330 | } |
1290 | 1331 | ||
@@ -1296,6 +1337,9 @@ init_chip(struct hfc_multi *hc) | |||
1296 | HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK); | 1337 | HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK); |
1297 | } | 1338 | } |
1298 | 1339 | ||
1340 | if (test_bit(HFC_CHIP_EMBSD, &hc->chip)) | ||
1341 | HFC_outb(hc, 0x02 /* R_CLK_CFG */, 0x40 /* V_CLKO_OFF */); | ||
1342 | |||
1299 | /* B410P GPIO */ | 1343 | /* B410P GPIO */ |
1300 | if (test_bit(HFC_CHIP_B410P, &hc->chip)) { | 1344 | if (test_bit(HFC_CHIP_B410P, &hc->chip)) { |
1301 | printk(KERN_NOTICE "Setting GPIOs\n"); | 1345 | printk(KERN_NOTICE "Setting GPIOs\n"); |
@@ -1424,7 +1468,7 @@ controller_fail: | |||
1424 | hc->hw.r_irqmsk_misc |= V_TI_IRQMSK; | 1468 | hc->hw.r_irqmsk_misc |= V_TI_IRQMSK; |
1425 | 1469 | ||
1426 | /* set E1 state machine IRQ */ | 1470 | /* set E1 state machine IRQ */ |
1427 | if (hc->type == 1) | 1471 | if (hc->ctype == HFC_TYPE_E1) |
1428 | hc->hw.r_irqmsk_misc |= V_STA_IRQMSK; | 1472 | hc->hw.r_irqmsk_misc |= V_STA_IRQMSK; |
1429 | 1473 | ||
1430 | /* set DTMF detection */ | 1474 | /* set DTMF detection */ |
@@ -1444,7 +1488,8 @@ controller_fail: | |||
1444 | r_conf_en = V_CONF_EN | V_ULAW; | 1488 | r_conf_en = V_CONF_EN | V_ULAW; |
1445 | else | 1489 | else |
1446 | r_conf_en = V_CONF_EN; | 1490 | r_conf_en = V_CONF_EN; |
1447 | HFC_outb(hc, R_CONF_EN, r_conf_en); | 1491 | if (hc->ctype != HFC_TYPE_XHFC) |
1492 | HFC_outb(hc, R_CONF_EN, r_conf_en); | ||
1448 | 1493 | ||
1449 | /* setting leds */ | 1494 | /* setting leds */ |
1450 | switch (hc->leds) { | 1495 | switch (hc->leds) { |
@@ -1468,16 +1513,23 @@ controller_fail: | |||
1468 | break; | 1513 | break; |
1469 | } | 1514 | } |
1470 | 1515 | ||
1516 | if (test_bit(HFC_CHIP_EMBSD, &hc->chip)) { | ||
1517 | hc->hw.r_st_sync = 0x10; /* V_AUTO_SYNCI */ | ||
1518 | HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync); | ||
1519 | } | ||
1520 | |||
1471 | /* set master clock */ | 1521 | /* set master clock */ |
1472 | if (hc->masterclk >= 0) { | 1522 | if (hc->masterclk >= 0) { |
1473 | if (debug & DEBUG_HFCMULTI_INIT) | 1523 | if (debug & DEBUG_HFCMULTI_INIT) |
1474 | printk(KERN_DEBUG "%s: setting ST master clock " | 1524 | printk(KERN_DEBUG "%s: setting ST master clock " |
1475 | "to port %d (0..%d)\n", | 1525 | "to port %d (0..%d)\n", |
1476 | __func__, hc->masterclk, hc->ports-1); | 1526 | __func__, hc->masterclk, hc->ports-1); |
1477 | hc->hw.r_st_sync = hc->masterclk | V_AUTO_SYNC; | 1527 | hc->hw.r_st_sync |= (hc->masterclk | V_AUTO_SYNC); |
1478 | HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync); | 1528 | HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync); |
1479 | } | 1529 | } |
1480 | 1530 | ||
1531 | |||
1532 | |||
1481 | /* setting misc irq */ | 1533 | /* setting misc irq */ |
1482 | HFC_outb(hc, R_IRQMSK_MISC, hc->hw.r_irqmsk_misc); | 1534 | HFC_outb(hc, R_IRQMSK_MISC, hc->hw.r_irqmsk_misc); |
1483 | if (debug & DEBUG_HFCMULTI_INIT) | 1535 | if (debug & DEBUG_HFCMULTI_INIT) |
@@ -1929,7 +1981,7 @@ next_frame: | |||
1929 | Fspace = 1; | 1981 | Fspace = 1; |
1930 | } | 1982 | } |
1931 | /* one frame only for ST D-channels, to allow resending */ | 1983 | /* one frame only for ST D-channels, to allow resending */ |
1932 | if (hc->type != 1 && dch) { | 1984 | if (hc->ctype != HFC_TYPE_E1 && dch) { |
1933 | if (f1 != f2) | 1985 | if (f1 != f2) |
1934 | Fspace = 0; | 1986 | Fspace = 0; |
1935 | } | 1987 | } |
@@ -1971,12 +2023,22 @@ next_frame: | |||
1971 | "slot_tx %d\n", | 2023 | "slot_tx %d\n", |
1972 | __func__, ch, slot_tx); | 2024 | __func__, ch, slot_tx); |
1973 | /* connect slot */ | 2025 | /* connect slot */ |
1974 | HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 | | 2026 | if (hc->ctype == HFC_TYPE_XHFC) |
1975 | V_HDLC_TRP | V_IFF); | 2027 | HFC_outb(hc, A_CON_HDLC, 0xc0 |
2028 | | 0x07 << 2 | V_HDLC_TRP | V_IFF); | ||
2029 | /* Enable FIFO, no interrupt */ | ||
2030 | else | ||
2031 | HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 | | ||
2032 | V_HDLC_TRP | V_IFF); | ||
1976 | HFC_outb_nodebug(hc, R_FIFO, ch<<1 | 1); | 2033 | HFC_outb_nodebug(hc, R_FIFO, ch<<1 | 1); |
1977 | HFC_wait_nodebug(hc); | 2034 | HFC_wait_nodebug(hc); |
1978 | HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 | | 2035 | if (hc->ctype == HFC_TYPE_XHFC) |
1979 | V_HDLC_TRP | V_IFF); | 2036 | HFC_outb(hc, A_CON_HDLC, 0xc0 |
2037 | | 0x07 << 2 | V_HDLC_TRP | V_IFF); | ||
2038 | /* Enable FIFO, no interrupt */ | ||
2039 | else | ||
2040 | HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 | | ||
2041 | V_HDLC_TRP | V_IFF); | ||
1980 | HFC_outb_nodebug(hc, R_FIFO, ch<<1); | 2042 | HFC_outb_nodebug(hc, R_FIFO, ch<<1); |
1981 | HFC_wait_nodebug(hc); | 2043 | HFC_wait_nodebug(hc); |
1982 | } | 2044 | } |
@@ -2004,10 +2066,22 @@ next_frame: | |||
2004 | "FIFO data: channel %d slot_tx %d\n", | 2066 | "FIFO data: channel %d slot_tx %d\n", |
2005 | __func__, ch, slot_tx); | 2067 | __func__, ch, slot_tx); |
2006 | /* disconnect slot */ | 2068 | /* disconnect slot */ |
2007 | HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 | V_HDLC_TRP | V_IFF); | 2069 | if (hc->ctype == HFC_TYPE_XHFC) |
2070 | HFC_outb(hc, A_CON_HDLC, 0x80 | ||
2071 | | 0x07 << 2 | V_HDLC_TRP | V_IFF); | ||
2072 | /* Enable FIFO, no interrupt */ | ||
2073 | else | ||
2074 | HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 | | ||
2075 | V_HDLC_TRP | V_IFF); | ||
2008 | HFC_outb_nodebug(hc, R_FIFO, ch<<1 | 1); | 2076 | HFC_outb_nodebug(hc, R_FIFO, ch<<1 | 1); |
2009 | HFC_wait_nodebug(hc); | 2077 | HFC_wait_nodebug(hc); |
2010 | HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 | V_HDLC_TRP | V_IFF); | 2078 | if (hc->ctype == HFC_TYPE_XHFC) |
2079 | HFC_outb(hc, A_CON_HDLC, 0x80 | ||
2080 | | 0x07 << 2 | V_HDLC_TRP | V_IFF); | ||
2081 | /* Enable FIFO, no interrupt */ | ||
2082 | else | ||
2083 | HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 | | ||
2084 | V_HDLC_TRP | V_IFF); | ||
2011 | HFC_outb_nodebug(hc, R_FIFO, ch<<1); | 2085 | HFC_outb_nodebug(hc, R_FIFO, ch<<1); |
2012 | HFC_wait_nodebug(hc); | 2086 | HFC_wait_nodebug(hc); |
2013 | } | 2087 | } |
@@ -2327,7 +2401,7 @@ handle_timer_irq(struct hfc_multi *hc) | |||
2327 | spin_unlock_irqrestore(&HFClock, flags); | 2401 | spin_unlock_irqrestore(&HFClock, flags); |
2328 | } | 2402 | } |
2329 | 2403 | ||
2330 | if (hc->type != 1 || hc->e1_state == 1) | 2404 | if (hc->ctype != HFC_TYPE_E1 || hc->e1_state == 1) |
2331 | for (ch = 0; ch <= 31; ch++) { | 2405 | for (ch = 0; ch <= 31; ch++) { |
2332 | if (hc->created[hc->chan[ch].port]) { | 2406 | if (hc->created[hc->chan[ch].port]) { |
2333 | hfcmulti_tx(hc, ch); | 2407 | hfcmulti_tx(hc, ch); |
@@ -2350,7 +2424,7 @@ handle_timer_irq(struct hfc_multi *hc) | |||
2350 | } | 2424 | } |
2351 | } | 2425 | } |
2352 | } | 2426 | } |
2353 | if (hc->type == 1 && hc->created[0]) { | 2427 | if (hc->ctype == HFC_TYPE_E1 && hc->created[0]) { |
2354 | dch = hc->chan[hc->dslot].dch; | 2428 | dch = hc->chan[hc->dslot].dch; |
2355 | if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) { | 2429 | if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) { |
2356 | /* LOS */ | 2430 | /* LOS */ |
@@ -2610,7 +2684,10 @@ hfcmulti_interrupt(int intno, void *dev_id) | |||
2610 | "card %d, this is no bug.\n", hc->id + 1, irqsem); | 2684 | "card %d, this is no bug.\n", hc->id + 1, irqsem); |
2611 | irqsem = hc->id + 1; | 2685 | irqsem = hc->id + 1; |
2612 | #endif | 2686 | #endif |
2613 | 2687 | #ifdef CONFIG_MISDN_HFCMULTI_8xx | |
2688 | if (hc->immap->im_cpm.cp_pbdat & hc->pb_irqmsk) | ||
2689 | goto irq_notforus; | ||
2690 | #endif | ||
2614 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { | 2691 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { |
2615 | spin_lock_irqsave(&plx_lock, flags); | 2692 | spin_lock_irqsave(&plx_lock, flags); |
2616 | plx_acc = hc->plx_membase + PLX_INTCSR; | 2693 | plx_acc = hc->plx_membase + PLX_INTCSR; |
@@ -2650,7 +2727,7 @@ hfcmulti_interrupt(int intno, void *dev_id) | |||
2650 | } | 2727 | } |
2651 | hc->irqcnt++; | 2728 | hc->irqcnt++; |
2652 | if (r_irq_statech) { | 2729 | if (r_irq_statech) { |
2653 | if (hc->type != 1) | 2730 | if (hc->ctype != HFC_TYPE_E1) |
2654 | ph_state_irq(hc, r_irq_statech); | 2731 | ph_state_irq(hc, r_irq_statech); |
2655 | } | 2732 | } |
2656 | if (status & V_EXT_IRQSTA) | 2733 | if (status & V_EXT_IRQSTA) |
@@ -2664,7 +2741,7 @@ hfcmulti_interrupt(int intno, void *dev_id) | |||
2664 | r_irq_misc = HFC_inb_nodebug(hc, R_IRQ_MISC); | 2741 | r_irq_misc = HFC_inb_nodebug(hc, R_IRQ_MISC); |
2665 | r_irq_misc &= hc->hw.r_irqmsk_misc; /* ignore disabled irqs */ | 2742 | r_irq_misc &= hc->hw.r_irqmsk_misc; /* ignore disabled irqs */ |
2666 | if (r_irq_misc & V_STA_IRQ) { | 2743 | if (r_irq_misc & V_STA_IRQ) { |
2667 | if (hc->type == 1) { | 2744 | if (hc->ctype == HFC_TYPE_E1) { |
2668 | /* state machine */ | 2745 | /* state machine */ |
2669 | dch = hc->chan[hc->dslot].dch; | 2746 | dch = hc->chan[hc->dslot].dch; |
2670 | e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA); | 2747 | e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA); |
@@ -2786,7 +2863,8 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx, | |||
2786 | if (hc->slot_owner[oslot_tx<<1] == ch) { | 2863 | if (hc->slot_owner[oslot_tx<<1] == ch) { |
2787 | HFC_outb(hc, R_SLOT, oslot_tx << 1); | 2864 | HFC_outb(hc, R_SLOT, oslot_tx << 1); |
2788 | HFC_outb(hc, A_SL_CFG, 0); | 2865 | HFC_outb(hc, A_SL_CFG, 0); |
2789 | HFC_outb(hc, A_CONF, 0); | 2866 | if (hc->ctype != HFC_TYPE_XHFC) |
2867 | HFC_outb(hc, A_CONF, 0); | ||
2790 | hc->slot_owner[oslot_tx<<1] = -1; | 2868 | hc->slot_owner[oslot_tx<<1] = -1; |
2791 | } else { | 2869 | } else { |
2792 | if (debug & DEBUG_HFCMULTI_MODE) | 2870 | if (debug & DEBUG_HFCMULTI_MODE) |
@@ -2839,7 +2917,9 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx, | |||
2839 | flow_tx, routing, conf); | 2917 | flow_tx, routing, conf); |
2840 | HFC_outb(hc, R_SLOT, slot_tx << 1); | 2918 | HFC_outb(hc, R_SLOT, slot_tx << 1); |
2841 | HFC_outb(hc, A_SL_CFG, (ch<<1) | routing); | 2919 | HFC_outb(hc, A_SL_CFG, (ch<<1) | routing); |
2842 | HFC_outb(hc, A_CONF, (conf < 0) ? 0 : (conf | V_CONF_SL)); | 2920 | if (hc->ctype != HFC_TYPE_XHFC) |
2921 | HFC_outb(hc, A_CONF, | ||
2922 | (conf < 0) ? 0 : (conf | V_CONF_SL)); | ||
2843 | hc->slot_owner[slot_tx << 1] = ch; | 2923 | hc->slot_owner[slot_tx << 1] = ch; |
2844 | hc->chan[ch].slot_tx = slot_tx; | 2924 | hc->chan[ch].slot_tx = slot_tx; |
2845 | hc->chan[ch].bank_tx = bank_tx; | 2925 | hc->chan[ch].bank_tx = bank_tx; |
@@ -2889,7 +2969,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx, | |||
2889 | HFC_outb(hc, A_IRQ_MSK, 0); | 2969 | HFC_outb(hc, A_IRQ_MSK, 0); |
2890 | HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); | 2970 | HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); |
2891 | HFC_wait(hc); | 2971 | HFC_wait(hc); |
2892 | if (hc->chan[ch].bch && hc->type != 1) { | 2972 | if (hc->chan[ch].bch && hc->ctype != HFC_TYPE_E1) { |
2893 | hc->hw.a_st_ctrl0[hc->chan[ch].port] &= | 2973 | hc->hw.a_st_ctrl0[hc->chan[ch].port] &= |
2894 | ((ch & 0x3) == 0)? ~V_B1_EN: ~V_B2_EN; | 2974 | ((ch & 0x3) == 0)? ~V_B1_EN: ~V_B2_EN; |
2895 | HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); | 2975 | HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); |
@@ -2965,8 +3045,13 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx, | |||
2965 | /* enable TX fifo */ | 3045 | /* enable TX fifo */ |
2966 | HFC_outb(hc, R_FIFO, ch << 1); | 3046 | HFC_outb(hc, R_FIFO, ch << 1); |
2967 | HFC_wait(hc); | 3047 | HFC_wait(hc); |
2968 | HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 | | 3048 | if (hc->ctype == HFC_TYPE_XHFC) |
2969 | V_HDLC_TRP | V_IFF); | 3049 | HFC_outb(hc, A_CON_HDLC, flow_tx | 0x07 << 2 | |
3050 | V_HDLC_TRP | V_IFF); | ||
3051 | /* Enable FIFO, no interrupt */ | ||
3052 | else | ||
3053 | HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 | | ||
3054 | V_HDLC_TRP | V_IFF); | ||
2970 | HFC_outb(hc, A_SUBCH_CFG, 0); | 3055 | HFC_outb(hc, A_SUBCH_CFG, 0); |
2971 | HFC_outb(hc, A_IRQ_MSK, 0); | 3056 | HFC_outb(hc, A_IRQ_MSK, 0); |
2972 | HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); | 3057 | HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); |
@@ -2976,13 +3061,19 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx, | |||
2976 | /* enable RX fifo */ | 3061 | /* enable RX fifo */ |
2977 | HFC_outb(hc, R_FIFO, (ch<<1)|1); | 3062 | HFC_outb(hc, R_FIFO, (ch<<1)|1); |
2978 | HFC_wait(hc); | 3063 | HFC_wait(hc); |
2979 | HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00 | V_HDLC_TRP); | 3064 | if (hc->ctype == HFC_TYPE_XHFC) |
3065 | HFC_outb(hc, A_CON_HDLC, flow_rx | 0x07 << 2 | | ||
3066 | V_HDLC_TRP); | ||
3067 | /* Enable FIFO, no interrupt*/ | ||
3068 | else | ||
3069 | HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00 | | ||
3070 | V_HDLC_TRP); | ||
2980 | HFC_outb(hc, A_SUBCH_CFG, 0); | 3071 | HFC_outb(hc, A_SUBCH_CFG, 0); |
2981 | HFC_outb(hc, A_IRQ_MSK, 0); | 3072 | HFC_outb(hc, A_IRQ_MSK, 0); |
2982 | HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); | 3073 | HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); |
2983 | HFC_wait(hc); | 3074 | HFC_wait(hc); |
2984 | } | 3075 | } |
2985 | if (hc->type != 1) { | 3076 | if (hc->ctype != HFC_TYPE_E1) { |
2986 | hc->hw.a_st_ctrl0[hc->chan[ch].port] |= | 3077 | hc->hw.a_st_ctrl0[hc->chan[ch].port] |= |
2987 | ((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN; | 3078 | ((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN; |
2988 | HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); | 3079 | HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); |
@@ -3003,7 +3094,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx, | |||
3003 | /* enable TX fifo */ | 3094 | /* enable TX fifo */ |
3004 | HFC_outb(hc, R_FIFO, ch<<1); | 3095 | HFC_outb(hc, R_FIFO, ch<<1); |
3005 | HFC_wait(hc); | 3096 | HFC_wait(hc); |
3006 | if (hc->type == 1 || hc->chan[ch].bch) { | 3097 | if (hc->ctype == HFC_TYPE_E1 || hc->chan[ch].bch) { |
3007 | /* E1 or B-channel */ | 3098 | /* E1 or B-channel */ |
3008 | HFC_outb(hc, A_CON_HDLC, flow_tx | 0x04); | 3099 | HFC_outb(hc, A_CON_HDLC, flow_tx | 0x04); |
3009 | HFC_outb(hc, A_SUBCH_CFG, 0); | 3100 | HFC_outb(hc, A_SUBCH_CFG, 0); |
@@ -3019,7 +3110,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx, | |||
3019 | HFC_outb(hc, R_FIFO, (ch<<1)|1); | 3110 | HFC_outb(hc, R_FIFO, (ch<<1)|1); |
3020 | HFC_wait(hc); | 3111 | HFC_wait(hc); |
3021 | HFC_outb(hc, A_CON_HDLC, flow_rx | 0x04); | 3112 | HFC_outb(hc, A_CON_HDLC, flow_rx | 0x04); |
3022 | if (hc->type == 1 || hc->chan[ch].bch) | 3113 | if (hc->ctype == HFC_TYPE_E1 || hc->chan[ch].bch) |
3023 | HFC_outb(hc, A_SUBCH_CFG, 0); /* full 8 bits */ | 3114 | HFC_outb(hc, A_SUBCH_CFG, 0); /* full 8 bits */ |
3024 | else | 3115 | else |
3025 | HFC_outb(hc, A_SUBCH_CFG, 2); /* 2 bits dchannel */ | 3116 | HFC_outb(hc, A_SUBCH_CFG, 2); /* 2 bits dchannel */ |
@@ -3028,7 +3119,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx, | |||
3028 | HFC_wait(hc); | 3119 | HFC_wait(hc); |
3029 | if (hc->chan[ch].bch) { | 3120 | if (hc->chan[ch].bch) { |
3030 | test_and_set_bit(FLG_HDLC, &hc->chan[ch].bch->Flags); | 3121 | test_and_set_bit(FLG_HDLC, &hc->chan[ch].bch->Flags); |
3031 | if (hc->type != 1) { | 3122 | if (hc->ctype != HFC_TYPE_E1) { |
3032 | hc->hw.a_st_ctrl0[hc->chan[ch].port] |= | 3123 | hc->hw.a_st_ctrl0[hc->chan[ch].port] |= |
3033 | ((ch&0x3) == 0) ? V_B1_EN : V_B2_EN; | 3124 | ((ch&0x3) == 0) ? V_B1_EN : V_B2_EN; |
3034 | HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); | 3125 | HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); |
@@ -3108,7 +3199,7 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd) | |||
3108 | case HW_RESET_REQ: | 3199 | case HW_RESET_REQ: |
3109 | /* start activation */ | 3200 | /* start activation */ |
3110 | spin_lock_irqsave(&hc->lock, flags); | 3201 | spin_lock_irqsave(&hc->lock, flags); |
3111 | if (hc->type == 1) { | 3202 | if (hc->ctype == HFC_TYPE_E1) { |
3112 | if (debug & DEBUG_HFCMULTI_MSG) | 3203 | if (debug & DEBUG_HFCMULTI_MSG) |
3113 | printk(KERN_DEBUG | 3204 | printk(KERN_DEBUG |
3114 | "%s: HW_RESET_REQ no BRI\n", | 3205 | "%s: HW_RESET_REQ no BRI\n", |
@@ -3129,7 +3220,7 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd) | |||
3129 | case HW_DEACT_REQ: | 3220 | case HW_DEACT_REQ: |
3130 | /* start deactivation */ | 3221 | /* start deactivation */ |
3131 | spin_lock_irqsave(&hc->lock, flags); | 3222 | spin_lock_irqsave(&hc->lock, flags); |
3132 | if (hc->type == 1) { | 3223 | if (hc->ctype == HFC_TYPE_E1) { |
3133 | if (debug & DEBUG_HFCMULTI_MSG) | 3224 | if (debug & DEBUG_HFCMULTI_MSG) |
3134 | printk(KERN_DEBUG | 3225 | printk(KERN_DEBUG |
3135 | "%s: HW_DEACT_REQ no BRI\n", | 3226 | "%s: HW_DEACT_REQ no BRI\n", |
@@ -3163,7 +3254,7 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd) | |||
3163 | break; | 3254 | break; |
3164 | case HW_POWERUP_REQ: | 3255 | case HW_POWERUP_REQ: |
3165 | spin_lock_irqsave(&hc->lock, flags); | 3256 | spin_lock_irqsave(&hc->lock, flags); |
3166 | if (hc->type == 1) { | 3257 | if (hc->ctype == HFC_TYPE_E1) { |
3167 | if (debug & DEBUG_HFCMULTI_MSG) | 3258 | if (debug & DEBUG_HFCMULTI_MSG) |
3168 | printk(KERN_DEBUG | 3259 | printk(KERN_DEBUG |
3169 | "%s: HW_POWERUP_REQ no BRI\n", | 3260 | "%s: HW_POWERUP_REQ no BRI\n", |
@@ -3240,7 +3331,7 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb) | |||
3240 | __func__, hc->chan[dch->slot].port, | 3331 | __func__, hc->chan[dch->slot].port, |
3241 | hc->ports-1); | 3332 | hc->ports-1); |
3242 | /* start activation */ | 3333 | /* start activation */ |
3243 | if (hc->type == 1) { | 3334 | if (hc->ctype == HFC_TYPE_E1) { |
3244 | ph_state_change(dch); | 3335 | ph_state_change(dch); |
3245 | if (debug & DEBUG_HFCMULTI_STATE) | 3336 | if (debug & DEBUG_HFCMULTI_STATE) |
3246 | printk(KERN_DEBUG | 3337 | printk(KERN_DEBUG |
@@ -3273,7 +3364,7 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb) | |||
3273 | __func__, hc->chan[dch->slot].port, | 3364 | __func__, hc->chan[dch->slot].port, |
3274 | hc->ports-1); | 3365 | hc->ports-1); |
3275 | /* start deactivation */ | 3366 | /* start deactivation */ |
3276 | if (hc->type == 1) { | 3367 | if (hc->ctype == HFC_TYPE_E1) { |
3277 | if (debug & DEBUG_HFCMULTI_MSG) | 3368 | if (debug & DEBUG_HFCMULTI_MSG) |
3278 | printk(KERN_DEBUG | 3369 | printk(KERN_DEBUG |
3279 | "%s: PH_DEACTIVATE no BRI\n", | 3370 | "%s: PH_DEACTIVATE no BRI\n", |
@@ -3493,6 +3584,8 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) | |||
3493 | features->hfc_id = hc->id; | 3584 | features->hfc_id = hc->id; |
3494 | if (test_bit(HFC_CHIP_DTMF, &hc->chip)) | 3585 | if (test_bit(HFC_CHIP_DTMF, &hc->chip)) |
3495 | features->hfc_dtmf = 1; | 3586 | features->hfc_dtmf = 1; |
3587 | if (test_bit(HFC_CHIP_CONF, &hc->chip)) | ||
3588 | features->hfc_conf = 1; | ||
3496 | features->hfc_loops = 0; | 3589 | features->hfc_loops = 0; |
3497 | if (test_bit(HFC_CHIP_B410P, &hc->chip)) { | 3590 | if (test_bit(HFC_CHIP_B410P, &hc->chip)) { |
3498 | features->hfc_echocanhw = 1; | 3591 | features->hfc_echocanhw = 1; |
@@ -3630,7 +3723,7 @@ ph_state_change(struct dchannel *dch) | |||
3630 | hc = dch->hw; | 3723 | hc = dch->hw; |
3631 | ch = dch->slot; | 3724 | ch = dch->slot; |
3632 | 3725 | ||
3633 | if (hc->type == 1) { | 3726 | if (hc->ctype == HFC_TYPE_E1) { |
3634 | if (dch->dev.D.protocol == ISDN_P_TE_E1) { | 3727 | if (dch->dev.D.protocol == ISDN_P_TE_E1) { |
3635 | if (debug & DEBUG_HFCMULTI_STATE) | 3728 | if (debug & DEBUG_HFCMULTI_STATE) |
3636 | printk(KERN_DEBUG | 3729 | printk(KERN_DEBUG |
@@ -3755,7 +3848,7 @@ hfcmulti_initmode(struct dchannel *dch) | |||
3755 | if (debug & DEBUG_HFCMULTI_INIT) | 3848 | if (debug & DEBUG_HFCMULTI_INIT) |
3756 | printk(KERN_DEBUG "%s: entered\n", __func__); | 3849 | printk(KERN_DEBUG "%s: entered\n", __func__); |
3757 | 3850 | ||
3758 | if (hc->type == 1) { | 3851 | if (hc->ctype == HFC_TYPE_E1) { |
3759 | hc->chan[hc->dslot].slot_tx = -1; | 3852 | hc->chan[hc->dslot].slot_tx = -1; |
3760 | hc->chan[hc->dslot].slot_rx = -1; | 3853 | hc->chan[hc->dslot].slot_rx = -1; |
3761 | hc->chan[hc->dslot].conf = -1; | 3854 | hc->chan[hc->dslot].conf = -1; |
@@ -3904,6 +3997,11 @@ hfcmulti_initmode(struct dchannel *dch) | |||
3904 | } | 3997 | } |
3905 | if (!test_bit(HFC_CFG_NONCAP_TX, &hc->chan[i].cfg)) | 3998 | if (!test_bit(HFC_CFG_NONCAP_TX, &hc->chan[i].cfg)) |
3906 | hc->hw.a_st_ctrl0[pt] |= V_TX_LI; | 3999 | hc->hw.a_st_ctrl0[pt] |= V_TX_LI; |
4000 | if (hc->ctype == HFC_TYPE_XHFC) { | ||
4001 | hc->hw.a_st_ctrl0[pt] |= 0x40 /* V_ST_PU_CTRL */; | ||
4002 | HFC_outb(hc, 0x35 /* A_ST_CTRL3 */, | ||
4003 | 0x7c << 1 /* V_ST_PULSE */); | ||
4004 | } | ||
3907 | /* line setup */ | 4005 | /* line setup */ |
3908 | HFC_outb(hc, A_ST_CTRL0, hc->hw.a_st_ctrl0[pt]); | 4006 | HFC_outb(hc, A_ST_CTRL0, hc->hw.a_st_ctrl0[pt]); |
3909 | /* disable E-channel */ | 4007 | /* disable E-channel */ |
@@ -3990,7 +4088,7 @@ open_bchannel(struct hfc_multi *hc, struct dchannel *dch, | |||
3990 | return -EINVAL; | 4088 | return -EINVAL; |
3991 | if (rq->protocol == ISDN_P_NONE) | 4089 | if (rq->protocol == ISDN_P_NONE) |
3992 | return -EINVAL; | 4090 | return -EINVAL; |
3993 | if (hc->type == 1) | 4091 | if (hc->ctype == HFC_TYPE_E1) |
3994 | ch = rq->adr.channel; | 4092 | ch = rq->adr.channel; |
3995 | else | 4093 | else |
3996 | ch = (rq->adr.channel - 1) + (dch->slot - 2); | 4094 | ch = (rq->adr.channel - 1) + (dch->slot - 2); |
@@ -4081,7 +4179,7 @@ hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg) | |||
4081 | switch (rq->protocol) { | 4179 | switch (rq->protocol) { |
4082 | case ISDN_P_TE_S0: | 4180 | case ISDN_P_TE_S0: |
4083 | case ISDN_P_NT_S0: | 4181 | case ISDN_P_NT_S0: |
4084 | if (hc->type == 1) { | 4182 | if (hc->ctype == HFC_TYPE_E1) { |
4085 | err = -EINVAL; | 4183 | err = -EINVAL; |
4086 | break; | 4184 | break; |
4087 | } | 4185 | } |
@@ -4089,7 +4187,7 @@ hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg) | |||
4089 | break; | 4187 | break; |
4090 | case ISDN_P_TE_E1: | 4188 | case ISDN_P_TE_E1: |
4091 | case ISDN_P_NT_E1: | 4189 | case ISDN_P_NT_E1: |
4092 | if (hc->type != 1) { | 4190 | if (hc->ctype != HFC_TYPE_E1) { |
4093 | err = -EINVAL; | 4191 | err = -EINVAL; |
4094 | break; | 4192 | break; |
4095 | } | 4193 | } |
@@ -4156,13 +4254,13 @@ init_card(struct hfc_multi *hc) | |||
4156 | disable_hwirq(hc); | 4254 | disable_hwirq(hc); |
4157 | spin_unlock_irqrestore(&hc->lock, flags); | 4255 | spin_unlock_irqrestore(&hc->lock, flags); |
4158 | 4256 | ||
4159 | if (request_irq(hc->pci_dev->irq, hfcmulti_interrupt, IRQF_SHARED, | 4257 | if (request_irq(hc->irq, hfcmulti_interrupt, IRQF_SHARED, |
4160 | "HFC-multi", hc)) { | 4258 | "HFC-multi", hc)) { |
4161 | printk(KERN_WARNING "mISDN: Could not get interrupt %d.\n", | 4259 | printk(KERN_WARNING "mISDN: Could not get interrupt %d.\n", |
4162 | hc->pci_dev->irq); | 4260 | hc->irq); |
4261 | hc->irq = 0; | ||
4163 | return -EIO; | 4262 | return -EIO; |
4164 | } | 4263 | } |
4165 | hc->irq = hc->pci_dev->irq; | ||
4166 | 4264 | ||
4167 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { | 4265 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { |
4168 | spin_lock_irqsave(&plx_lock, plx_flags); | 4266 | spin_lock_irqsave(&plx_lock, plx_flags); |
@@ -4269,6 +4367,10 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev, | |||
4269 | hc->ledstate = 0xAFFEAFFE; | 4367 | hc->ledstate = 0xAFFEAFFE; |
4270 | hc->opticalsupport = m->opticalsupport; | 4368 | hc->opticalsupport = m->opticalsupport; |
4271 | 4369 | ||
4370 | hc->pci_iobase = 0; | ||
4371 | hc->pci_membase = NULL; | ||
4372 | hc->plx_membase = NULL; | ||
4373 | |||
4272 | /* set memory access methods */ | 4374 | /* set memory access methods */ |
4273 | if (m->io_mode) /* use mode from card config */ | 4375 | if (m->io_mode) /* use mode from card config */ |
4274 | hc->io_mode = m->io_mode; | 4376 | hc->io_mode = m->io_mode; |
@@ -4276,44 +4378,12 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev, | |||
4276 | case HFC_IO_MODE_PLXSD: | 4378 | case HFC_IO_MODE_PLXSD: |
4277 | test_and_set_bit(HFC_CHIP_PLXSD, &hc->chip); | 4379 | test_and_set_bit(HFC_CHIP_PLXSD, &hc->chip); |
4278 | hc->slots = 128; /* required */ | 4380 | hc->slots = 128; /* required */ |
4279 | /* fall through */ | ||
4280 | case HFC_IO_MODE_PCIMEM: | ||
4281 | hc->HFC_outb = HFC_outb_pcimem; | 4381 | hc->HFC_outb = HFC_outb_pcimem; |
4282 | hc->HFC_inb = HFC_inb_pcimem; | 4382 | hc->HFC_inb = HFC_inb_pcimem; |
4283 | hc->HFC_inw = HFC_inw_pcimem; | 4383 | hc->HFC_inw = HFC_inw_pcimem; |
4284 | hc->HFC_wait = HFC_wait_pcimem; | 4384 | hc->HFC_wait = HFC_wait_pcimem; |
4285 | hc->read_fifo = read_fifo_pcimem; | 4385 | hc->read_fifo = read_fifo_pcimem; |
4286 | hc->write_fifo = write_fifo_pcimem; | 4386 | hc->write_fifo = write_fifo_pcimem; |
4287 | break; | ||
4288 | case HFC_IO_MODE_REGIO: | ||
4289 | hc->HFC_outb = HFC_outb_regio; | ||
4290 | hc->HFC_inb = HFC_inb_regio; | ||
4291 | hc->HFC_inw = HFC_inw_regio; | ||
4292 | hc->HFC_wait = HFC_wait_regio; | ||
4293 | hc->read_fifo = read_fifo_regio; | ||
4294 | hc->write_fifo = write_fifo_regio; | ||
4295 | break; | ||
4296 | default: | ||
4297 | printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n"); | ||
4298 | pci_disable_device(hc->pci_dev); | ||
4299 | return -EIO; | ||
4300 | } | ||
4301 | hc->HFC_outb_nodebug = hc->HFC_outb; | ||
4302 | hc->HFC_inb_nodebug = hc->HFC_inb; | ||
4303 | hc->HFC_inw_nodebug = hc->HFC_inw; | ||
4304 | hc->HFC_wait_nodebug = hc->HFC_wait; | ||
4305 | #ifdef HFC_REGISTER_DEBUG | ||
4306 | hc->HFC_outb = HFC_outb_debug; | ||
4307 | hc->HFC_inb = HFC_inb_debug; | ||
4308 | hc->HFC_inw = HFC_inw_debug; | ||
4309 | hc->HFC_wait = HFC_wait_debug; | ||
4310 | #endif | ||
4311 | hc->pci_iobase = 0; | ||
4312 | hc->pci_membase = NULL; | ||
4313 | hc->plx_membase = NULL; | ||
4314 | |||
4315 | switch (hc->io_mode) { | ||
4316 | case HFC_IO_MODE_PLXSD: | ||
4317 | hc->plx_origmembase = hc->pci_dev->resource[0].start; | 4387 | hc->plx_origmembase = hc->pci_dev->resource[0].start; |
4318 | /* MEMBASE 1 is PLX PCI Bridge */ | 4388 | /* MEMBASE 1 is PLX PCI Bridge */ |
4319 | 4389 | ||
@@ -4361,6 +4431,12 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev, | |||
4361 | pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO); | 4431 | pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO); |
4362 | break; | 4432 | break; |
4363 | case HFC_IO_MODE_PCIMEM: | 4433 | case HFC_IO_MODE_PCIMEM: |
4434 | hc->HFC_outb = HFC_outb_pcimem; | ||
4435 | hc->HFC_inb = HFC_inb_pcimem; | ||
4436 | hc->HFC_inw = HFC_inw_pcimem; | ||
4437 | hc->HFC_wait = HFC_wait_pcimem; | ||
4438 | hc->read_fifo = read_fifo_pcimem; | ||
4439 | hc->write_fifo = write_fifo_pcimem; | ||
4364 | hc->pci_origmembase = hc->pci_dev->resource[1].start; | 4440 | hc->pci_origmembase = hc->pci_dev->resource[1].start; |
4365 | if (!hc->pci_origmembase) { | 4441 | if (!hc->pci_origmembase) { |
4366 | printk(KERN_WARNING | 4442 | printk(KERN_WARNING |
@@ -4377,12 +4453,18 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev, | |||
4377 | pci_disable_device(hc->pci_dev); | 4453 | pci_disable_device(hc->pci_dev); |
4378 | return -EIO; | 4454 | return -EIO; |
4379 | } | 4455 | } |
4380 | printk(KERN_INFO "card %d: defined at MEMBASE %#lx (%#lx) IRQ %d " | 4456 | printk(KERN_INFO "card %d: defined at MEMBASE %#lx (%#lx) IRQ " |
4381 | "HZ %d leds-type %d\n", hc->id, (u_long)hc->pci_membase, | 4457 | "%d HZ %d leds-type %d\n", hc->id, (u_long)hc->pci_membase, |
4382 | hc->pci_origmembase, hc->pci_dev->irq, HZ, hc->leds); | 4458 | hc->pci_origmembase, hc->pci_dev->irq, HZ, hc->leds); |
4383 | pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO); | 4459 | pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO); |
4384 | break; | 4460 | break; |
4385 | case HFC_IO_MODE_REGIO: | 4461 | case HFC_IO_MODE_REGIO: |
4462 | hc->HFC_outb = HFC_outb_regio; | ||
4463 | hc->HFC_inb = HFC_inb_regio; | ||
4464 | hc->HFC_inw = HFC_inw_regio; | ||
4465 | hc->HFC_wait = HFC_wait_regio; | ||
4466 | hc->read_fifo = read_fifo_regio; | ||
4467 | hc->write_fifo = write_fifo_regio; | ||
4386 | hc->pci_iobase = (u_int) hc->pci_dev->resource[0].start; | 4468 | hc->pci_iobase = (u_int) hc->pci_dev->resource[0].start; |
4387 | if (!hc->pci_iobase) { | 4469 | if (!hc->pci_iobase) { |
4388 | printk(KERN_WARNING | 4470 | printk(KERN_WARNING |
@@ -4464,7 +4546,7 @@ release_port(struct hfc_multi *hc, struct dchannel *dch) | |||
4464 | dch->timer.function = NULL; | 4546 | dch->timer.function = NULL; |
4465 | } | 4547 | } |
4466 | 4548 | ||
4467 | if (hc->type == 1) { /* E1 */ | 4549 | if (hc->ctype == HFC_TYPE_E1) { /* E1 */ |
4468 | /* remove sync */ | 4550 | /* remove sync */ |
4469 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { | 4551 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { |
4470 | hc->syncronized = 0; | 4552 | hc->syncronized = 0; |
@@ -4863,9 +4945,15 @@ init_multi_port(struct hfc_multi *hc, int pt) | |||
4863 | test_and_set_bit(HFC_CFG_DIS_ECHANNEL, | 4945 | test_and_set_bit(HFC_CFG_DIS_ECHANNEL, |
4864 | &hc->chan[i + 2].cfg); | 4946 | &hc->chan[i + 2].cfg); |
4865 | } | 4947 | } |
4866 | snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-%ds.%d-%d", | 4948 | if (hc->ctype == HFC_TYPE_XHFC) { |
4867 | hc->type, HFC_cnt + 1, pt + 1); | 4949 | snprintf(name, MISDN_MAX_IDLEN - 1, "xhfc.%d-%d", |
4868 | ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name); | 4950 | HFC_cnt + 1, pt + 1); |
4951 | ret = mISDN_register_device(&dch->dev, NULL, name); | ||
4952 | } else { | ||
4953 | snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-%ds.%d-%d", | ||
4954 | hc->ctype, HFC_cnt + 1, pt + 1); | ||
4955 | ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name); | ||
4956 | } | ||
4869 | if (ret) | 4957 | if (ret) |
4870 | goto free_chan; | 4958 | goto free_chan; |
4871 | hc->created[pt] = 1; | 4959 | hc->created[pt] = 1; |
@@ -4876,9 +4964,9 @@ free_chan: | |||
4876 | } | 4964 | } |
4877 | 4965 | ||
4878 | static int | 4966 | static int |
4879 | hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent) | 4967 | hfcmulti_init(struct hm_map *m, struct pci_dev *pdev, |
4968 | const struct pci_device_id *ent) | ||
4880 | { | 4969 | { |
4881 | struct hm_map *m = (struct hm_map *)ent->driver_data; | ||
4882 | int ret_err = 0; | 4970 | int ret_err = 0; |
4883 | int pt; | 4971 | int pt; |
4884 | struct hfc_multi *hc; | 4972 | struct hfc_multi *hc; |
@@ -4913,16 +5001,18 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
4913 | } | 5001 | } |
4914 | spin_lock_init(&hc->lock); | 5002 | spin_lock_init(&hc->lock); |
4915 | hc->mtyp = m; | 5003 | hc->mtyp = m; |
4916 | hc->type = m->type; | 5004 | hc->ctype = m->type; |
4917 | hc->ports = m->ports; | 5005 | hc->ports = m->ports; |
4918 | hc->id = HFC_cnt; | 5006 | hc->id = HFC_cnt; |
4919 | hc->pcm = pcm[HFC_cnt]; | 5007 | hc->pcm = pcm[HFC_cnt]; |
4920 | hc->io_mode = iomode[HFC_cnt]; | 5008 | hc->io_mode = iomode[HFC_cnt]; |
4921 | if (dslot[HFC_cnt] < 0 && hc->type == 1) { | 5009 | if (dslot[HFC_cnt] < 0 && hc->ctype == HFC_TYPE_E1) { |
4922 | hc->dslot = 0; | 5010 | hc->dslot = 0; |
4923 | printk(KERN_INFO "HFC-E1 card has disabled D-channel, but " | 5011 | printk(KERN_INFO "HFC-E1 card has disabled D-channel, but " |
4924 | "31 B-channels\n"); | 5012 | "31 B-channels\n"); |
4925 | } if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32 && hc->type == 1) { | 5013 | } |
5014 | if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32 | ||
5015 | && hc->ctype == HFC_TYPE_E1) { | ||
4926 | hc->dslot = dslot[HFC_cnt]; | 5016 | hc->dslot = dslot[HFC_cnt]; |
4927 | printk(KERN_INFO "HFC-E1 card has alternating D-channel on " | 5017 | printk(KERN_INFO "HFC-E1 card has alternating D-channel on " |
4928 | "time slot %d\n", dslot[HFC_cnt]); | 5018 | "time slot %d\n", dslot[HFC_cnt]); |
@@ -4944,8 +5034,11 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
4944 | for (i = 0; i < (poll >> 1); i++) | 5034 | for (i = 0; i < (poll >> 1); i++) |
4945 | hc->silence_data[i] = hc->silence; | 5035 | hc->silence_data[i] = hc->silence; |
4946 | 5036 | ||
4947 | if (!(type[HFC_cnt] & 0x200)) | 5037 | if (hc->ctype != HFC_TYPE_XHFC) { |
4948 | test_and_set_bit(HFC_CHIP_DTMF, &hc->chip); | 5038 | if (!(type[HFC_cnt] & 0x200)) |
5039 | test_and_set_bit(HFC_CHIP_DTMF, &hc->chip); | ||
5040 | test_and_set_bit(HFC_CHIP_CONF, &hc->chip); | ||
5041 | } | ||
4949 | 5042 | ||
4950 | if (type[HFC_cnt] & 0x800) | 5043 | if (type[HFC_cnt] & 0x800) |
4951 | test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip); | 5044 | test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip); |
@@ -4969,8 +5062,18 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
4969 | printk(KERN_NOTICE "Watchdog enabled\n"); | 5062 | printk(KERN_NOTICE "Watchdog enabled\n"); |
4970 | } | 5063 | } |
4971 | 5064 | ||
4972 | /* setup pci, hc->slots may change due to PLXSD */ | 5065 | if (pdev && ent) |
4973 | ret_err = setup_pci(hc, pdev, ent); | 5066 | /* setup pci, hc->slots may change due to PLXSD */ |
5067 | ret_err = setup_pci(hc, pdev, ent); | ||
5068 | else | ||
5069 | #ifdef CONFIG_MISDN_HFCMULTI_8xx | ||
5070 | ret_err = setup_embedded(hc, m); | ||
5071 | #else | ||
5072 | { | ||
5073 | printk(KERN_WARNING "Embedded IO Mode not selected\n"); | ||
5074 | ret_err = -EIO; | ||
5075 | } | ||
5076 | #endif | ||
4974 | if (ret_err) { | 5077 | if (ret_err) { |
4975 | if (hc == syncmaster) | 5078 | if (hc == syncmaster) |
4976 | syncmaster = NULL; | 5079 | syncmaster = NULL; |
@@ -4978,7 +5081,17 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
4978 | return ret_err; | 5081 | return ret_err; |
4979 | } | 5082 | } |
4980 | 5083 | ||
4981 | /* crate channels */ | 5084 | hc->HFC_outb_nodebug = hc->HFC_outb; |
5085 | hc->HFC_inb_nodebug = hc->HFC_inb; | ||
5086 | hc->HFC_inw_nodebug = hc->HFC_inw; | ||
5087 | hc->HFC_wait_nodebug = hc->HFC_wait; | ||
5088 | #ifdef HFC_REGISTER_DEBUG | ||
5089 | hc->HFC_outb = HFC_outb_debug; | ||
5090 | hc->HFC_inb = HFC_inb_debug; | ||
5091 | hc->HFC_inw = HFC_inw_debug; | ||
5092 | hc->HFC_wait = HFC_wait_debug; | ||
5093 | #endif | ||
5094 | /* create channels */ | ||
4982 | for (pt = 0; pt < hc->ports; pt++) { | 5095 | for (pt = 0; pt < hc->ports; pt++) { |
4983 | if (Port_cnt >= MAX_PORTS) { | 5096 | if (Port_cnt >= MAX_PORTS) { |
4984 | printk(KERN_ERR "too many ports (max=%d).\n", | 5097 | printk(KERN_ERR "too many ports (max=%d).\n", |
@@ -4986,7 +5099,7 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
4986 | ret_err = -EINVAL; | 5099 | ret_err = -EINVAL; |
4987 | goto free_card; | 5100 | goto free_card; |
4988 | } | 5101 | } |
4989 | if (hc->type == 1) | 5102 | if (hc->ctype == HFC_TYPE_E1) |
4990 | ret_err = init_e1_port(hc, m); | 5103 | ret_err = init_e1_port(hc, m); |
4991 | else | 5104 | else |
4992 | ret_err = init_multi_port(hc, pt); | 5105 | ret_err = init_multi_port(hc, pt); |
@@ -5070,6 +5183,7 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
5070 | hc->iclock = mISDN_register_clock("HFCMulti", 0, clockctl, hc); | 5183 | hc->iclock = mISDN_register_clock("HFCMulti", 0, clockctl, hc); |
5071 | 5184 | ||
5072 | /* initialize hardware */ | 5185 | /* initialize hardware */ |
5186 | hc->irq = (m->irq) ? : hc->pci_dev->irq; | ||
5073 | ret_err = init_card(hc); | 5187 | ret_err = init_card(hc); |
5074 | if (ret_err) { | 5188 | if (ret_err) { |
5075 | printk(KERN_ERR "init card returns %d\n", ret_err); | 5189 | printk(KERN_ERR "init card returns %d\n", ret_err); |
@@ -5120,45 +5234,47 @@ static void __devexit hfc_remove_pci(struct pci_dev *pdev) | |||
5120 | #define VENDOR_PRIM "PrimuX" | 5234 | #define VENDOR_PRIM "PrimuX" |
5121 | 5235 | ||
5122 | static const struct hm_map hfcm_map[] = { | 5236 | static const struct hm_map hfcm_map[] = { |
5123 | /*0*/ {VENDOR_BN, "HFC-1S Card (mini PCI)", 4, 1, 1, 3, 0, DIP_4S, 0}, | 5237 | /*0*/ {VENDOR_BN, "HFC-1S Card (mini PCI)", 4, 1, 1, 3, 0, DIP_4S, 0, 0}, |
5124 | /*1*/ {VENDOR_BN, "HFC-2S Card", 4, 2, 1, 3, 0, DIP_4S, 0}, | 5238 | /*1*/ {VENDOR_BN, "HFC-2S Card", 4, 2, 1, 3, 0, DIP_4S, 0, 0}, |
5125 | /*2*/ {VENDOR_BN, "HFC-2S Card (mini PCI)", 4, 2, 1, 3, 0, DIP_4S, 0}, | 5239 | /*2*/ {VENDOR_BN, "HFC-2S Card (mini PCI)", 4, 2, 1, 3, 0, DIP_4S, 0, 0}, |
5126 | /*3*/ {VENDOR_BN, "HFC-4S Card", 4, 4, 1, 2, 0, DIP_4S, 0}, | 5240 | /*3*/ {VENDOR_BN, "HFC-4S Card", 4, 4, 1, 2, 0, DIP_4S, 0, 0}, |
5127 | /*4*/ {VENDOR_BN, "HFC-4S Card (mini PCI)", 4, 4, 1, 2, 0, 0, 0}, | 5241 | /*4*/ {VENDOR_BN, "HFC-4S Card (mini PCI)", 4, 4, 1, 2, 0, 0, 0, 0}, |
5128 | /*5*/ {VENDOR_CCD, "HFC-4S Eval (old)", 4, 4, 0, 0, 0, 0, 0}, | 5242 | /*5*/ {VENDOR_CCD, "HFC-4S Eval (old)", 4, 4, 0, 0, 0, 0, 0, 0}, |
5129 | /*6*/ {VENDOR_CCD, "HFC-4S IOB4ST", 4, 4, 1, 2, 0, DIP_4S, 0}, | 5243 | /*6*/ {VENDOR_CCD, "HFC-4S IOB4ST", 4, 4, 1, 2, 0, DIP_4S, 0, 0}, |
5130 | /*7*/ {VENDOR_CCD, "HFC-4S", 4, 4, 1, 2, 0, 0, 0}, | 5244 | /*7*/ {VENDOR_CCD, "HFC-4S", 4, 4, 1, 2, 0, 0, 0, 0}, |
5131 | /*8*/ {VENDOR_DIG, "HFC-4S Card", 4, 4, 0, 2, 0, 0, HFC_IO_MODE_REGIO}, | 5245 | /*8*/ {VENDOR_DIG, "HFC-4S Card", 4, 4, 0, 2, 0, 0, HFC_IO_MODE_REGIO, 0}, |
5132 | /*9*/ {VENDOR_CCD, "HFC-4S Swyx 4xS0 SX2 QuadBri", 4, 4, 1, 2, 0, 0, 0}, | 5246 | /*9*/ {VENDOR_CCD, "HFC-4S Swyx 4xS0 SX2 QuadBri", 4, 4, 1, 2, 0, 0, 0, 0}, |
5133 | /*10*/ {VENDOR_JH, "HFC-4S (junghanns 2.0)", 4, 4, 1, 2, 0, 0, 0}, | 5247 | /*10*/ {VENDOR_JH, "HFC-4S (junghanns 2.0)", 4, 4, 1, 2, 0, 0, 0, 0}, |
5134 | /*11*/ {VENDOR_PRIM, "HFC-2S Primux Card", 4, 2, 0, 0, 0, 0, 0}, | 5248 | /*11*/ {VENDOR_PRIM, "HFC-2S Primux Card", 4, 2, 0, 0, 0, 0, 0, 0}, |
5135 | 5249 | ||
5136 | /*12*/ {VENDOR_BN, "HFC-8S Card", 8, 8, 1, 0, 0, 0, 0}, | 5250 | /*12*/ {VENDOR_BN, "HFC-8S Card", 8, 8, 1, 0, 0, 0, 0, 0}, |
5137 | /*13*/ {VENDOR_BN, "HFC-8S Card (+)", 8, 8, 1, 8, 0, DIP_8S, | 5251 | /*13*/ {VENDOR_BN, "HFC-8S Card (+)", 8, 8, 1, 8, 0, DIP_8S, |
5138 | HFC_IO_MODE_REGIO}, | 5252 | HFC_IO_MODE_REGIO, 0}, |
5139 | /*14*/ {VENDOR_CCD, "HFC-8S Eval (old)", 8, 8, 0, 0, 0, 0, 0}, | 5253 | /*14*/ {VENDOR_CCD, "HFC-8S Eval (old)", 8, 8, 0, 0, 0, 0, 0, 0}, |
5140 | /*15*/ {VENDOR_CCD, "HFC-8S IOB4ST Recording", 8, 8, 1, 0, 0, 0, 0}, | 5254 | /*15*/ {VENDOR_CCD, "HFC-8S IOB4ST Recording", 8, 8, 1, 0, 0, 0, 0, 0}, |
5141 | 5255 | ||
5142 | /*16*/ {VENDOR_CCD, "HFC-8S IOB8ST", 8, 8, 1, 0, 0, 0, 0}, | 5256 | /*16*/ {VENDOR_CCD, "HFC-8S IOB8ST", 8, 8, 1, 0, 0, 0, 0, 0}, |
5143 | /*17*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0}, | 5257 | /*17*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0}, |
5144 | /*18*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0}, | 5258 | /*18*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0}, |
5145 | 5259 | ||
5146 | /*19*/ {VENDOR_BN, "HFC-E1 Card", 1, 1, 0, 1, 0, DIP_E1, 0}, | 5260 | /*19*/ {VENDOR_BN, "HFC-E1 Card", 1, 1, 0, 1, 0, DIP_E1, 0, 0}, |
5147 | /*20*/ {VENDOR_BN, "HFC-E1 Card (mini PCI)", 1, 1, 0, 1, 0, 0, 0}, | 5261 | /*20*/ {VENDOR_BN, "HFC-E1 Card (mini PCI)", 1, 1, 0, 1, 0, 0, 0, 0}, |
5148 | /*21*/ {VENDOR_BN, "HFC-E1+ Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0}, | 5262 | /*21*/ {VENDOR_BN, "HFC-E1+ Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0}, |
5149 | /*22*/ {VENDOR_BN, "HFC-E1 Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0}, | 5263 | /*22*/ {VENDOR_BN, "HFC-E1 Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0}, |
5150 | 5264 | ||
5151 | /*23*/ {VENDOR_CCD, "HFC-E1 Eval (old)", 1, 1, 0, 0, 0, 0, 0}, | 5265 | /*23*/ {VENDOR_CCD, "HFC-E1 Eval (old)", 1, 1, 0, 0, 0, 0, 0, 0}, |
5152 | /*24*/ {VENDOR_CCD, "HFC-E1 IOB1E1", 1, 1, 0, 1, 0, 0, 0}, | 5266 | /*24*/ {VENDOR_CCD, "HFC-E1 IOB1E1", 1, 1, 0, 1, 0, 0, 0, 0}, |
5153 | /*25*/ {VENDOR_CCD, "HFC-E1", 1, 1, 0, 1, 0, 0, 0}, | 5267 | /*25*/ {VENDOR_CCD, "HFC-E1", 1, 1, 0, 1, 0, 0, 0, 0}, |
5154 | 5268 | ||
5155 | /*26*/ {VENDOR_CCD, "HFC-4S Speech Design", 4, 4, 0, 0, 0, 0, | 5269 | /*26*/ {VENDOR_CCD, "HFC-4S Speech Design", 4, 4, 0, 0, 0, 0, |
5156 | HFC_IO_MODE_PLXSD}, | 5270 | HFC_IO_MODE_PLXSD, 0}, |
5157 | /*27*/ {VENDOR_CCD, "HFC-E1 Speech Design", 1, 1, 0, 0, 0, 0, | 5271 | /*27*/ {VENDOR_CCD, "HFC-E1 Speech Design", 1, 1, 0, 0, 0, 0, |
5158 | HFC_IO_MODE_PLXSD}, | 5272 | HFC_IO_MODE_PLXSD, 0}, |
5159 | /*28*/ {VENDOR_CCD, "HFC-4S OpenVox", 4, 4, 1, 0, 0, 0, 0}, | 5273 | /*28*/ {VENDOR_CCD, "HFC-4S OpenVox", 4, 4, 1, 0, 0, 0, 0, 0}, |
5160 | /*29*/ {VENDOR_CCD, "HFC-2S OpenVox", 4, 2, 1, 0, 0, 0, 0}, | 5274 | /*29*/ {VENDOR_CCD, "HFC-2S OpenVox", 4, 2, 1, 0, 0, 0, 0, 0}, |
5161 | /*30*/ {VENDOR_CCD, "HFC-8S OpenVox", 8, 8, 1, 0, 0, 0, 0}, | 5275 | /*30*/ {VENDOR_CCD, "HFC-8S OpenVox", 8, 8, 1, 0, 0, 0, 0, 0}, |
5276 | /*31*/ {VENDOR_CCD, "XHFC-4S Speech Design", 5, 4, 0, 0, 0, 0, | ||
5277 | HFC_IO_MODE_EMBSD, XHFC_IRQ}, | ||
5162 | }; | 5278 | }; |
5163 | 5279 | ||
5164 | #undef H | 5280 | #undef H |
@@ -5265,7 +5381,7 @@ hfcmulti_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
5265 | "Please contact the driver maintainer for support.\n"); | 5381 | "Please contact the driver maintainer for support.\n"); |
5266 | return -ENODEV; | 5382 | return -ENODEV; |
5267 | } | 5383 | } |
5268 | ret = hfcmulti_init(pdev, ent); | 5384 | ret = hfcmulti_init(m, pdev, ent); |
5269 | if (ret) | 5385 | if (ret) |
5270 | return ret; | 5386 | return ret; |
5271 | HFC_cnt++; | 5387 | HFC_cnt++; |
@@ -5295,6 +5411,8 @@ static int __init | |||
5295 | HFCmulti_init(void) | 5411 | HFCmulti_init(void) |
5296 | { | 5412 | { |
5297 | int err; | 5413 | int err; |
5414 | int i, xhfc = 0; | ||
5415 | struct hm_map m; | ||
5298 | 5416 | ||
5299 | printk(KERN_INFO "mISDN: HFC-multi driver %s\n", HFC_MULTI_VERSION); | 5417 | printk(KERN_INFO "mISDN: HFC-multi driver %s\n", HFC_MULTI_VERSION); |
5300 | 5418 | ||
@@ -5342,11 +5460,43 @@ HFCmulti_init(void) | |||
5342 | if (!clock) | 5460 | if (!clock) |
5343 | clock = 1; | 5461 | clock = 1; |
5344 | 5462 | ||
5463 | /* Register the embedded devices. | ||
5464 | * This should be done before the PCI cards registration */ | ||
5465 | switch (hwid) { | ||
5466 | case HWID_MINIP4: | ||
5467 | xhfc = 1; | ||
5468 | m = hfcm_map[31]; | ||
5469 | break; | ||
5470 | case HWID_MINIP8: | ||
5471 | xhfc = 2; | ||
5472 | m = hfcm_map[31]; | ||
5473 | break; | ||
5474 | case HWID_MINIP16: | ||
5475 | xhfc = 4; | ||
5476 | m = hfcm_map[31]; | ||
5477 | break; | ||
5478 | default: | ||
5479 | xhfc = 0; | ||
5480 | } | ||
5481 | |||
5482 | for (i = 0; i < xhfc; ++i) { | ||
5483 | err = hfcmulti_init(&m, NULL, NULL); | ||
5484 | if (err) { | ||
5485 | printk(KERN_ERR "error registering embedded driver: " | ||
5486 | "%x\n", err); | ||
5487 | return -err; | ||
5488 | } | ||
5489 | HFC_cnt++; | ||
5490 | printk(KERN_INFO "%d devices registered\n", HFC_cnt); | ||
5491 | } | ||
5492 | |||
5493 | /* Register the PCI cards */ | ||
5345 | err = pci_register_driver(&hfcmultipci_driver); | 5494 | err = pci_register_driver(&hfcmultipci_driver); |
5346 | if (err < 0) { | 5495 | if (err < 0) { |
5347 | printk(KERN_ERR "error registering pci driver: %x\n", err); | 5496 | printk(KERN_ERR "error registering pci driver: %x\n", err); |
5348 | return err; | 5497 | return err; |
5349 | } | 5498 | } |
5499 | |||
5350 | return 0; | 5500 | return 0; |
5351 | } | 5501 | } |
5352 | 5502 | ||
diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c index d19b4f6d7d87..05866184ba23 100644 --- a/drivers/isdn/mISDN/dsp_cmx.c +++ b/drivers/isdn/mISDN/dsp_cmx.c | |||
@@ -947,6 +947,10 @@ conf_software: | |||
947 | if (current_conf >= 0) { | 947 | if (current_conf >= 0) { |
948 | join_members: | 948 | join_members: |
949 | list_for_each_entry(member, &conf->mlist, list) { | 949 | list_for_each_entry(member, &conf->mlist, list) { |
950 | /* if no conference engine on our chip, change to | ||
951 | * software */ | ||
952 | if (!member->dsp->features.hfc_conf) | ||
953 | goto conf_software; | ||
950 | /* in case of hdlc, change to software */ | 954 | /* in case of hdlc, change to software */ |
951 | if (member->dsp->hdlc) | 955 | if (member->dsp->hdlc) |
952 | goto conf_software; | 956 | goto conf_software; |
diff --git a/include/linux/mISDNdsp.h b/include/linux/mISDNdsp.h index 2c483d45f141..41d1eeb9b3bd 100644 --- a/include/linux/mISDNdsp.h +++ b/include/linux/mISDNdsp.h | |||
@@ -25,6 +25,7 @@ extern void mISDN_dsp_element_unregister(struct mISDN_dsp_element *elem); | |||
25 | struct dsp_features { | 25 | struct dsp_features { |
26 | int hfc_id; /* unique id to identify the chip (or -1) */ | 26 | int hfc_id; /* unique id to identify the chip (or -1) */ |
27 | int hfc_dtmf; /* set if HFCmulti card supports dtmf */ | 27 | int hfc_dtmf; /* set if HFCmulti card supports dtmf */ |
28 | int hfc_conf; /* set if HFCmulti card supports conferences */ | ||
28 | int hfc_loops; /* set if card supports tone loops */ | 29 | int hfc_loops; /* set if card supports tone loops */ |
29 | int hfc_echocanhw; /* set if card supports echocancelation*/ | 30 | int hfc_echocanhw; /* set if card supports echocancelation*/ |
30 | int pcm_id; /* unique id to identify the pcm bus (or -1) */ | 31 | int pcm_id; /* unique id to identify the pcm bus (or -1) */ |