linux/sound/pci/ice1712/revo.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *   ALSA driver for ICEnsemble ICE1712 (Envy24)
   4 *
   5 *   Lowlevel functions for M-Audio Audiophile 192, Revolution 7.1 and 5.1
   6 *
   7 *      Copyright (c) 2003 Takashi Iwai <tiwai@suse.de>
   8 */      
   9
  10#include <linux/delay.h>
  11#include <linux/interrupt.h>
  12#include <linux/init.h>
  13#include <linux/slab.h>
  14#include <sound/core.h>
  15
  16#include "ice1712.h"
  17#include "envy24ht.h"
  18#include "revo.h"
  19
  20/* a non-standard I2C device for revo51 */
  21struct revo51_spec {
  22        struct snd_i2c_device *dev;
  23        struct snd_pt2258 *pt2258;
  24        struct ak4114 *ak4114;
  25};
  26
  27static void revo_i2s_mclk_changed(struct snd_ice1712 *ice)
  28{
  29        /* assert PRST# to converters; MT05 bit 7 */
  30        outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
  31        mdelay(5);
  32        /* deassert PRST# */
  33        outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD));
  34}
  35
  36/*
  37 * change the rate of Envy24HT, AK4355 and AK4381
  38 */
  39static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
  40{
  41        unsigned char old, tmp, dfs;
  42        int reg, shift;
  43
  44        if (rate == 0)  /* no hint - S/PDIF input is master, simply return */
  45                return;
  46
  47        /* adjust DFS on codecs */
  48        if (rate > 96000)
  49                dfs = 2;
  50        else if (rate > 48000)
  51                dfs = 1;
  52        else
  53                dfs = 0;
  54
  55        if (ak->type == SND_AK4355 || ak->type == SND_AK4358) {
  56                reg = 2;
  57                shift = 4;
  58        } else {
  59                reg = 1;
  60                shift = 3;
  61        }
  62        tmp = snd_akm4xxx_get(ak, 0, reg);
  63        old = (tmp >> shift) & 0x03;
  64        if (old == dfs)
  65                return;
  66
  67        /* reset DFS */
  68        snd_akm4xxx_reset(ak, 1);
  69        tmp = snd_akm4xxx_get(ak, 0, reg);
  70        tmp &= ~(0x03 << shift);
  71        tmp |= dfs << shift;
  72        /* snd_akm4xxx_write(ak, 0, reg, tmp); */
  73        snd_akm4xxx_set(ak, 0, reg, tmp); /* value is written in reset(0) */
  74        snd_akm4xxx_reset(ak, 0);
  75}
  76
  77/*
  78 * I2C access to the PT2258 volume controller on GPIO 6/7 (Revolution 5.1)
  79 */
  80
  81static void revo_i2c_start(struct snd_i2c_bus *bus)
  82{
  83        struct snd_ice1712 *ice = bus->private_data;
  84        snd_ice1712_save_gpio_status(ice);
  85}
  86
  87static void revo_i2c_stop(struct snd_i2c_bus *bus)
  88{
  89        struct snd_ice1712 *ice = bus->private_data;
  90        snd_ice1712_restore_gpio_status(ice);
  91}
  92
  93static void revo_i2c_direction(struct snd_i2c_bus *bus, int clock, int data)
  94{
  95        struct snd_ice1712 *ice = bus->private_data;
  96        unsigned int mask, val;
  97
  98        val = 0;
  99        if (clock)
 100                val |= VT1724_REVO_I2C_CLOCK;   /* write SCL */
 101        if (data)
 102                val |= VT1724_REVO_I2C_DATA;    /* write SDA */
 103        mask = VT1724_REVO_I2C_CLOCK | VT1724_REVO_I2C_DATA;
 104        ice->gpio.direction &= ~mask;
 105        ice->gpio.direction |= val;
 106        snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
 107        snd_ice1712_gpio_set_mask(ice, ~mask);
 108}
 109
 110static void revo_i2c_setlines(struct snd_i2c_bus *bus, int clk, int data)
 111{
 112        struct snd_ice1712 *ice = bus->private_data;
 113        unsigned int val = 0;
 114
 115        if (clk)
 116                val |= VT1724_REVO_I2C_CLOCK;
 117        if (data)
 118                val |= VT1724_REVO_I2C_DATA;
 119        snd_ice1712_gpio_write_bits(ice,
 120                                    VT1724_REVO_I2C_DATA |
 121                                    VT1724_REVO_I2C_CLOCK, val);
 122        udelay(5);
 123}
 124
 125static int revo_i2c_getdata(struct snd_i2c_bus *bus, int ack)
 126{
 127        struct snd_ice1712 *ice = bus->private_data;
 128        int bit;
 129
 130        if (ack)
 131                udelay(5);
 132        bit = snd_ice1712_gpio_read_bits(ice, VT1724_REVO_I2C_DATA) ? 1 : 0;
 133        return bit;
 134}
 135
 136static struct snd_i2c_bit_ops revo51_bit_ops = {
 137        .start = revo_i2c_start,
 138        .stop = revo_i2c_stop,
 139        .direction = revo_i2c_direction,
 140        .setlines = revo_i2c_setlines,
 141        .getdata = revo_i2c_getdata,
 142};
 143
 144static int revo51_i2c_init(struct snd_ice1712 *ice,
 145                           struct snd_pt2258 *pt)
 146{
 147        struct revo51_spec *spec;
 148        int err;
 149
 150        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 151        if (!spec)
 152                return -ENOMEM;
 153        ice->spec = spec;
 154
 155        /* create the I2C bus */
 156        err = snd_i2c_bus_create(ice->card, "ICE1724 GPIO6", NULL, &ice->i2c);
 157        if (err < 0)
 158                return err;
 159
 160        ice->i2c->private_data = ice;
 161        ice->i2c->hw_ops.bit = &revo51_bit_ops;
 162
 163        /* create the I2C device */
 164        err = snd_i2c_device_create(ice->i2c, "PT2258", 0x40, &spec->dev);
 165        if (err < 0)
 166                return err;
 167
 168        pt->card = ice->card;
 169        pt->i2c_bus = ice->i2c;
 170        pt->i2c_dev = spec->dev;
 171        spec->pt2258 = pt;
 172
 173        snd_pt2258_reset(pt);
 174
 175        return 0;
 176}
 177
 178/*
 179 * initialize the chips on M-Audio Revolution cards
 180 */
 181
 182#define AK_DAC(xname,xch) { .name = xname, .num_channels = xch }
 183
 184static const struct snd_akm4xxx_dac_channel revo71_front[] = {
 185        {
 186                .name = "PCM Playback Volume",
 187                .num_channels = 2,
 188                /* front channels DAC supports muting */
 189                .switch_name = "PCM Playback Switch",
 190        },
 191};
 192
 193static const struct snd_akm4xxx_dac_channel revo71_surround[] = {
 194        AK_DAC("PCM Center Playback Volume", 1),
 195        AK_DAC("PCM LFE Playback Volume", 1),
 196        AK_DAC("PCM Side Playback Volume", 2),
 197        AK_DAC("PCM Rear Playback Volume", 2),
 198};
 199
 200static const struct snd_akm4xxx_dac_channel revo51_dac[] = {
 201        AK_DAC("PCM Playback Volume", 2),
 202        AK_DAC("PCM Center Playback Volume", 1),
 203        AK_DAC("PCM LFE Playback Volume", 1),
 204        AK_DAC("PCM Rear Playback Volume", 2),
 205        AK_DAC("PCM Headphone Volume", 2),
 206};
 207
 208static const char *revo51_adc_input_names[] = {
 209        "Mic",
 210        "Line",
 211        "CD",
 212        NULL
 213};
 214
 215static const struct snd_akm4xxx_adc_channel revo51_adc[] = {
 216        {
 217                .name = "PCM Capture Volume",
 218                .switch_name = "PCM Capture Switch",
 219                .num_channels = 2,
 220                .input_names = revo51_adc_input_names
 221        },
 222};
 223
 224static const struct snd_akm4xxx akm_revo_front = {
 225        .type = SND_AK4381,
 226        .num_dacs = 2,
 227        .ops = {
 228                .set_rate_val = revo_set_rate_val
 229        },
 230        .dac_info = revo71_front,
 231};
 232
 233static const struct snd_ak4xxx_private akm_revo_front_priv = {
 234        .caddr = 1,
 235        .cif = 0,
 236        .data_mask = VT1724_REVO_CDOUT,
 237        .clk_mask = VT1724_REVO_CCLK,
 238        .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
 239        .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS2,
 240        .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
 241        .add_flags = VT1724_REVO_CCLK, /* high at init */
 242        .mask_flags = 0,
 243};
 244
 245static const struct snd_akm4xxx akm_revo_surround = {
 246        .type = SND_AK4355,
 247        .idx_offset = 1,
 248        .num_dacs = 6,
 249        .ops = {
 250                .set_rate_val = revo_set_rate_val
 251        },
 252        .dac_info = revo71_surround,
 253};
 254
 255static const struct snd_ak4xxx_private akm_revo_surround_priv = {
 256        .caddr = 3,
 257        .cif = 0,
 258        .data_mask = VT1724_REVO_CDOUT,
 259        .clk_mask = VT1724_REVO_CCLK,
 260        .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
 261        .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS1,
 262        .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
 263        .add_flags = VT1724_REVO_CCLK, /* high at init */
 264        .mask_flags = 0,
 265};
 266
 267static const struct snd_akm4xxx akm_revo51 = {
 268        .type = SND_AK4358,
 269        .num_dacs = 8,
 270        .ops = {
 271                .set_rate_val = revo_set_rate_val
 272        },
 273        .dac_info = revo51_dac,
 274};
 275
 276static const struct snd_ak4xxx_private akm_revo51_priv = {
 277        .caddr = 2,
 278        .cif = 0,
 279        .data_mask = VT1724_REVO_CDOUT,
 280        .clk_mask = VT1724_REVO_CCLK,
 281        .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1,
 282        .cs_addr = VT1724_REVO_CS1,
 283        .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1,
 284        .add_flags = VT1724_REVO_CCLK, /* high at init */
 285        .mask_flags = 0,
 286};
 287
 288static const struct snd_akm4xxx akm_revo51_adc = {
 289        .type = SND_AK5365,
 290        .num_adcs = 2,
 291        .adc_info = revo51_adc,
 292};
 293
 294static const struct snd_ak4xxx_private akm_revo51_adc_priv = {
 295        .caddr = 2,
 296        .cif = 0,
 297        .data_mask = VT1724_REVO_CDOUT,
 298        .clk_mask = VT1724_REVO_CCLK,
 299        .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1,
 300        .cs_addr = VT1724_REVO_CS0,
 301        .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1,
 302        .add_flags = VT1724_REVO_CCLK, /* high at init */
 303        .mask_flags = 0,
 304};
 305
 306static struct snd_pt2258 ptc_revo51_volume;
 307
 308/* AK4358 for AP192 DAC, AK5385A for ADC */
 309static void ap192_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
 310{
 311        struct snd_ice1712 *ice = ak->private_data[0];
 312        int dfs;
 313
 314        revo_set_rate_val(ak, rate);
 315
 316        /* reset CKS */
 317        snd_ice1712_gpio_write_bits(ice, 1 << 8, rate > 96000 ? 1 << 8 : 0);
 318        /* reset DFS pins of AK5385A for ADC, too */
 319        if (rate > 96000)
 320                dfs = 2;
 321        else if (rate > 48000)
 322                dfs = 1;
 323        else
 324                dfs = 0;
 325        snd_ice1712_gpio_write_bits(ice, 3 << 9, dfs << 9);
 326        /* reset ADC */
 327        snd_ice1712_gpio_write_bits(ice, 1 << 11, 0);
 328        snd_ice1712_gpio_write_bits(ice, 1 << 11, 1 << 11);
 329}
 330
 331static const struct snd_akm4xxx_dac_channel ap192_dac[] = {
 332        AK_DAC("PCM Playback Volume", 2)
 333};
 334
 335static const struct snd_akm4xxx akm_ap192 = {
 336        .type = SND_AK4358,
 337        .num_dacs = 2,
 338        .ops = {
 339                .set_rate_val = ap192_set_rate_val
 340        },
 341        .dac_info = ap192_dac,
 342};
 343
 344static const struct snd_ak4xxx_private akm_ap192_priv = {
 345        .caddr = 2,
 346        .cif = 0,
 347        .data_mask = VT1724_REVO_CDOUT,
 348        .clk_mask = VT1724_REVO_CCLK,
 349        .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS3,
 350        .cs_addr = VT1724_REVO_CS3,
 351        .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS3,
 352        .add_flags = VT1724_REVO_CCLK, /* high at init */
 353        .mask_flags = 0,
 354};
 355
 356/* AK4114 support on Audiophile 192 */
 357/* CDTO (pin 32) -- GPIO2 pin 52
 358 * CDTI (pin 33) -- GPIO3 pin 53 (shared with AK4358)
 359 * CCLK (pin 34) -- GPIO1 pin 51 (shared with AK4358)
 360 * CSN  (pin 35) -- GPIO7 pin 59
 361 */
 362#define AK4114_ADDR     0x00
 363
 364static void write_data(struct snd_ice1712 *ice, unsigned int gpio,
 365                       unsigned int data, int idx)
 366{
 367        for (; idx >= 0; idx--) {
 368                /* drop clock */
 369                gpio &= ~VT1724_REVO_CCLK;
 370                snd_ice1712_gpio_write(ice, gpio);
 371                udelay(1);
 372                /* set data */
 373                if (data & (1 << idx))
 374                        gpio |= VT1724_REVO_CDOUT;
 375                else
 376                        gpio &= ~VT1724_REVO_CDOUT;
 377                snd_ice1712_gpio_write(ice, gpio);
 378                udelay(1);
 379                /* raise clock */
 380                gpio |= VT1724_REVO_CCLK;
 381                snd_ice1712_gpio_write(ice, gpio);
 382                udelay(1);
 383        }
 384}
 385
 386static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio,
 387                               int idx)
 388{
 389        unsigned char data = 0;
 390
 391        for (; idx >= 0; idx--) {
 392                /* drop clock */
 393                gpio &= ~VT1724_REVO_CCLK;
 394                snd_ice1712_gpio_write(ice, gpio);
 395                udelay(1);
 396                /* read data */
 397                if (snd_ice1712_gpio_read(ice) & VT1724_REVO_CDIN)
 398                        data |= (1 << idx);
 399                udelay(1);
 400                /* raise clock */
 401                gpio |= VT1724_REVO_CCLK;
 402                snd_ice1712_gpio_write(ice, gpio);
 403                udelay(1);
 404        }
 405        return data;
 406}
 407
 408static unsigned int ap192_4wire_start(struct snd_ice1712 *ice)
 409{
 410        unsigned int tmp;
 411
 412        snd_ice1712_save_gpio_status(ice);
 413        tmp = snd_ice1712_gpio_read(ice);
 414        tmp |= VT1724_REVO_CCLK; /* high at init */
 415        tmp |= VT1724_REVO_CS0;
 416        tmp &= ~VT1724_REVO_CS3;
 417        snd_ice1712_gpio_write(ice, tmp);
 418        udelay(1);
 419        return tmp;
 420}
 421
 422static void ap192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp)
 423{
 424        tmp |= VT1724_REVO_CS3;
 425        tmp |= VT1724_REVO_CS0;
 426        snd_ice1712_gpio_write(ice, tmp);
 427        udelay(1);
 428        snd_ice1712_restore_gpio_status(ice);
 429}
 430
 431static void ap192_ak4114_write(void *private_data, unsigned char addr,
 432                               unsigned char data)
 433{
 434        struct snd_ice1712 *ice = private_data;
 435        unsigned int tmp, addrdata;
 436
 437        tmp = ap192_4wire_start(ice);
 438        addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f);
 439        addrdata = (addrdata << 8) | data;
 440        write_data(ice, tmp, addrdata, 15);
 441        ap192_4wire_finish(ice, tmp);
 442}
 443
 444static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr)
 445{
 446        struct snd_ice1712 *ice = private_data;
 447        unsigned int tmp;
 448        unsigned char data;
 449
 450        tmp = ap192_4wire_start(ice);
 451        write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7);
 452        data = read_data(ice, tmp, 7);
 453        ap192_4wire_finish(ice, tmp);
 454        return data;
 455}
 456
 457static int ap192_ak4114_init(struct snd_ice1712 *ice)
 458{
 459        static const unsigned char ak4114_init_vals[] = {
 460                AK4114_RST | AK4114_PWN | AK4114_OCKS0,
 461                AK4114_DIF_I24I2S,
 462                AK4114_TX1E,
 463                AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(0),
 464                0,
 465                0
 466        };
 467        static const unsigned char ak4114_init_txcsb[] = {
 468                0x41, 0x02, 0x2c, 0x00, 0x00
 469        };
 470        int err;
 471
 472        struct revo51_spec *spec;
 473        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 474        if (!spec)
 475                return -ENOMEM;
 476        ice->spec = spec;
 477
 478        err = snd_ak4114_create(ice->card,
 479                                 ap192_ak4114_read,
 480                                 ap192_ak4114_write,
 481                                 ak4114_init_vals, ak4114_init_txcsb,
 482                                 ice, &spec->ak4114);
 483        if (err < 0)
 484                return err;
 485        /* AK4114 in Revo cannot detect external rate correctly.
 486         * No reason to stop capture stream due to incorrect checks */
 487        spec->ak4114->check_flags = AK4114_CHECK_NO_RATE;
 488
 489        return 0;
 490}
 491
 492static int revo_init(struct snd_ice1712 *ice)
 493{
 494        struct snd_akm4xxx *ak;
 495        int err;
 496
 497        /* determine I2C, DACs and ADCs */
 498        switch (ice->eeprom.subvendor) {
 499        case VT1724_SUBDEVICE_REVOLUTION71:
 500                ice->num_total_dacs = 8;
 501                ice->num_total_adcs = 2;
 502                ice->gpio.i2s_mclk_changed = revo_i2s_mclk_changed;
 503                break;
 504        case VT1724_SUBDEVICE_REVOLUTION51:
 505                ice->num_total_dacs = 8;
 506                ice->num_total_adcs = 2;
 507                break;
 508        case VT1724_SUBDEVICE_AUDIOPHILE192:
 509                ice->num_total_dacs = 2;
 510                ice->num_total_adcs = 2;
 511                break;
 512        default:
 513                snd_BUG();
 514                return -EINVAL;
 515        }
 516
 517        /* second stage of initialization, analog parts and others */
 518        ak = ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL);
 519        if (! ak)
 520                return -ENOMEM;
 521        switch (ice->eeprom.subvendor) {
 522        case VT1724_SUBDEVICE_REVOLUTION71:
 523                ice->akm_codecs = 2;
 524                err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front,
 525                                                &akm_revo_front_priv, ice);
 526                if (err < 0)
 527                        return err;
 528                err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo_surround,
 529                                                &akm_revo_surround_priv, ice);
 530                if (err < 0)
 531                        return err;
 532                /* unmute all codecs */
 533                snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,
 534                                                VT1724_REVO_MUTE);
 535                break;
 536        case VT1724_SUBDEVICE_REVOLUTION51:
 537                ice->akm_codecs = 2;
 538                err = snd_ice1712_akm4xxx_init(ak, &akm_revo51,
 539                                               &akm_revo51_priv, ice);
 540                if (err < 0)
 541                        return err;
 542                err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo51_adc,
 543                                               &akm_revo51_adc_priv, ice);
 544                if (err < 0)
 545                        return err;
 546                err = revo51_i2c_init(ice, &ptc_revo51_volume);
 547                if (err < 0)
 548                        return err;
 549                /* unmute all codecs */
 550                snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,
 551                                            VT1724_REVO_MUTE);
 552                break;
 553        case VT1724_SUBDEVICE_AUDIOPHILE192:
 554                ice->akm_codecs = 1;
 555                err = snd_ice1712_akm4xxx_init(ak, &akm_ap192, &akm_ap192_priv,
 556                                               ice);
 557                if (err < 0)
 558                        return err;
 559                err = ap192_ak4114_init(ice);
 560                if (err < 0)
 561                        return err;
 562                
 563                /* unmute all codecs */
 564                snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,
 565                                            VT1724_REVO_MUTE);
 566                break;
 567        }
 568
 569        return 0;
 570}
 571
 572
 573static int revo_add_controls(struct snd_ice1712 *ice)
 574{
 575        struct revo51_spec *spec = ice->spec;
 576        int err;
 577
 578        switch (ice->eeprom.subvendor) {
 579        case VT1724_SUBDEVICE_REVOLUTION71:
 580                err = snd_ice1712_akm4xxx_build_controls(ice);
 581                if (err < 0)
 582                        return err;
 583                break;
 584        case VT1724_SUBDEVICE_REVOLUTION51:
 585                err = snd_ice1712_akm4xxx_build_controls(ice);
 586                if (err < 0)
 587                        return err;
 588                spec = ice->spec;
 589                err = snd_pt2258_build_controls(spec->pt2258);
 590                if (err < 0)
 591                        return err;
 592                break;
 593        case VT1724_SUBDEVICE_AUDIOPHILE192:
 594                err = snd_ice1712_akm4xxx_build_controls(ice);
 595                if (err < 0)
 596                        return err;
 597                /* only capture SPDIF over AK4114 */
 598                err = snd_ak4114_build(spec->ak4114, NULL,
 599                   ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
 600                if (err < 0)
 601                        return err;
 602                break;
 603        }
 604        return 0;
 605}
 606
 607/* entry point */
 608struct snd_ice1712_card_info snd_vt1724_revo_cards[] = {
 609        {
 610                .subvendor = VT1724_SUBDEVICE_REVOLUTION71,
 611                .name = "M Audio Revolution-7.1",
 612                .model = "revo71",
 613                .chip_init = revo_init,
 614                .build_controls = revo_add_controls,
 615        },
 616        {
 617                .subvendor = VT1724_SUBDEVICE_REVOLUTION51,
 618                .name = "M Audio Revolution-5.1",
 619                .model = "revo51",
 620                .chip_init = revo_init,
 621                .build_controls = revo_add_controls,
 622        },
 623        {
 624                .subvendor = VT1724_SUBDEVICE_AUDIOPHILE192,
 625                .name = "M Audio Audiophile192",
 626                .model = "ap192",
 627                .chip_init = revo_init,
 628                .build_controls = revo_add_controls,
 629        },
 630        { } /* terminator */
 631};
 632