linux/sound/pci/oxygen/xonar_cs43xx.c
<<
>>
Prefs
   1/*
   2 * card driver for models with CS4398/CS4362A DACs (Xonar D1/DX)
   3 *
   4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
   5 *
   6 *
   7 *  This driver is free software; you can redistribute it and/or modify
   8 *  it under the terms of the GNU General Public License, version 2.
   9 *
  10 *  This driver is distributed in the hope that it will be useful,
  11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 *  GNU General Public License for more details.
  14 *
  15 *  You should have received a copy of the GNU General Public License
  16 *  along with this driver; if not, see <http://www.gnu.org/licenses/>.
  17 */
  18
  19/*
  20 * Xonar D1/DX
  21 * -----------
  22 *
  23 * CMI8788:
  24 *
  25 *   I\xC2\xB2C <-> CS4398 (addr 1001111) (front)
  26 *       <-> CS4362A (addr 0011000) (surround, center/LFE, back)
  27 *
  28 *   GPI 0 <- external power present (DX only)
  29 *
  30 *   GPIO 0 -> enable output to speakers
  31 *   GPIO 1 -> route output to front panel
  32 *   GPIO 2 -> M0 of CS5361
  33 *   GPIO 3 -> M1 of CS5361
  34 *   GPIO 6 -> ?
  35 *   GPIO 7 -> ?
  36 *   GPIO 8 -> route input jack to line-in (0) or mic-in (1)
  37 *
  38 * CM9780:
  39 *
  40 *   LINE_OUT -> input of ADC
  41 *
  42 *   AUX_IN  <- aux
  43 *   MIC_IN  <- mic
  44 *   FMIC_IN <- front mic
  45 *
  46 *   GPO 0 -> route line-in (0) or AC97 output (1) to CS5361 input
  47 */
  48
  49#include <linux/pci.h>
  50#include <linux/delay.h>
  51#include <sound/ac97_codec.h>
  52#include <sound/control.h>
  53#include <sound/core.h>
  54#include <sound/pcm.h>
  55#include <sound/pcm_params.h>
  56#include <sound/tlv.h>
  57#include "xonar.h"
  58#include "cm9780.h"
  59#include "cs4398.h"
  60#include "cs4362a.h"
  61
  62#define GPI_EXT_POWER           0x01
  63#define GPIO_D1_OUTPUT_ENABLE   0x0001
  64#define GPIO_D1_FRONT_PANEL     0x0002
  65#define GPIO_D1_MAGIC           0x00c0
  66#define GPIO_D1_INPUT_ROUTE     0x0100
  67
  68#define I2C_DEVICE_CS4398       0x9e    /* 10011, AD1=1, AD0=1, /W=0 */
  69#define I2C_DEVICE_CS4362A      0x30    /* 001100, AD0=0, /W=0 */
  70
  71struct xonar_cs43xx {
  72        struct xonar_generic generic;
  73        u8 cs4398_regs[8];
  74        u8 cs4362a_regs[15];
  75};
  76
  77static void cs4398_write(struct oxygen *chip, u8 reg, u8 value)
  78{
  79        struct xonar_cs43xx *data = chip->model_data;
  80
  81        oxygen_write_i2c(chip, I2C_DEVICE_CS4398, reg, value);
  82        if (reg < ARRAY_SIZE(data->cs4398_regs))
  83                data->cs4398_regs[reg] = value;
  84}
  85
  86static void cs4398_write_cached(struct oxygen *chip, u8 reg, u8 value)
  87{
  88        struct xonar_cs43xx *data = chip->model_data;
  89
  90        if (value != data->cs4398_regs[reg])
  91                cs4398_write(chip, reg, value);
  92}
  93
  94static void cs4362a_write(struct oxygen *chip, u8 reg, u8 value)
  95{
  96        struct xonar_cs43xx *data = chip->model_data;
  97
  98        oxygen_write_i2c(chip, I2C_DEVICE_CS4362A, reg, value);
  99        if (reg < ARRAY_SIZE(data->cs4362a_regs))
 100                data->cs4362a_regs[reg] = value;
 101}
 102
 103static void cs4362a_write_cached(struct oxygen *chip, u8 reg, u8 value)
 104{
 105        struct xonar_cs43xx *data = chip->model_data;
 106
 107        if (value != data->cs4362a_regs[reg])
 108                cs4362a_write(chip, reg, value);
 109}
 110
 111static void cs43xx_registers_init(struct oxygen *chip)
 112{
 113        struct xonar_cs43xx *data = chip->model_data;
 114        unsigned int i;
 115
 116        /* set CPEN (control port mode) and power down */
 117        cs4398_write(chip, 8, CS4398_CPEN | CS4398_PDN);
 118        cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
 119        /* configure */
 120        cs4398_write(chip, 2, data->cs4398_regs[2]);
 121        cs4398_write(chip, 3, CS4398_ATAPI_B_R | CS4398_ATAPI_A_L);
 122        cs4398_write(chip, 4, data->cs4398_regs[4]);
 123        cs4398_write(chip, 5, data->cs4398_regs[5]);
 124        cs4398_write(chip, 6, data->cs4398_regs[6]);
 125        cs4398_write(chip, 7, data->cs4398_regs[7]);
 126        cs4362a_write(chip, 0x02, CS4362A_DIF_LJUST);
 127        cs4362a_write(chip, 0x03, CS4362A_MUTEC_6 | CS4362A_AMUTE |
 128                      CS4362A_RMP_UP | CS4362A_ZERO_CROSS | CS4362A_SOFT_RAMP);
 129        cs4362a_write(chip, 0x04, data->cs4362a_regs[0x04]);
 130        cs4362a_write(chip, 0x05, 0);
 131        for (i = 6; i <= 14; ++i)
 132                cs4362a_write(chip, i, data->cs4362a_regs[i]);
 133        /* clear power down */
 134        cs4398_write(chip, 8, CS4398_CPEN);
 135        cs4362a_write(chip, 0x01, CS4362A_CPEN);
 136}
 137
 138static void xonar_d1_init(struct oxygen *chip)
 139{
 140        struct xonar_cs43xx *data = chip->model_data;
 141
 142        data->generic.anti_pop_delay = 800;
 143        data->generic.output_enable_bit = GPIO_D1_OUTPUT_ENABLE;
 144        data->cs4398_regs[2] =
 145                CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST;
 146        data->cs4398_regs[4] = CS4398_MUTEP_LOW |
 147                CS4398_MUTE_B | CS4398_MUTE_A | CS4398_PAMUTE;
 148        data->cs4398_regs[5] = 60 * 2;
 149        data->cs4398_regs[6] = 60 * 2;
 150        data->cs4398_regs[7] = CS4398_RMP_DN | CS4398_RMP_UP |
 151                CS4398_ZERO_CROSS | CS4398_SOFT_RAMP;
 152        data->cs4362a_regs[4] = CS4362A_RMP_DN | CS4362A_DEM_NONE;
 153        data->cs4362a_regs[6] = CS4362A_FM_SINGLE |
 154                CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
 155        data->cs4362a_regs[7] = 60 | CS4362A_MUTE;
 156        data->cs4362a_regs[8] = 60 | CS4362A_MUTE;
 157        data->cs4362a_regs[9] = data->cs4362a_regs[6];
 158        data->cs4362a_regs[10] = 60 | CS4362A_MUTE;
 159        data->cs4362a_regs[11] = 60 | CS4362A_MUTE;
 160        data->cs4362a_regs[12] = data->cs4362a_regs[6];
 161        data->cs4362a_regs[13] = 60 | CS4362A_MUTE;
 162        data->cs4362a_regs[14] = 60 | CS4362A_MUTE;
 163
 164        oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
 165                       OXYGEN_2WIRE_LENGTH_8 |
 166                       OXYGEN_2WIRE_INTERRUPT_MASK |
 167                       OXYGEN_2WIRE_SPEED_FAST);
 168
 169        cs43xx_registers_init(chip);
 170
 171        oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
 172                          GPIO_D1_FRONT_PANEL |
 173                          GPIO_D1_MAGIC |
 174                          GPIO_D1_INPUT_ROUTE);
 175        oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
 176                            GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE);
 177
 178        xonar_init_cs53x1(chip);
 179        xonar_enable_output(chip);
 180
 181        snd_component_add(chip->card, "CS4398");
 182        snd_component_add(chip->card, "CS4362A");
 183        snd_component_add(chip->card, "CS5361");
 184}
 185
 186static void xonar_dx_init(struct oxygen *chip)
 187{
 188        struct xonar_cs43xx *data = chip->model_data;
 189
 190        data->generic.ext_power_reg = OXYGEN_GPI_DATA;
 191        data->generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
 192        data->generic.ext_power_bit = GPI_EXT_POWER;
 193        xonar_init_ext_power(chip);
 194        xonar_d1_init(chip);
 195}
 196
 197static void xonar_d1_cleanup(struct oxygen *chip)
 198{
 199        xonar_disable_output(chip);
 200        cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN);
 201        oxygen_clear_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC);
 202}
 203
 204static void xonar_d1_suspend(struct oxygen *chip)
 205{
 206        xonar_d1_cleanup(chip);
 207}
 208
 209static void xonar_d1_resume(struct oxygen *chip)
 210{
 211        oxygen_set_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC);
 212        msleep(1);
 213        cs43xx_registers_init(chip);
 214        xonar_enable_output(chip);
 215}
 216
 217static void set_cs43xx_params(struct oxygen *chip,
 218                              struct snd_pcm_hw_params *params)
 219{
 220        struct xonar_cs43xx *data = chip->model_data;
 221        u8 cs4398_fm, cs4362a_fm;
 222
 223        if (params_rate(params) <= 50000) {
 224                cs4398_fm = CS4398_FM_SINGLE;
 225                cs4362a_fm = CS4362A_FM_SINGLE;
 226        } else if (params_rate(params) <= 100000) {
 227                cs4398_fm = CS4398_FM_DOUBLE;
 228                cs4362a_fm = CS4362A_FM_DOUBLE;
 229        } else {
 230                cs4398_fm = CS4398_FM_QUAD;
 231                cs4362a_fm = CS4362A_FM_QUAD;
 232        }
 233        cs4398_fm |= CS4398_DEM_NONE | CS4398_DIF_LJUST;
 234        cs4398_write_cached(chip, 2, cs4398_fm);
 235        cs4362a_fm |= data->cs4362a_regs[6] & ~CS4362A_FM_MASK;
 236        cs4362a_write_cached(chip, 6, cs4362a_fm);
 237        cs4362a_write_cached(chip, 12, cs4362a_fm);
 238        cs4362a_fm &= CS4362A_FM_MASK;
 239        cs4362a_fm |= data->cs4362a_regs[9] & ~CS4362A_FM_MASK;
 240        cs4362a_write_cached(chip, 9, cs4362a_fm);
 241}
 242
 243static void update_cs4362a_volumes(struct oxygen *chip)
 244{
 245        unsigned int i;
 246        u8 mute;
 247
 248        mute = chip->dac_mute ? CS4362A_MUTE : 0;
 249        for (i = 0; i < 6; ++i)
 250                cs4362a_write_cached(chip, 7 + i + i / 2,
 251                                     (127 - chip->dac_volume[2 + i]) | mute);
 252}
 253
 254static void update_cs43xx_volume(struct oxygen *chip)
 255{
 256        cs4398_write_cached(chip, 5, (127 - chip->dac_volume[0]) * 2);
 257        cs4398_write_cached(chip, 6, (127 - chip->dac_volume[1]) * 2);
 258        update_cs4362a_volumes(chip);
 259}
 260
 261static void update_cs43xx_mute(struct oxygen *chip)
 262{
 263        u8 reg;
 264
 265        reg = CS4398_MUTEP_LOW | CS4398_PAMUTE;
 266        if (chip->dac_mute)
 267                reg |= CS4398_MUTE_B | CS4398_MUTE_A;
 268        cs4398_write_cached(chip, 4, reg);
 269        update_cs4362a_volumes(chip);
 270}
 271
 272static void update_cs43xx_center_lfe_mix(struct oxygen *chip, bool mixed)
 273{
 274        struct xonar_cs43xx *data = chip->model_data;
 275        u8 reg;
 276
 277        reg = data->cs4362a_regs[9] & ~CS4362A_ATAPI_MASK;
 278        if (mixed)
 279                reg |= CS4362A_ATAPI_B_LR | CS4362A_ATAPI_A_LR;
 280        else
 281                reg |= CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L;
 282        cs4362a_write_cached(chip, 9, reg);
 283}
 284
 285static const struct snd_kcontrol_new front_panel_switch = {
 286        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 287        .name = "Front Panel Playback Switch",
 288        .info = snd_ctl_boolean_mono_info,
 289        .get = xonar_gpio_bit_switch_get,
 290        .put = xonar_gpio_bit_switch_put,
 291        .private_value = GPIO_D1_FRONT_PANEL,
 292};
 293
 294static int rolloff_info(struct snd_kcontrol *ctl,
 295                        struct snd_ctl_elem_info *info)
 296{
 297        static const char *const names[2] = {
 298                "Fast Roll-off", "Slow Roll-off"
 299        };
 300
 301        return snd_ctl_enum_info(info, 1, 2, names);
 302}
 303
 304static int rolloff_get(struct snd_kcontrol *ctl,
 305                       struct snd_ctl_elem_value *value)
 306{
 307        struct oxygen *chip = ctl->private_data;
 308        struct xonar_cs43xx *data = chip->model_data;
 309
 310        value->value.enumerated.item[0] =
 311                (data->cs4398_regs[7] & CS4398_FILT_SEL) != 0;
 312        return 0;
 313}
 314
 315static int rolloff_put(struct snd_kcontrol *ctl,
 316                       struct snd_ctl_elem_value *value)
 317{
 318        struct oxygen *chip = ctl->private_data;
 319        struct xonar_cs43xx *data = chip->model_data;
 320        int changed;
 321        u8 reg;
 322
 323        mutex_lock(&chip->mutex);
 324        reg = data->cs4398_regs[7];
 325        if (value->value.enumerated.item[0])
 326                reg |= CS4398_FILT_SEL;
 327        else
 328                reg &= ~CS4398_FILT_SEL;
 329        changed = reg != data->cs4398_regs[7];
 330        if (changed) {
 331                cs4398_write(chip, 7, reg);
 332                if (reg & CS4398_FILT_SEL)
 333                        reg = data->cs4362a_regs[0x04] | CS4362A_FILT_SEL;
 334                else
 335                        reg = data->cs4362a_regs[0x04] & ~CS4362A_FILT_SEL;
 336                cs4362a_write(chip, 0x04, reg);
 337        }
 338        mutex_unlock(&chip->mutex);
 339        return changed;
 340}
 341
 342static const struct snd_kcontrol_new rolloff_control = {
 343        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 344        .name = "DAC Filter Playback Enum",
 345        .info = rolloff_info,
 346        .get = rolloff_get,
 347        .put = rolloff_put,
 348};
 349
 350static void xonar_d1_line_mic_ac97_switch(struct oxygen *chip,
 351                                          unsigned int reg, unsigned int mute)
 352{
 353        if (reg == AC97_LINE) {
 354                spin_lock_irq(&chip->reg_lock);
 355                oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
 356                                      mute ? GPIO_D1_INPUT_ROUTE : 0,
 357                                      GPIO_D1_INPUT_ROUTE);
 358                spin_unlock_irq(&chip->reg_lock);
 359        }
 360}
 361
 362static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -6000, 100, 0);
 363
 364static int xonar_d1_mixer_init(struct oxygen *chip)
 365{
 366        int err;
 367
 368        err = snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip));
 369        if (err < 0)
 370                return err;
 371        err = snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip));
 372        if (err < 0)
 373                return err;
 374        return 0;
 375}
 376
 377static void dump_cs4362a_registers(struct xonar_cs43xx *data,
 378                                   struct snd_info_buffer *buffer)
 379{
 380        unsigned int i;
 381
 382        snd_iprintf(buffer, "\nCS4362A:");
 383        for (i = 1; i <= 14; ++i)
 384                snd_iprintf(buffer, " %02x", data->cs4362a_regs[i]);
 385        snd_iprintf(buffer, "\n");
 386}
 387
 388static void dump_d1_registers(struct oxygen *chip,
 389                              struct snd_info_buffer *buffer)
 390{
 391        struct xonar_cs43xx *data = chip->model_data;
 392        unsigned int i;
 393
 394        snd_iprintf(buffer, "\nCS4398: 7?");
 395        for (i = 2; i < 8; ++i)
 396                snd_iprintf(buffer, " %02x", data->cs4398_regs[i]);
 397        snd_iprintf(buffer, "\n");
 398        dump_cs4362a_registers(data, buffer);
 399}
 400
 401static const struct oxygen_model model_xonar_d1 = {
 402        .longname = "Asus Virtuoso 100",
 403        .chip = "AV200",
 404        .init = xonar_d1_init,
 405        .mixer_init = xonar_d1_mixer_init,
 406        .cleanup = xonar_d1_cleanup,
 407        .suspend = xonar_d1_suspend,
 408        .resume = xonar_d1_resume,
 409        .set_dac_params = set_cs43xx_params,
 410        .set_adc_params = xonar_set_cs53x1_params,
 411        .update_dac_volume = update_cs43xx_volume,
 412        .update_dac_mute = update_cs43xx_mute,
 413        .update_center_lfe_mix = update_cs43xx_center_lfe_mix,
 414        .ac97_switch = xonar_d1_line_mic_ac97_switch,
 415        .dump_registers = dump_d1_registers,
 416        .dac_tlv = cs4362a_db_scale,
 417        .model_data_size = sizeof(struct xonar_cs43xx),
 418        .device_config = PLAYBACK_0_TO_I2S |
 419                         PLAYBACK_1_TO_SPDIF |
 420                         CAPTURE_0_FROM_I2S_2 |
 421                         AC97_FMIC_SWITCH,
 422        .dac_channels_pcm = 8,
 423        .dac_channels_mixer = 8,
 424        .dac_volume_min = 127 - 60,
 425        .dac_volume_max = 127,
 426        .function_flags = OXYGEN_FUNCTION_2WIRE,
 427        .dac_mclks = OXYGEN_MCLKS(256, 128, 128),
 428        .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
 429        .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
 430        .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
 431};
 432
 433int __devinit get_xonar_cs43xx_model(struct oxygen *chip,
 434                                     const struct pci_device_id *id)
 435{
 436        switch (id->subdevice) {
 437        case 0x834f:
 438                chip->model = model_xonar_d1;
 439                chip->model.shortname = "Xonar D1";
 440                break;
 441        case 0x8275:
 442        case 0x8327:
 443                chip->model = model_xonar_d1;
 444                chip->model.shortname = "Xonar DX";
 445                chip->model.init = xonar_dx_init;
 446                break;
 447        default:
 448                return -EINVAL;
 449        }
 450        return 0;
 451}
 452