diff options
Diffstat (limited to 'drivers/isdn/hardware/mISDN/hfcmulti.c')
-rw-r--r-- | drivers/isdn/hardware/mISDN/hfcmulti.c | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c index 3fc2e9d95341..592db93105f9 100644 --- a/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/drivers/isdn/hardware/mISDN/hfcmulti.c | |||
@@ -133,6 +133,12 @@ | |||
133 | * Give the value of the clock control register (A_ST_CLK_DLY) | 133 | * Give the value of the clock control register (A_ST_CLK_DLY) |
134 | * of the S/T interfaces in TE mode. | 134 | * of the S/T interfaces in TE mode. |
135 | * This register is needed for the TBR3 certification, so don't change it. | 135 | * This register is needed for the TBR3 certification, so don't change it. |
136 | * | ||
137 | * clock: | ||
138 | * NOTE: only one clockdelay_te value must be given once | ||
139 | * Selects interface with clock source for mISDN and applications. | ||
140 | * Set to card number starting with 1. Set to -1 to disable. | ||
141 | * By default, the first card is used as clock source. | ||
136 | */ | 142 | */ |
137 | 143 | ||
138 | /* | 144 | /* |
@@ -190,12 +196,13 @@ static int nt_t1_count[] = { 3840, 1920, 960, 480, 240, 120, 60, 30 }; | |||
190 | */ | 196 | */ |
191 | 197 | ||
192 | static uint type[MAX_CARDS]; | 198 | static uint type[MAX_CARDS]; |
193 | static uint pcm[MAX_CARDS]; | 199 | static int pcm[MAX_CARDS]; |
194 | static uint dslot[MAX_CARDS]; | 200 | static int dslot[MAX_CARDS]; |
195 | static uint iomode[MAX_CARDS]; | 201 | static uint iomode[MAX_CARDS]; |
196 | static uint port[MAX_PORTS]; | 202 | static uint port[MAX_PORTS]; |
197 | static uint debug; | 203 | static uint debug; |
198 | static uint poll; | 204 | static uint poll; |
205 | static int clock; | ||
199 | static uint timer; | 206 | static uint timer; |
200 | static uint clockdelay_te = CLKDEL_TE; | 207 | static uint clockdelay_te = CLKDEL_TE; |
201 | static uint clockdelay_nt = CLKDEL_NT; | 208 | static uint clockdelay_nt = CLKDEL_NT; |
@@ -207,12 +214,13 @@ MODULE_LICENSE("GPL"); | |||
207 | MODULE_VERSION(HFC_MULTI_VERSION); | 214 | MODULE_VERSION(HFC_MULTI_VERSION); |
208 | module_param(debug, uint, S_IRUGO | S_IWUSR); | 215 | module_param(debug, uint, S_IRUGO | S_IWUSR); |
209 | module_param(poll, uint, S_IRUGO | S_IWUSR); | 216 | module_param(poll, uint, S_IRUGO | S_IWUSR); |
217 | module_param(clock, int, S_IRUGO | S_IWUSR); | ||
210 | module_param(timer, uint, S_IRUGO | S_IWUSR); | 218 | module_param(timer, uint, S_IRUGO | S_IWUSR); |
211 | module_param(clockdelay_te, uint, S_IRUGO | S_IWUSR); | 219 | module_param(clockdelay_te, uint, S_IRUGO | S_IWUSR); |
212 | module_param(clockdelay_nt, uint, S_IRUGO | S_IWUSR); | 220 | module_param(clockdelay_nt, uint, S_IRUGO | S_IWUSR); |
213 | module_param_array(type, uint, NULL, S_IRUGO | S_IWUSR); | 221 | module_param_array(type, uint, NULL, S_IRUGO | S_IWUSR); |
214 | module_param_array(pcm, uint, NULL, S_IRUGO | S_IWUSR); | 222 | module_param_array(pcm, int, NULL, S_IRUGO | S_IWUSR); |
215 | module_param_array(dslot, uint, NULL, S_IRUGO | S_IWUSR); | 223 | module_param_array(dslot, int, NULL, S_IRUGO | S_IWUSR); |
216 | module_param_array(iomode, uint, NULL, S_IRUGO | S_IWUSR); | 224 | module_param_array(iomode, uint, NULL, S_IRUGO | S_IWUSR); |
217 | module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR); | 225 | module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR); |
218 | 226 | ||
@@ -2629,6 +2637,7 @@ hfcmulti_interrupt(int intno, void *dev_id) | |||
2629 | iqcnt = 0; | 2637 | iqcnt = 0; |
2630 | } | 2638 | } |
2631 | #endif | 2639 | #endif |
2640 | |||
2632 | if (!r_irq_statech && | 2641 | if (!r_irq_statech && |
2633 | !(status & (V_DTMF_STA | V_LOST_STA | V_EXT_IRQSTA | | 2642 | !(status & (V_DTMF_STA | V_LOST_STA | V_EXT_IRQSTA | |
2634 | V_MISC_IRQSTA | V_FR_IRQSTA))) { | 2643 | V_MISC_IRQSTA | V_FR_IRQSTA))) { |
@@ -2683,11 +2692,13 @@ hfcmulti_interrupt(int intno, void *dev_id) | |||
2683 | plxsd_checksync(hc, 0); | 2692 | plxsd_checksync(hc, 0); |
2684 | } | 2693 | } |
2685 | } | 2694 | } |
2686 | if (r_irq_misc & V_TI_IRQ) | 2695 | if (r_irq_misc & V_TI_IRQ) { |
2696 | if (hc->iclock_on) | ||
2697 | mISDN_clock_update(hc->iclock, poll, NULL); | ||
2687 | handle_timer_irq(hc); | 2698 | handle_timer_irq(hc); |
2699 | } | ||
2688 | 2700 | ||
2689 | if (r_irq_misc & V_DTMF_IRQ) { | 2701 | if (r_irq_misc & V_DTMF_IRQ) { |
2690 | /* -> DTMF IRQ */ | ||
2691 | hfcmulti_dtmf(hc); | 2702 | hfcmulti_dtmf(hc); |
2692 | } | 2703 | } |
2693 | if (r_irq_misc & V_IRQ_PROC) { | 2704 | if (r_irq_misc & V_IRQ_PROC) { |
@@ -4075,6 +4086,15 @@ hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg) | |||
4075 | return err; | 4086 | return err; |
4076 | } | 4087 | } |
4077 | 4088 | ||
4089 | static int | ||
4090 | clockctl(void *priv, int enable) | ||
4091 | { | ||
4092 | struct hfc_multi *hc = priv; | ||
4093 | |||
4094 | hc->iclock_on = enable; | ||
4095 | return 0; | ||
4096 | } | ||
4097 | |||
4078 | /* | 4098 | /* |
4079 | * initialize the card | 4099 | * initialize the card |
4080 | */ | 4100 | */ |
@@ -4489,10 +4509,14 @@ release_card(struct hfc_multi *hc) | |||
4489 | printk(KERN_WARNING "%s: release card (%d) entered\n", | 4509 | printk(KERN_WARNING "%s: release card (%d) entered\n", |
4490 | __func__, hc->id); | 4510 | __func__, hc->id); |
4491 | 4511 | ||
4512 | /* unregister clock source */ | ||
4513 | if (hc->iclock) | ||
4514 | mISDN_unregister_clock(hc->iclock); | ||
4515 | |||
4516 | /* disable irq */ | ||
4492 | spin_lock_irqsave(&hc->lock, flags); | 4517 | spin_lock_irqsave(&hc->lock, flags); |
4493 | disable_hwirq(hc); | 4518 | disable_hwirq(hc); |
4494 | spin_unlock_irqrestore(&hc->lock, flags); | 4519 | spin_unlock_irqrestore(&hc->lock, flags); |
4495 | |||
4496 | udelay(1000); | 4520 | udelay(1000); |
4497 | 4521 | ||
4498 | /* dimm leds */ | 4522 | /* dimm leds */ |
@@ -5003,6 +5027,10 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
5003 | list_add_tail(&hc->list, &HFClist); | 5027 | list_add_tail(&hc->list, &HFClist); |
5004 | spin_unlock_irqrestore(&HFClock, flags); | 5028 | spin_unlock_irqrestore(&HFClock, flags); |
5005 | 5029 | ||
5030 | /* use as clock source */ | ||
5031 | if (clock == HFC_cnt + 1) | ||
5032 | hc->iclock = mISDN_register_clock("HFCMulti", 0, clockctl, hc); | ||
5033 | |||
5006 | /* initialize hardware */ | 5034 | /* initialize hardware */ |
5007 | ret_err = init_card(hc); | 5035 | ret_err = init_card(hc); |
5008 | if (ret_err) { | 5036 | if (ret_err) { |
@@ -5273,6 +5301,9 @@ HFCmulti_init(void) | |||
5273 | 5301 | ||
5274 | } | 5302 | } |
5275 | 5303 | ||
5304 | if (!clock) | ||
5305 | clock = 1; | ||
5306 | |||
5276 | err = pci_register_driver(&hfcmultipci_driver); | 5307 | err = pci_register_driver(&hfcmultipci_driver); |
5277 | if (err < 0) { | 5308 | if (err < 0) { |
5278 | printk(KERN_ERR "error registering pci driver: %x\n", err); | 5309 | printk(KERN_ERR "error registering pci driver: %x\n", err); |