aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/hardware/mISDN/hfcmulti.c
diff options
context:
space:
mode:
authorAndreas Eversberg <andreas@eversberg.eu>2008-08-02 16:51:52 -0400
committerKarsten Keil <kkeil@suse.de>2009-01-09 16:44:22 -0500
commit8dd2f36f317569665e454268a2677cfba3e848f1 (patch)
tree62f0d30aa090594648ed21cb9a863e4cc2b4f4fd /drivers/isdn/hardware/mISDN/hfcmulti.c
parent69e656cc16511719a89d83373c48172d3f39bc5f (diff)
mISDN: Add feature via MISDN_CTRL_FILL_EMPTY to fill fifo if empty
This prevents underrun of fifo when filled and in case of an underrun it prevents subsequent underruns due to jitter. Improve dsp, so buffers are kept filled with a certain delay, so moderate jitter will not cause underrun all the time -> the audio quality is highly improved. tones are not interrupted by gaps anymore, except when CPU is stalling or in high load. Signed-off-by: Andreas Eversberg <andreas@eversberg.eu> Signed-off-by: Karsten Keil <kkeil@suse.de>
Diffstat (limited to 'drivers/isdn/hardware/mISDN/hfcmulti.c')
-rw-r--r--drivers/isdn/hardware/mISDN/hfcmulti.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index ff5ec3cbeb77..3fc2e9d95341 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -180,7 +180,6 @@ static int nt_t1_count[] = { 3840, 1920, 960, 480, 240, 120, 60, 30 };
180#define CLKDEL_TE 0x0f /* CLKDEL in TE mode */ 180#define CLKDEL_TE 0x0f /* CLKDEL in TE mode */
181#define CLKDEL_NT 0x6c /* CLKDEL in NT mode 181#define CLKDEL_NT 0x6c /* CLKDEL in NT mode
182 (0x60 MUST be included!) */ 182 (0x60 MUST be included!) */
183static u_char silence = 0xff; /* silence by LAW */
184 183
185#define DIP_4S 0x1 /* DIP Switches for Beronet 1S/2S/4S cards */ 184#define DIP_4S 0x1 /* DIP Switches for Beronet 1S/2S/4S cards */
186#define DIP_8S 0x2 /* DIP Switches for Beronet 8S+ cards */ 185#define DIP_8S 0x2 /* DIP Switches for Beronet 8S+ cards */
@@ -1975,6 +1974,17 @@ next_frame:
1975 return; /* no data */ 1974 return; /* no data */
1976 } 1975 }
1977 1976
1977 /* "fill fifo if empty" feature */
1978 if (bch && test_bit(FLG_FILLEMPTY, &bch->Flags)
1979 && !test_bit(FLG_HDLC, &bch->Flags) && z2 == z1) {
1980 if (debug & DEBUG_HFCMULTI_FILL)
1981 printk(KERN_DEBUG "%s: buffer empty, so we have "
1982 "underrun\n", __func__);
1983 /* fill buffer, to prevent future underrun */
1984 hc->write_fifo(hc, hc->silence_data, poll >> 1);
1985 Zspace -= (poll >> 1);
1986 }
1987
1978 /* if audio data and connected slot */ 1988 /* if audio data and connected slot */
1979 if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) && (!*txpending) 1989 if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) && (!*txpending)
1980 && slot_tx >= 0) { 1990 && slot_tx >= 0) {
@@ -2011,7 +2021,6 @@ next_frame:
2011 __func__, hc->id + 1, ch, Zspace, z1, z2, ii-i, len-i, 2021 __func__, hc->id + 1, ch, Zspace, z1, z2, ii-i, len-i,
2012 temp ? "HDLC":"TRANS"); 2022 temp ? "HDLC":"TRANS");
2013 2023
2014
2015 /* Have to prep the audio data */ 2024 /* Have to prep the audio data */
2016 hc->write_fifo(hc, d, ii - i); 2025 hc->write_fifo(hc, d, ii - i);
2017 *idxp = ii; 2026 *idxp = ii;
@@ -2050,7 +2059,7 @@ next_frame:
2050 * no more data at all. this prevents sending an undefined value. 2059 * no more data at all. this prevents sending an undefined value.
2051 */ 2060 */
2052 if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags)) 2061 if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags))
2053 HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, silence); 2062 HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
2054} 2063}
2055 2064
2056 2065
@@ -2932,7 +2941,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
2932 HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); 2941 HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
2933 HFC_wait(hc); 2942 HFC_wait(hc);
2934 /* tx silence */ 2943 /* tx silence */
2935 HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, silence); 2944 HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
2936 HFC_outb(hc, R_SLOT, (((ch / 4) * 8) + 2945 HFC_outb(hc, R_SLOT, (((ch / 4) * 8) +
2937 ((ch % 4) * 4)) << 1); 2946 ((ch % 4) * 4)) << 1);
2938 HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1)); 2947 HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1));
@@ -2947,7 +2956,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
2947 HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); 2956 HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
2948 HFC_wait(hc); 2957 HFC_wait(hc);
2949 /* tx silence */ 2958 /* tx silence */
2950 HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, silence); 2959 HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
2951 /* enable RX fifo */ 2960 /* enable RX fifo */
2952 HFC_outb(hc, R_FIFO, (ch<<1)|1); 2961 HFC_outb(hc, R_FIFO, (ch<<1)|1);
2953 HFC_wait(hc); 2962 HFC_wait(hc);
@@ -3439,7 +3448,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
3439 switch (cq->op) { 3448 switch (cq->op) {
3440 case MISDN_CTRL_GETOP: 3449 case MISDN_CTRL_GETOP:
3441 cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP 3450 cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP
3442 | MISDN_CTRL_RX_OFF; 3451 | MISDN_CTRL_RX_OFF | MISDN_CTRL_FILL_EMPTY;
3443 break; 3452 break;
3444 case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */ 3453 case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */
3445 hc->chan[bch->slot].rx_off = !!cq->p1; 3454 hc->chan[bch->slot].rx_off = !!cq->p1;
@@ -3454,6 +3463,12 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
3454 printk(KERN_DEBUG "%s: RX_OFF request (nr=%d off=%d)\n", 3463 printk(KERN_DEBUG "%s: RX_OFF request (nr=%d off=%d)\n",
3455 __func__, bch->nr, hc->chan[bch->slot].rx_off); 3464 __func__, bch->nr, hc->chan[bch->slot].rx_off);
3456 break; 3465 break;
3466 case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */
3467 test_and_set_bit(FLG_FILLEMPTY, &bch->Flags);
3468 if (debug & DEBUG_HFCMULTI_MSG)
3469 printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d "
3470 "off=%d)\n", __func__, bch->nr, !!cq->p1);
3471 break;
3457 case MISDN_CTRL_HW_FEATURES: /* fill features structure */ 3472 case MISDN_CTRL_HW_FEATURES: /* fill features structure */
3458 if (debug & DEBUG_HFCMULTI_MSG) 3473 if (debug & DEBUG_HFCMULTI_MSG)
3459 printk(KERN_DEBUG "%s: HW_FEATURE request\n", 3474 printk(KERN_DEBUG "%s: HW_FEATURE request\n",
@@ -3970,6 +3985,7 @@ open_bchannel(struct hfc_multi *hc, struct dchannel *dch,
3970 } 3985 }
3971 if (test_and_set_bit(FLG_OPEN, &bch->Flags)) 3986 if (test_and_set_bit(FLG_OPEN, &bch->Flags))
3972 return -EBUSY; /* b-channel can be only open once */ 3987 return -EBUSY; /* b-channel can be only open once */
3988 test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
3973 bch->ch.protocol = rq->protocol; 3989 bch->ch.protocol = rq->protocol;
3974 hc->chan[ch].rx_off = 0; 3990 hc->chan[ch].rx_off = 0;
3975 rq->ch = &bch->ch; 3991 rq->ch = &bch->ch;
@@ -4806,6 +4822,7 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
4806 struct hfc_multi *hc; 4822 struct hfc_multi *hc;
4807 u_long flags; 4823 u_long flags;
4808 u_char dips = 0, pmj = 0; /* dip settings, port mode Jumpers */ 4824 u_char dips = 0, pmj = 0; /* dip settings, port mode Jumpers */
4825 int i;
4809 4826
4810 if (HFC_cnt >= MAX_CARDS) { 4827 if (HFC_cnt >= MAX_CARDS) {
4811 printk(KERN_ERR "too many cards (max=%d).\n", 4828 printk(KERN_ERR "too many cards (max=%d).\n",
@@ -4839,11 +4856,11 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
4839 hc->id = HFC_cnt; 4856 hc->id = HFC_cnt;
4840 hc->pcm = pcm[HFC_cnt]; 4857 hc->pcm = pcm[HFC_cnt];
4841 hc->io_mode = iomode[HFC_cnt]; 4858 hc->io_mode = iomode[HFC_cnt];
4842 if (dslot[HFC_cnt] < 0) { 4859 if (dslot[HFC_cnt] < 0 && hc->type == 1) {
4843 hc->dslot = 0; 4860 hc->dslot = 0;
4844 printk(KERN_INFO "HFC-E1 card has disabled D-channel, but " 4861 printk(KERN_INFO "HFC-E1 card has disabled D-channel, but "
4845 "31 B-channels\n"); 4862 "31 B-channels\n");
4846 } if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32) { 4863 } if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32 && hc->type == 1) {
4847 hc->dslot = dslot[HFC_cnt]; 4864 hc->dslot = dslot[HFC_cnt];
4848 printk(KERN_INFO "HFC-E1 card has alternating D-channel on " 4865 printk(KERN_INFO "HFC-E1 card has alternating D-channel on "
4849 "time slot %d\n", dslot[HFC_cnt]); 4866 "time slot %d\n", dslot[HFC_cnt]);
@@ -4854,9 +4871,17 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
4854 hc->masterclk = -1; 4871 hc->masterclk = -1;
4855 if (type[HFC_cnt] & 0x100) { 4872 if (type[HFC_cnt] & 0x100) {
4856 test_and_set_bit(HFC_CHIP_ULAW, &hc->chip); 4873 test_and_set_bit(HFC_CHIP_ULAW, &hc->chip);
4857 silence = 0xff; /* ulaw silence */ 4874 hc->silence = 0xff; /* ulaw silence */
4858 } else 4875 } else
4859 silence = 0x2a; /* alaw silence */ 4876 hc->silence = 0x2a; /* alaw silence */
4877 if ((poll >> 1) > sizeof(hc->silence_data)) {
4878 printk(KERN_ERR "HFCMULTI error: silence_data too small, "
4879 "please fix\n");
4880 return -EINVAL;
4881 }
4882 for (i = 0; i < (poll >> 1); i++)
4883 hc->silence_data[i] = hc->silence;
4884
4860 if (!(type[HFC_cnt] & 0x200)) 4885 if (!(type[HFC_cnt] & 0x200))
4861 test_and_set_bit(HFC_CHIP_DTMF, &hc->chip); 4886 test_and_set_bit(HFC_CHIP_DTMF, &hc->chip);
4862 4887