aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/hardware/mISDN/hfcpci.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/hfcpci.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/hfcpci.c')
-rw-r--r--drivers/isdn/hardware/mISDN/hfcpci.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
index cd8302af40e..80c356e5dbe 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -751,6 +751,36 @@ hfcpci_fill_fifo(struct bchannel *bch)
751 /* fcnt contains available bytes in fifo */ 751 /* fcnt contains available bytes in fifo */
752 fcnt = B_FIFO_SIZE - fcnt; 752 fcnt = B_FIFO_SIZE - fcnt;
753 /* remaining bytes to send (bytes in fifo) */ 753 /* remaining bytes to send (bytes in fifo) */
754
755 /* "fill fifo if empty" feature */
756 if (test_bit(FLG_FILLEMPTY, &bch->Flags) && !fcnt) {
757 /* printk(KERN_DEBUG "%s: buffer empty, so we have "
758 "underrun\n", __func__); */
759 /* fill buffer, to prevent future underrun */
760 count = HFCPCI_FILLEMPTY;
761 new_z1 = le16_to_cpu(*z1t) + count;
762 /* new buffer Position */
763 if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL))
764 new_z1 -= B_FIFO_SIZE; /* buffer wrap */
765 dst = bdata + (le16_to_cpu(*z1t) - B_SUB_VAL);
766 maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(*z1t);
767 /* end of fifo */
768 if (bch->debug & DEBUG_HW_BFIFO)
769 printk(KERN_DEBUG "hfcpci_FFt fillempty "
770 "fcnt(%d) maxl(%d) nz1(%x) dst(%p)\n",
771 fcnt, maxlen, new_z1, dst);
772 fcnt += count;
773 if (maxlen > count)
774 maxlen = count; /* limit size */
775 memset(dst, 0x2a, maxlen); /* first copy */
776 count -= maxlen; /* remaining bytes */
777 if (count) {
778 dst = bdata; /* start of buffer */
779 memset(dst, 0x2a, count);
780 }
781 *z1t = cpu_to_le16(new_z1); /* now send data */
782 }
783
754next_t_frame: 784next_t_frame:
755 count = bch->tx_skb->len - bch->tx_idx; 785 count = bch->tx_skb->len - bch->tx_idx;
756 /* maximum fill shall be HFCPCI_BTRANS_MAX */ 786 /* maximum fill shall be HFCPCI_BTRANS_MAX */
@@ -1481,11 +1511,17 @@ deactivate_bchannel(struct bchannel *bch)
1481static int 1511static int
1482channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) 1512channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
1483{ 1513{
1484 int ret = 0; 1514 int ret = 0;
1485 1515
1486 switch (cq->op) { 1516 switch (cq->op) {
1487 case MISDN_CTRL_GETOP: 1517 case MISDN_CTRL_GETOP:
1488 cq->op = 0; 1518 cq->op = MISDN_CTRL_FILL_EMPTY;
1519 break;
1520 case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */
1521 test_and_set_bit(FLG_FILLEMPTY, &bch->Flags);
1522 if (debug & DEBUG_HW_OPEN)
1523 printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d "
1524 "off=%d)\n", __func__, bch->nr, !!cq->p1);
1489 break; 1525 break;
1490 default: 1526 default:
1491 printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op); 1527 printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op);
@@ -1903,6 +1939,7 @@ open_bchannel(struct hfc_pci *hc, struct channel_req *rq)
1903 bch = &hc->bch[rq->adr.channel - 1]; 1939 bch = &hc->bch[rq->adr.channel - 1];
1904 if (test_and_set_bit(FLG_OPEN, &bch->Flags)) 1940 if (test_and_set_bit(FLG_OPEN, &bch->Flags))
1905 return -EBUSY; /* b-channel can be only open once */ 1941 return -EBUSY; /* b-channel can be only open once */
1942 test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
1906 bch->ch.protocol = rq->protocol; 1943 bch->ch.protocol = rq->protocol;
1907 rq->ch = &bch->ch; /* TODO: E-channel */ 1944 rq->ch = &bch->ch; /* TODO: E-channel */
1908 if (!try_module_get(THIS_MODULE)) 1945 if (!try_module_get(THIS_MODULE))