fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / sound / pci / ice1712 / revo.c
index d48d425..bf98ea3 100644 (file)
@@ -33,7 +33,7 @@
 #include "envy24ht.h"
 #include "revo.h"
 
-static void revo_i2s_mclk_changed(ice1712_t *ice)
+static void revo_i2s_mclk_changed(struct snd_ice1712 *ice)
 {
        /* assert PRST# to converters; MT05 bit 7 */
        outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
@@ -45,7 +45,7 @@ static void revo_i2s_mclk_changed(ice1712_t *ice)
 /*
  * change the rate of envy24HT, AK4355 and AK4381
  */
-static void revo_set_rate_val(akm4xxx_t *ak, unsigned int rate)
+static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
 {
        unsigned char old, tmp, dfs;
        int reg, shift;
@@ -61,7 +61,7 @@ static void revo_set_rate_val(akm4xxx_t *ak, unsigned int rate)
        else
                dfs = 0;
 
-       if (ak->type == SND_AK4355) {
+       if (ak->type == SND_AK4355 || ak->type == SND_AK4358) {
                reg = 2;
                shift = 4;
        } else {
@@ -87,12 +87,41 @@ static void revo_set_rate_val(akm4xxx_t *ak, unsigned int rate)
  * initialize the chips on M-Audio Revolution cards
  */
 
-static akm4xxx_t akm_revo_front __devinitdata = {
+#define AK_DAC(xname,xch) { .name = xname, .num_channels = xch }
+
+static struct snd_akm4xxx_dac_channel revo71_front[] = {
+       AK_DAC("PCM Playback Volume", 2)
+};
+
+static struct snd_akm4xxx_dac_channel revo71_surround[] = {
+       AK_DAC("PCM Center Playback Volume", 1),
+       AK_DAC("PCM LFE Playback Volume", 1),
+       AK_DAC("PCM Side Playback Volume", 2),
+       AK_DAC("PCM Rear Playback Volume", 2),
+};
+
+static struct snd_akm4xxx_dac_channel revo51_dac[] = {
+       AK_DAC("PCM Playback Volume", 2),
+       AK_DAC("PCM Center Playback Volume", 1),
+       AK_DAC("PCM LFE Playback Volume", 1),
+       AK_DAC("PCM Rear Playback Volume", 2),
+};
+
+static struct snd_akm4xxx_adc_channel revo51_adc[] = {
+       {
+               .name = "PCM Capture Volume",
+               .switch_name = "PCM Capture Switch",
+               .num_channels = 2
+       },
+};
+
+static struct snd_akm4xxx akm_revo_front __devinitdata = {
        .type = SND_AK4381,
        .num_dacs = 2,
        .ops = {
                .set_rate_val = revo_set_rate_val
-       }
+       },
+       .dac_info = revo71_front,
 };
 
 static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = {
@@ -107,13 +136,14 @@ static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = {
        .mask_flags = 0,
 };
 
-static akm4xxx_t akm_revo_surround __devinitdata = {
+static struct snd_akm4xxx akm_revo_surround __devinitdata = {
        .type = SND_AK4355,
        .idx_offset = 1,
        .num_dacs = 6,
        .ops = {
                .set_rate_val = revo_set_rate_val
-       }
+       },
+       .dac_info = revo71_surround,
 };
 
 static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = {
@@ -128,20 +158,48 @@ static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = {
        .mask_flags = 0,
 };
 
-static unsigned int rates[] = {
-       32000, 44100, 48000, 64000, 88200, 96000,
-       176400, 192000,
+static struct snd_akm4xxx akm_revo51 __devinitdata = {
+       .type = SND_AK4358,
+       .num_dacs = 6,
+       .ops = {
+               .set_rate_val = revo_set_rate_val
+       },
+       .dac_info = revo51_dac,
 };
 
-static snd_pcm_hw_constraint_list_t revo_rates = {
-       .count = ARRAY_SIZE(rates),
-       .list = rates,
-       .mask = 0,
+static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = {
+       .caddr = 2,
+       .cif = 0,
+       .data_mask = VT1724_REVO_CDOUT,
+       .clk_mask = VT1724_REVO_CCLK,
+       .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
+       .cs_addr = VT1724_REVO_CS1 | VT1724_REVO_CS2,
+       .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
+       .add_flags = VT1724_REVO_CCLK, /* high at init */
+       .mask_flags = 0,
 };
 
-static int __devinit revo_init(ice1712_t *ice)
+static struct snd_akm4xxx akm_revo51_adc __devinitdata = {
+       .type = SND_AK5365,
+       .num_adcs = 2,
+       .adc_info = revo51_adc,
+};
+
+static struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = {
+       .caddr = 2,
+       .cif = 0,
+       .data_mask = VT1724_REVO_CDOUT,
+       .clk_mask = VT1724_REVO_CCLK,
+       .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
+       .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS2,
+       .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
+       .add_flags = VT1724_REVO_CCLK, /* high at init */
+       .mask_flags = 0,
+};
+
+static int __devinit revo_init(struct snd_ice1712 *ice)
 {
-       akm4xxx_t *ak;
+       struct snd_akm4xxx *ak;
        int err;
 
        /* determine I2C, DACs and ADCs */
@@ -149,21 +207,25 @@ static int __devinit revo_init(ice1712_t *ice)
        case VT1724_SUBDEVICE_REVOLUTION71:
                ice->num_total_dacs = 8;
                ice->num_total_adcs = 2;
+               ice->gpio.i2s_mclk_changed = revo_i2s_mclk_changed;
+               break;
+       case VT1724_SUBDEVICE_REVOLUTION51:
+               ice->num_total_dacs = 6;
+               ice->num_total_adcs = 2;
                break;
        default:
                snd_BUG();
                return -EINVAL;
        }
 
-       ice->gpio.i2s_mclk_changed = revo_i2s_mclk_changed;
-
        /* second stage of initialization, analog parts and others */
-       ak = ice->akm = kcalloc(2, sizeof(akm4xxx_t), GFP_KERNEL);
+       ak = ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL);
        if (! ak)
                return -ENOMEM;
        ice->akm_codecs = 2;
        switch (ice->eeprom.subvendor) {
        case VT1724_SUBDEVICE_REVOLUTION71:
+               ice->akm_codecs = 2;
                if ((err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front, &akm_revo_front_priv, ice)) < 0)
                        return err;
                if ((err = snd_ice1712_akm4xxx_init(ak + 1, &akm_revo_surround, &akm_revo_surround_priv, ice)) < 0)
@@ -171,20 +233,30 @@ static int __devinit revo_init(ice1712_t *ice)
                /* unmute all codecs */
                snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, VT1724_REVO_MUTE);
                break;
+       case VT1724_SUBDEVICE_REVOLUTION51:
+               ice->akm_codecs = 2;
+               if ((err = snd_ice1712_akm4xxx_init(ak, &akm_revo51, &akm_revo51_priv, ice)) < 0)
+                       return err;
+               err = snd_ice1712_akm4xxx_init(ak + 1, &akm_revo51_adc,
+                                              &akm_revo51_adc_priv, ice);
+               if (err < 0)
+                       return err;
+               /* unmute all codecs - needed! */
+               snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, VT1724_REVO_MUTE);
+               break;
        }
 
-       ice->hw_rates = &revo_rates; /* AK codecs don't support lower than 32k */
-
        return 0;
 }
 
 
-static int __devinit revo_add_controls(ice1712_t *ice)
+static int __devinit revo_add_controls(struct snd_ice1712 *ice)
 {
        int err;
 
        switch (ice->eeprom.subvendor) {
        case VT1724_SUBDEVICE_REVOLUTION71:
+       case VT1724_SUBDEVICE_REVOLUTION51:
                err = snd_ice1712_akm4xxx_build_controls(ice);
                if (err < 0)
                        return err;
@@ -201,5 +273,12 @@ struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = {
                .chip_init = revo_init,
                .build_controls = revo_add_controls,
        },
+       {
+               .subvendor = VT1724_SUBDEVICE_REVOLUTION51,
+               .name = "M Audio Revolution-5.1",
+               .model = "revo51",
+               .chip_init = revo_init,
+               .build_controls = revo_add_controls,
+       },
        { } /* terminator */
 };