Summary: add support for syba 7.1 surround sound card
Keywords: syba via VT1723 Tremor
Kernel: 3.8.8-203.fc18.x86_64

add support for syba 7.1 surround sound card
actually the card only has 6 dmas, so it is really only 5.1
added code to force_rate setting to not fail EBUSY when the dmas are running.
suggest using force_rate with pulseaudio to avoid loops with error logging.

diff -ur a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
add support for syba 7.1 surround sound card
actually the card only has 6 dmas, so it is really only 5.1
added code to force_rate setting to not fail EBUSY when the dmas are running.
suggest using force_rate with pulseaudio to avoid loops with error logging.
Signed-off-by: psmith2...@yahoo.com
--- a/sound/pci/ice1712/ice1724.c       2013-04-24 14:19:10.225007602 -0600
+++ b/sound/pci/ice1712/ice1724.c       2013-04-29 08:49:26.739934818 -0600
@@ -72,6 +72,7 @@
               WTM_DEVICE_DESC
               SE_DEVICE_DESC
               QTET_DEVICE_DESC
+               "{Syba 7.1 Surround Sound},"
                "{VIA,VT1720},"
                "{VIA,VT1724},"
                "{ICEnsemble,Generic ICE1724},"
@@ -82,6 +83,7 @@
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;      /* ID for this card */
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;            /* 
Enable this card */
 static char *model[SNDRV_CARDS];
+static bool force_rate;
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for ICE1724 soundcard.");
@@ -91,7 +93,8 @@
 MODULE_PARM_DESC(enable, "Enable ICE1724 soundcard.");
 module_param_array(model, charp, NULL, 0444);
 MODULE_PARM_DESC(model, "Use the given board model.");
-
+module_param(force_rate, bool, 0644);
+MODULE_PARM_DESC(force_rate, "suppress err when setting rate while dma 
running");
 
 /* Both VT1720 and VT1724 have the same PCI IDs */
 static DEFINE_PCI_DEVICE_TABLE(snd_vt1724_ids) = {
@@ -570,18 +573,6 @@
        }
 
        switch (cmd) {
-       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-               spin_lock(&ice->reg_lock);
-               old = inb(ICEMT1724(ice, DMA_PAUSE));
-               if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
-                       old |= what;
-               else
-                       old &= ~what;
-               outb(old, ICEMT1724(ice, DMA_PAUSE));
-               spin_unlock(&ice->reg_lock);
-               break;
-
        case SNDRV_PCM_TRIGGER_START:
        case SNDRV_PCM_TRIGGER_STOP:
        case SNDRV_PCM_TRIGGER_SUSPEND:
@@ -593,6 +584,19 @@
                        old &= ~what;
                outb(old, ICEMT1724(ice, DMA_CONTROL));
                spin_unlock(&ice->reg_lock);
+               if (cmd == SNDRV_PCM_TRIGGER_START)
+                       break;
+               /* fall through */
+       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               spin_lock(&ice->reg_lock);
+               old = inb(ICEMT1724(ice, DMA_PAUSE));
+               if (cmd == SNDRV_PCM_TRIGGER_PAUSE_PUSH)
+                       old |= what;
+               else
+                       old &= ~what;
+               outb(old, ICEMT1724(ice, DMA_PAUSE));
+               spin_unlock(&ice->reg_lock);
                break;
 
        case SNDRV_PCM_TRIGGER_RESUME:
@@ -663,17 +667,27 @@
        unsigned long flags;
        unsigned char mclk_change;
        unsigned int i, old_rate;
+       unsigned char dma_control, dma_pause;
 
        if (rate > ice->hw_rates->list[ice->hw_rates->count - 1])
                return -EINVAL;
 
        spin_lock_irqsave(&ice->reg_lock, flags);
-       if ((inb(ICEMT1724(ice, DMA_CONTROL)) & DMA_STARTS) ||
-           (inb(ICEMT1724(ice, DMA_PAUSE)) & DMA_PAUSES)) {
+       dma_control = inb(ICEMT1724(ice, DMA_CONTROL));
+       dma_pause = inb(ICEMT1724(ice, DMA_PAUSE));
+       if ((dma_control & DMA_STARTS) || (dma_pause & DMA_PAUSES)) {
+               int ret = 0;
                /* running? we cannot change the rate now... */
+               if ((rate != ice->cur_rate) && force >= 0) {
+                       snd_printd("ice1724: dma busy %02x/%02x, rate reset\n",
+                               dma_control, dma_pause);
+                               ret = -EBUSY;
+               }
                spin_unlock_irqrestore(&ice->reg_lock, flags);
-               return ((rate == ice->cur_rate) && !force) ? 0 : -EBUSY;
+               return ret;
        }
+       if (force < 0)
+               force = 0;
        if (!force && is_pro_rate_locked(ice)) {
                /* comparing required and current rate - makes sense for
                 * internal clock only */
@@ -720,7 +734,7 @@
                                    struct snd_pcm_hw_params *hw_params)
 {
        struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
-       int i, chs, err;
+       int i, chs, err, force;
 
        chs = params_channels(hw_params);
        mutex_lock(&ice->open_mutex);
@@ -756,7 +770,8 @@
        }
        mutex_unlock(&ice->open_mutex);
 
-       err = snd_vt1724_set_pro_rate(ice, params_rate(hw_params), 0);
+       force = force_rate ? -1 : 0;
+       err = snd_vt1724_set_pro_rate(ice, params_rate(hw_params), force);
        if (err < 0)
                return err;
 
@@ -768,6 +783,7 @@
        struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
        int i;
 
+       snd_vt1724_pcm_trigger(substream, SNDRV_PCM_TRIGGER_STOP);
        mutex_lock(&ice->open_mutex);
        /* unmark surround channels */
        for (i = 0; i < 3; i++)
@@ -1068,6 +1084,8 @@
        constrain_rate_if_locked(substream);
        if (ice->pro_open)
                ice->pro_open(ice, substream);
+       if (ice->quirk_open)
+               ice->quirk_open(ice);
        return 0;
 }
 
@@ -1089,6 +1107,8 @@
        constrain_rate_if_locked(substream);
        if (ice->pro_open)
                ice->pro_open(ice, substream);
+       if (ice->quirk_open)
+               ice->quirk_open(ice);
        return 0;
 }
 
@@ -1422,6 +1442,8 @@
        snd_pcm_set_sync(substream);
        snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
        set_rate_constraints(ice, substream);
+       if (ice->quirk_open)
+               ice->quirk_open(ice);
        return 0;
 }
 
