Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *   ALSA driver for ICEnsemble ICE1712 (Envy24)
0004  *
0005  *   Lowlevel functions for M-Audio Audiophile 192, Revolution 7.1 and 5.1
0006  *
0007  *  Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
0008  */      
0009 
0010 #include <linux/delay.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/init.h>
0013 #include <linux/slab.h>
0014 #include <sound/core.h>
0015 
0016 #include "ice1712.h"
0017 #include "envy24ht.h"
0018 #include "revo.h"
0019 
0020 /* a non-standard I2C device for revo51 */
0021 struct revo51_spec {
0022     struct snd_i2c_device *dev;
0023     struct snd_pt2258 *pt2258;
0024     struct ak4114 *ak4114;
0025 };
0026 
0027 static void revo_i2s_mclk_changed(struct snd_ice1712 *ice)
0028 {
0029     /* assert PRST# to converters; MT05 bit 7 */
0030     outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
0031     mdelay(5);
0032     /* deassert PRST# */
0033     outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));
0034 }
0035 
0036 /*
0037  * change the rate of Envy24HT, AK4355 and AK4381
0038  */
0039 static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
0040 {
0041     unsigned char old, tmp, dfs;
0042     int reg, shift;
0043 
0044     if (rate == 0)  /* no hint - S/PDIF input is master, simply return */
0045         return;
0046 
0047     /* adjust DFS on codecs */
0048     if (rate > 96000)
0049         dfs = 2;
0050     else if (rate > 48000)
0051         dfs = 1;
0052     else
0053         dfs = 0;
0054 
0055     if (ak->type == SND_AK4355 || ak->type == SND_AK4358) {
0056         reg = 2;
0057         shift = 4;
0058     } else {
0059         reg = 1;
0060         shift = 3;
0061     }
0062     tmp = snd_akm4xxx_get(ak, 0, reg);
0063     old = (tmp >> shift) & 0x03;
0064     if (old == dfs)
0065         return;
0066 
0067     /* reset DFS */
0068     snd_akm4xxx_reset(ak, 1);
0069     tmp = snd_akm4xxx_get(ak, 0, reg);
0070     tmp &= ~(0x03 << shift);
0071     tmp |= dfs << shift;
0072     /* snd_akm4xxx_write(ak, 0, reg, tmp); */
0073     snd_akm4xxx_set(ak, 0, reg, tmp); /* value is written in reset(0) */
0074     snd_akm4xxx_reset(ak, 0);
0075 }
0076 
0077 /*
0078  * I2C access to the PT2258 volume controller on GPIO 6/7 (Revolution 5.1)
0079  */
0080 
0081 static void revo_i2c_start(struct snd_i2c_bus *bus)
0082 {
0083     struct snd_ice1712 *ice = bus->private_data;
0084     snd_ice1712_save_gpio_status(ice);
0085 }
0086 
0087 static void revo_i2c_stop(struct snd_i2c_bus *bus)
0088 {
0089     struct snd_ice1712 *ice = bus->private_data;
0090     snd_ice1712_restore_gpio_status(ice);
0091 }
0092 
0093 static void revo_i2c_direction(struct snd_i2c_bus *bus, int clock, int data)
0094 {
0095     struct snd_ice1712 *ice = bus->private_data;
0096     unsigned int mask, val;
0097 
0098     val = 0;
0099     if (clock)
0100         val |= VT1724_REVO_I2C_CLOCK;   /* write SCL */
0101     if (data)
0102         val |= VT1724_REVO_I2C_DATA;    /* write SDA */
0103     mask = VT1724_REVO_I2C_CLOCK | VT1724_REVO_I2C_DATA;
0104     ice->gpio.direction &= ~mask;
0105     ice->gpio.direction |= val;
0106     snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
0107     snd_ice1712_gpio_set_mask(ice, ~mask);
0108 }
0109 
0110 static void revo_i2c_setlines(struct snd_i2c_bus *bus, int clk, int data)
0111 {
0112     struct snd_ice1712 *ice = bus->private_data;
0113     unsigned int val = 0;
0114 
0115     if (clk)
0116         val |= VT1724_REVO_I2C_CLOCK;
0117     if (data)
0118         val |= VT1724_REVO_I2C_DATA;
0119     snd_ice1712_gpio_write_bits(ice,
0120                     VT1724_REVO_I2C_DATA |
0121                     VT1724_REVO_I2C_CLOCK, val);
0122     udelay(5);
0123 }
0124 
0125 static int revo_i2c_getdata(struct snd_i2c_bus *bus, int ack)
0126 {
0127     struct snd_ice1712 *ice = bus->private_data;
0128     int bit;
0129 
0130     if (ack)
0131         udelay(5);
0132     bit = snd_ice1712_gpio_read_bits(ice, VT1724_REVO_I2C_DATA) ? 1 : 0;
0133     return bit;
0134 }
0135 
0136 static struct snd_i2c_bit_ops revo51_bit_ops = {
0137     .start = revo_i2c_start,
0138     .stop = revo_i2c_stop,
0139     .direction = revo_i2c_direction,
0140     .setlines = revo_i2c_setlines,
0141     .getdata = revo_i2c_getdata,
0142 };
0143 
0144 static int revo51_i2c_init(struct snd_ice1712 *ice,
0145                struct snd_pt2258 *pt)
0146 {
0147     struct revo51_spec *spec;
0148     int err;
0149 
0150     spec = kzalloc(sizeof(*spec), GFP_KERNEL);
0151     if (!spec)
0152         return -ENOMEM;
0153     ice->spec = spec;
0154 
0155     /* create the I2C bus */
0156     err = snd_i2c_bus_create(ice->card, "ICE1724 GPIO6", NULL, &ice->i2c);
0157     if (err < 0)
0158         return err;
0159 
0160     ice->i2c->private_data = ice;
0161     ice->i2c->hw_ops.bit = &revo51_bit_ops;
0162 
0163     /* create the I2C device */
0164     err = snd_i2c_device_create(ice->i2c, "PT2258", 0x40, &spec->dev);
0165     if (err < 0)
0166         return err;
0167 
0168     pt->card = ice->card;
0169     pt->i2c_bus = ice->i2c;
0170     pt->i2c_dev = spec->dev;
0171     spec->pt2258 = pt;
0172 
0173     snd_pt2258_reset(pt);
0174 
0175     return 0;
0176 }
0177 
0178 /*
0179  * initialize the chips on M-Audio Revolution cards
0180  */
0181 
0182 #define AK_DAC(xname,xch) { .name = xname, .num_channels = xch }
0183 
0184 static const struct snd_akm4xxx_dac_channel revo71_front[] = {
0185     {
0186         .name = "PCM Playback Volume",
0187         .num_channels = 2,
0188         /* front channels DAC supports muting */
0189         .switch_name = "PCM Playback Switch",
0190     },
0191 };
0192 
0193 static const struct snd_akm4xxx_dac_channel revo71_surround[] = {
0194     AK_DAC("PCM Center Playback Volume", 1),
0195     AK_DAC("PCM LFE Playback Volume", 1),
0196     AK_DAC("PCM Side Playback Volume", 2),
0197     AK_DAC("PCM Rear Playback Volume", 2),
0198 };
0199 
0200 static const struct snd_akm4xxx_dac_channel revo51_dac[] = {
0201     AK_DAC("PCM Playback Volume", 2),
0202     AK_DAC("PCM Center Playback Volume", 1),
0203     AK_DAC("PCM LFE Playback Volume", 1),
0204     AK_DAC("PCM Rear Playback Volume", 2),
0205     AK_DAC("PCM Headphone Volume", 2),
0206 };
0207 
0208 static const char *revo51_adc_input_names[] = {
0209     "Mic",
0210     "Line",
0211     "CD",
0212     NULL
0213 };
0214 
0215 static const struct snd_akm4xxx_adc_channel revo51_adc[] = {
0216     {
0217         .name = "PCM Capture Volume",
0218         .switch_name = "PCM Capture Switch",
0219         .num_channels = 2,
0220         .input_names = revo51_adc_input_names
0221     },
0222 };
0223 
0224 static const struct snd_akm4xxx akm_revo_front = {
0225     .type = SND_AK4381,
0226     .num_dacs = 2,
0227     .ops = {
0228         .set_rate_val = revo_set_rate_val
0229     },
0230     .dac_info = revo71_front,
0231 };
0232 
0233 static const struct snd_ak4xxx_private akm_revo_front_priv = {
0234     .caddr = 1,
0235     .cif = 0,
0236     .data_mask = VT1724_REVO_CDOUT,
0237     .clk_mask = VT1724_REVO_CCLK,
0238     .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
0239     .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS2,
0240     .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
0241     .add_flags = VT1724_REVO_CCLK, /* high at init */
0242     .mask_flags = 0,
0243 };
0244 
0245 static const struct snd_akm4xxx akm_revo_surround = {
0246     .type = SND_AK4355,
0247     .idx_offset = 1,
0248     .num_dacs = 6,
0249     .ops = {
0250         .set_rate_val = revo_set_rate_val
0251     },
0252     .dac_info = revo71_surround,
0253 };
0254 
0255 static const struct snd_ak4xxx_private akm_revo_surround_priv = {
0256     .caddr = 3,
0257     .cif = 0,
0258     .data_mask = VT1724_REVO_CDOUT,
0259     .clk_mask = VT1724_REVO_CCLK,
0260     .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
0261     .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS1,
0262     .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
0263     .add_flags = VT1724_REVO_CCLK, /* high at init */
0264     .mask_flags = 0,
0265 };
0266 
0267 static const struct snd_akm4xxx akm_revo51 = {
0268     .type = SND_AK4358,
0269     .num_dacs = 8,
0270     .ops = {
0271         .set_rate_val = revo_set_rate_val
0272     },
0273     .dac_info = revo51_dac,
0274 };
0275 
0276 static const struct snd_ak4xxx_private akm_revo51_priv = {
0277     .caddr = 2,
0278     .cif = 0,
0279     .data_mask = VT1724_REVO_CDOUT,
0280     .clk_mask = VT1724_REVO_CCLK,
0281     .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1,
0282     .cs_addr = VT1724_REVO_CS1,
0283     .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1,
0284     .add_flags = VT1724_REVO_CCLK, /* high at init */
0285     .mask_flags = 0,
0286 };
0287 
0288 static const struct snd_akm4xxx akm_revo51_adc = {
0289     .type = SND_AK5365,
0290     .num_adcs = 2,
0291     .adc_info = revo51_adc,
0292 };
0293 
0294 static const struct snd_ak4xxx_private akm_revo51_adc_priv = {
0295     .caddr = 2,
0296     .cif = 0,
0297     .data_mask = VT1724_REVO_CDOUT,
0298     .clk_mask = VT1724_REVO_CCLK,
0299     .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1,
0300     .cs_addr = VT1724_REVO_CS0,
0301     .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1,
0302     .add_flags = VT1724_REVO_CCLK, /* high at init */
0303     .mask_flags = 0,
0304 };
0305 
0306 static struct snd_pt2258 ptc_revo51_volume;
0307 
0308 /* AK4358 for AP192 DAC, AK5385A for ADC */
0309 static void ap192_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
0310 {
0311     struct snd_ice1712 *ice = ak->private_data[0];
0312     int dfs;
0313 
0314     revo_set_rate_val(ak, rate);
0315 
0316     /* reset CKS */
0317     snd_ice1712_gpio_write_bits(ice, 1 << 8, rate > 96000 ? 1 << 8 : 0);
0318     /* reset DFS pins of AK5385A for ADC, too */
0319     if (rate > 96000)
0320         dfs = 2;
0321     else if (rate > 48000)
0322         dfs = 1;
0323     else
0324         dfs = 0;
0325     snd_ice1712_gpio_write_bits(ice, 3 << 9, dfs << 9);
0326     /* reset ADC */
0327     snd_ice1712_gpio_write_bits(ice, 1 << 11, 0);
0328     snd_ice1712_gpio_write_bits(ice, 1 << 11, 1 << 11);
0329 }
0330 
0331 static const struct snd_akm4xxx_dac_channel ap192_dac[] = {
0332     AK_DAC("PCM Playback Volume", 2)
0333 };
0334 
0335 static const struct snd_akm4xxx akm_ap192 = {
0336     .type = SND_AK4358,
0337     .num_dacs = 2,
0338     .ops = {
0339         .set_rate_val = ap192_set_rate_val
0340     },
0341     .dac_info = ap192_dac,
0342 };
0343 
0344 static const struct snd_ak4xxx_private akm_ap192_priv = {
0345     .caddr = 2,
0346     .cif = 0,
0347     .data_mask = VT1724_REVO_CDOUT,
0348     .clk_mask = VT1724_REVO_CCLK,
0349     .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS3,
0350     .cs_addr = VT1724_REVO_CS3,
0351     .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS3,
0352     .add_flags = VT1724_REVO_CCLK, /* high at init */
0353     .mask_flags = 0,
0354 };
0355 
0356 /* AK4114 support on Audiophile 192 */
0357 /* CDTO (pin 32) -- GPIO2 pin 52
0358  * CDTI (pin 33) -- GPIO3 pin 53 (shared with AK4358)
0359  * CCLK (pin 34) -- GPIO1 pin 51 (shared with AK4358)
0360  * CSN  (pin 35) -- GPIO7 pin 59
0361  */
0362 #define AK4114_ADDR 0x00
0363 
0364 static void write_data(struct snd_ice1712 *ice, unsigned int gpio,
0365                unsigned int data, int idx)
0366 {
0367     for (; idx >= 0; idx--) {
0368         /* drop clock */
0369         gpio &= ~VT1724_REVO_CCLK;
0370         snd_ice1712_gpio_write(ice, gpio);
0371         udelay(1);
0372         /* set data */
0373         if (data & (1 << idx))
0374             gpio |= VT1724_REVO_CDOUT;
0375         else
0376             gpio &= ~VT1724_REVO_CDOUT;
0377         snd_ice1712_gpio_write(ice, gpio);
0378         udelay(1);
0379         /* raise clock */
0380         gpio |= VT1724_REVO_CCLK;
0381         snd_ice1712_gpio_write(ice, gpio);
0382         udelay(1);
0383     }
0384 }
0385 
0386 static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio,
0387                    int idx)
0388 {
0389     unsigned char data = 0;
0390 
0391     for (; idx >= 0; idx--) {
0392         /* drop clock */
0393         gpio &= ~VT1724_REVO_CCLK;
0394         snd_ice1712_gpio_write(ice, gpio);
0395         udelay(1);
0396         /* read data */
0397         if (snd_ice1712_gpio_read(ice) & VT1724_REVO_CDIN)
0398             data |= (1 << idx);
0399         udelay(1);
0400         /* raise clock */
0401         gpio |= VT1724_REVO_CCLK;
0402         snd_ice1712_gpio_write(ice, gpio);
0403         udelay(1);
0404     }
0405     return data;
0406 }
0407 
0408 static unsigned int ap192_4wire_start(struct snd_ice1712 *ice)
0409 {
0410     unsigned int tmp;
0411 
0412     snd_ice1712_save_gpio_status(ice);
0413     tmp = snd_ice1712_gpio_read(ice);
0414     tmp |= VT1724_REVO_CCLK; /* high at init */
0415     tmp |= VT1724_REVO_CS0;
0416     tmp &= ~VT1724_REVO_CS3;
0417     snd_ice1712_gpio_write(ice, tmp);
0418     udelay(1);
0419     return tmp;
0420 }
0421 
0422 static void ap192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp)
0423 {
0424     tmp |= VT1724_REVO_CS3;
0425     tmp |= VT1724_REVO_CS0;
0426     snd_ice1712_gpio_write(ice, tmp);
0427     udelay(1);
0428     snd_ice1712_restore_gpio_status(ice);
0429 }
0430 
0431 static void ap192_ak4114_write(void *private_data, unsigned char addr,
0432                    unsigned char data)
0433 {
0434     struct snd_ice1712 *ice = private_data;
0435     unsigned int tmp, addrdata;
0436 
0437     tmp = ap192_4wire_start(ice);
0438     addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f);
0439     addrdata = (addrdata << 8) | data;
0440     write_data(ice, tmp, addrdata, 15);
0441     ap192_4wire_finish(ice, tmp);
0442 }
0443 
0444 static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr)
0445 {
0446     struct snd_ice1712 *ice = private_data;
0447     unsigned int tmp;
0448     unsigned char data;
0449 
0450     tmp = ap192_4wire_start(ice);
0451     write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7);
0452     data = read_data(ice, tmp, 7);
0453     ap192_4wire_finish(ice, tmp);
0454     return data;
0455 }
0456 
0457 static int ap192_ak4114_init(struct snd_ice1712 *ice)
0458 {
0459     static const unsigned char ak4114_init_vals[] = {
0460         AK4114_RST | AK4114_PWN | AK4114_OCKS0,
0461         AK4114_DIF_I24I2S,
0462         AK4114_TX1E,
0463         AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(0),
0464         0,
0465         0
0466     };
0467     static const unsigned char ak4114_init_txcsb[] = {
0468         0x41, 0x02, 0x2c, 0x00, 0x00
0469     };
0470     int err;
0471 
0472     struct revo51_spec *spec;
0473     spec = kzalloc(sizeof(*spec), GFP_KERNEL);
0474     if (!spec)
0475         return -ENOMEM;
0476     ice->spec = spec;
0477 
0478     err = snd_ak4114_create(ice->card,
0479                  ap192_ak4114_read,
0480                  ap192_ak4114_write,
0481                  ak4114_init_vals, ak4114_init_txcsb,
0482                  ice, &spec->ak4114);
0483     if (err < 0)
0484         return err;
0485     /* AK4114 in Revo cannot detect external rate correctly.
0486      * No reason to stop capture stream due to incorrect checks */
0487     spec->ak4114->check_flags = AK4114_CHECK_NO_RATE;
0488 
0489     return 0;
0490 }
0491 
0492 static int revo_init(struct snd_ice1712 *ice)
0493 {
0494     struct snd_akm4xxx *ak;
0495     int err;
0496 
0497     /* determine I2C, DACs and ADCs */
0498     switch (ice->eeprom.subvendor) {
0499     case VT1724_SUBDEVICE_REVOLUTION71:
0500         ice->num_total_dacs = 8;
0501         ice->num_total_adcs = 2;
0502         ice->gpio.i2s_mclk_changed = revo_i2s_mclk_changed;
0503         break;
0504     case VT1724_SUBDEVICE_REVOLUTION51:
0505         ice->num_total_dacs = 8;
0506         ice->num_total_adcs = 2;
0507         break;
0508     case VT1724_SUBDEVICE_AUDIOPHILE192:
0509         ice->num_total_dacs = 2;
0510         ice->num_total_adcs = 2;
0511         break;
0512     default:
0513         snd_BUG();
0514         return -EINVAL;
0515     }
0516 
0517     /* second stage of initialization, analog parts and others */
0518     ak = ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL);
0519     if (! ak)
0520         return -ENOMEM;
0521     switch (ice->eeprom.subvendor) {
0522     case VT1724_SUBDEVICE_REVOLUTION71:
0523         ice->akm_codecs = 2;
0524         err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front,
0525                         &akm_revo_front_priv, ice);
0526         if (err < 0)
0527             return err;
0528         err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo_surround,
0529                         &akm_revo_surround_priv, ice);
0530         if (err < 0)
0531             return err;
0532         /* unmute all codecs */
0533         snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,
0534                         VT1724_REVO_MUTE);
0535         break;
0536     case VT1724_SUBDEVICE_REVOLUTION51:
0537         ice->akm_codecs = 2;
0538         err = snd_ice1712_akm4xxx_init(ak, &akm_revo51,
0539                            &akm_revo51_priv, ice);
0540         if (err < 0)
0541             return err;
0542         err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo51_adc,
0543                            &akm_revo51_adc_priv, ice);
0544         if (err < 0)
0545             return err;
0546         err = revo51_i2c_init(ice, &ptc_revo51_volume);
0547         if (err < 0)
0548             return err;
0549         /* unmute all codecs */
0550         snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,
0551                         VT1724_REVO_MUTE);
0552         break;
0553     case VT1724_SUBDEVICE_AUDIOPHILE192:
0554         ice->akm_codecs = 1;
0555         err = snd_ice1712_akm4xxx_init(ak, &akm_ap192, &akm_ap192_priv,
0556                            ice);
0557         if (err < 0)
0558             return err;
0559         err = ap192_ak4114_init(ice);
0560         if (err < 0)
0561             return err;
0562         
0563         /* unmute all codecs */
0564         snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,
0565                         VT1724_REVO_MUTE);
0566         break;
0567     }
0568 
0569     return 0;
0570 }
0571 
0572 
0573 static int revo_add_controls(struct snd_ice1712 *ice)
0574 {
0575     struct revo51_spec *spec = ice->spec;
0576     int err;
0577 
0578     switch (ice->eeprom.subvendor) {
0579     case VT1724_SUBDEVICE_REVOLUTION71:
0580         err = snd_ice1712_akm4xxx_build_controls(ice);
0581         if (err < 0)
0582             return err;
0583         break;
0584     case VT1724_SUBDEVICE_REVOLUTION51:
0585         err = snd_ice1712_akm4xxx_build_controls(ice);
0586         if (err < 0)
0587             return err;
0588         spec = ice->spec;
0589         err = snd_pt2258_build_controls(spec->pt2258);
0590         if (err < 0)
0591             return err;
0592         break;
0593     case VT1724_SUBDEVICE_AUDIOPHILE192:
0594         err = snd_ice1712_akm4xxx_build_controls(ice);
0595         if (err < 0)
0596             return err;
0597         /* only capture SPDIF over AK4114 */
0598         err = snd_ak4114_build(spec->ak4114, NULL,
0599            ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
0600         if (err < 0)
0601             return err;
0602         break;
0603     }
0604     return 0;
0605 }
0606 
0607 /* entry point */
0608 struct snd_ice1712_card_info snd_vt1724_revo_cards[] = {
0609     {
0610         .subvendor = VT1724_SUBDEVICE_REVOLUTION71,
0611         .name = "M Audio Revolution-7.1",
0612         .model = "revo71",
0613         .chip_init = revo_init,
0614         .build_controls = revo_add_controls,
0615     },
0616     {
0617         .subvendor = VT1724_SUBDEVICE_REVOLUTION51,
0618         .name = "M Audio Revolution-5.1",
0619         .model = "revo51",
0620         .chip_init = revo_init,
0621         .build_controls = revo_add_controls,
0622     },
0623     {
0624         .subvendor = VT1724_SUBDEVICE_AUDIOPHILE192,
0625         .name = "M Audio Audiophile192",
0626         .model = "ap192",
0627         .chip_init = revo_init,
0628         .build_controls = revo_add_controls,
0629     },
0630     { } /* terminator */
0631 };