root/sound/pci/oxygen/xonar_cs43xx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cs4398_write
  2. cs4398_write_cached
  3. cs4362a_write
  4. cs4362a_write_cached
  5. cs43xx_registers_init
  6. xonar_d1_init
  7. xonar_dx_init
  8. xonar_d1_cleanup
  9. xonar_d1_suspend
  10. xonar_d1_resume
  11. set_cs43xx_params
  12. update_cs4362a_volumes
  13. update_cs43xx_volume
  14. update_cs43xx_mute
  15. update_cs43xx_center_lfe_mix
  16. rolloff_info
  17. rolloff_get
  18. rolloff_put
  19. xonar_d1_line_mic_ac97_switch
  20. xonar_d1_mixer_init
  21. dump_cs4362a_registers
  22. dump_d1_registers
  23. get_xonar_cs43xx_model

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

/* [<][>][^][v][top][bottom][index][help] */