@@ -2242,6 +2264,46 @@
        { } /* terminator */
 };
 
+
+#define VT1724_SUBDEVICE_SYBA_71_SS 0x12140324
+
+static void syba_quirk_open(struct snd_ice1712 *ice)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&ice->reg_lock, flags);
+       outb(0xff, ICEREG1724(ice, AC97_CFG));
+       udelay(500);
+       outb(ice->eeprom.data[ICE_EEP2_ACLINK], ICEREG1724(ice, AC97_CFG));
+       spin_unlock_irqrestore(&ice->reg_lock, flags);
+}
+
+static int syba_init(struct snd_ice1712 *ice)
+{
+       /* determine I2C, DACs and ADCs */
+       switch (ice->eeprom.subvendor) {
+       case VT1724_SUBDEVICE_SYBA_71_SS:
+               ice->num_total_dacs = 8;
+               ice->num_total_adcs = 2;
+               ice->quirk_open = syba_quirk_open;
+               break;
+       default:
+               snd_BUG();
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static struct snd_ice1712_card_info snd_vt1724_syba_cards[] = {
+       {
+               .subvendor = VT1724_SUBDEVICE_SYBA_71_SS,
+               .name = "Syba 7.1 Surround Sound",
+               .model = "syba71ss",
+               .chip_init = syba_init,
+       },
+       { } /* terminator */
+};
+
+
 static struct snd_ice1712_card_info *card_tables[] = {
        snd_vt1724_revo_cards,
        snd_vt1724_amp_cards,
@@ -2258,6 +2320,7 @@
        snd_vt1724_qtet_cards,
        snd_vt1724_ooaoo_cards,
        snd_vt1724_psc724_cards,
+       snd_vt1724_syba_cards,
        NULL,
 };
 

Reply via email to