linux/sound/soc/codecs/adau1761.c
<<
>>
Prefs
   1/*
   2 * Driver for ADAU1361/ADAU1461/ADAU1761/ADAU1961 codec
   3 *
   4 * Copyright 2011-2013 Analog Devices Inc.
   5 * Author: Lars-Peter Clausen <lars@metafoo.de>
   6 *
   7 * Licensed under the GPL-2 or later.
   8 */
   9
  10#include <linux/module.h>
  11#include <linux/init.h>
  12#include <linux/i2c.h>
  13#include <linux/spi/spi.h>
  14#include <linux/slab.h>
  15#include <sound/core.h>
  16#include <sound/pcm.h>
  17#include <sound/pcm_params.h>
  18#include <sound/soc.h>
  19#include <sound/tlv.h>
  20#include <linux/platform_data/adau17x1.h>
  21
  22#include "adau17x1.h"
  23#include "adau1761.h"
  24
  25#define ADAU1761_DIGMIC_JACKDETECT      0x4008
  26#define ADAU1761_REC_MIXER_LEFT0        0x400a
  27#define ADAU1761_REC_MIXER_LEFT1        0x400b
  28#define ADAU1761_REC_MIXER_RIGHT0       0x400c
  29#define ADAU1761_REC_MIXER_RIGHT1       0x400d
  30#define ADAU1761_LEFT_DIFF_INPUT_VOL    0x400e
  31#define ADAU1761_RIGHT_DIFF_INPUT_VOL   0x400f
  32#define ADAU1761_PLAY_LR_MIXER_LEFT     0x4020
  33#define ADAU1761_PLAY_MIXER_LEFT0       0x401c
  34#define ADAU1761_PLAY_MIXER_LEFT1       0x401d
  35#define ADAU1761_PLAY_MIXER_RIGHT0      0x401e
  36#define ADAU1761_PLAY_MIXER_RIGHT1      0x401f
  37#define ADAU1761_PLAY_LR_MIXER_RIGHT    0x4021
  38#define ADAU1761_PLAY_MIXER_MONO        0x4022
  39#define ADAU1761_PLAY_HP_LEFT_VOL       0x4023
  40#define ADAU1761_PLAY_HP_RIGHT_VOL      0x4024
  41#define ADAU1761_PLAY_LINE_LEFT_VOL     0x4025
  42#define ADAU1761_PLAY_LINE_RIGHT_VOL    0x4026
  43#define ADAU1761_PLAY_MONO_OUTPUT_VOL   0x4027
  44#define ADAU1761_POP_CLICK_SUPPRESS     0x4028
  45#define ADAU1761_JACK_DETECT_PIN        0x4031
  46#define ADAU1761_DEJITTER               0x4036
  47#define ADAU1761_CLK_ENABLE0            0x40f9
  48#define ADAU1761_CLK_ENABLE1            0x40fa
  49
  50#define ADAU1761_DIGMIC_JACKDETECT_ACTIVE_LOW   BIT(0)
  51#define ADAU1761_DIGMIC_JACKDETECT_DIGMIC       BIT(5)
  52
  53#define ADAU1761_DIFF_INPUT_VOL_LDEN            BIT(0)
  54
  55#define ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP   BIT(0)
  56#define ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE    BIT(1)
  57
  58#define ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP      BIT(0)
  59
  60#define ADAU1761_PLAY_LINE_LEFT_VOL_MODE_HP     BIT(0)
  61
  62#define ADAU1761_PLAY_LINE_RIGHT_VOL_MODE_HP    BIT(0)
  63
  64
  65#define ADAU1761_FIRMWARE "adau1761.bin"
  66
  67static const struct reg_default adau1761_reg_defaults[] = {
  68        { ADAU1761_DEJITTER,                    0x03 },
  69        { ADAU1761_DIGMIC_JACKDETECT,           0x00 },
  70        { ADAU1761_REC_MIXER_LEFT0,             0x00 },
  71        { ADAU1761_REC_MIXER_LEFT1,             0x00 },
  72        { ADAU1761_REC_MIXER_RIGHT0,            0x00 },
  73        { ADAU1761_REC_MIXER_RIGHT1,            0x00 },
  74        { ADAU1761_LEFT_DIFF_INPUT_VOL,         0x00 },
  75        { ADAU1761_RIGHT_DIFF_INPUT_VOL,        0x00 },
  76        { ADAU1761_PLAY_LR_MIXER_LEFT,          0x00 },
  77        { ADAU1761_PLAY_MIXER_LEFT0,            0x00 },
  78        { ADAU1761_PLAY_MIXER_LEFT1,            0x00 },
  79        { ADAU1761_PLAY_MIXER_RIGHT0,           0x00 },
  80        { ADAU1761_PLAY_MIXER_RIGHT1,           0x00 },
  81        { ADAU1761_PLAY_LR_MIXER_RIGHT,         0x00 },
  82        { ADAU1761_PLAY_MIXER_MONO,             0x00 },
  83        { ADAU1761_PLAY_HP_LEFT_VOL,            0x00 },
  84        { ADAU1761_PLAY_HP_RIGHT_VOL,           0x00 },
  85        { ADAU1761_PLAY_LINE_LEFT_VOL,          0x00 },
  86        { ADAU1761_PLAY_LINE_RIGHT_VOL,         0x00 },
  87        { ADAU1761_PLAY_MONO_OUTPUT_VOL,        0x00 },
  88        { ADAU1761_POP_CLICK_SUPPRESS,          0x00 },
  89        { ADAU1761_JACK_DETECT_PIN,             0x00 },
  90        { ADAU1761_CLK_ENABLE0,                 0x00 },
  91        { ADAU1761_CLK_ENABLE1,                 0x00 },
  92        { ADAU17X1_CLOCK_CONTROL,               0x00 },
  93        { ADAU17X1_PLL_CONTROL,                 0x00 },
  94        { ADAU17X1_REC_POWER_MGMT,              0x00 },
  95        { ADAU17X1_MICBIAS,                     0x00 },
  96        { ADAU17X1_SERIAL_PORT0,                0x00 },
  97        { ADAU17X1_SERIAL_PORT1,                0x00 },
  98        { ADAU17X1_CONVERTER0,                  0x00 },
  99        { ADAU17X1_CONVERTER1,                  0x00 },
 100        { ADAU17X1_LEFT_INPUT_DIGITAL_VOL,      0x00 },
 101        { ADAU17X1_RIGHT_INPUT_DIGITAL_VOL,     0x00 },
 102        { ADAU17X1_ADC_CONTROL,                 0x00 },
 103        { ADAU17X1_PLAY_POWER_MGMT,             0x00 },
 104        { ADAU17X1_DAC_CONTROL0,                0x00 },
 105        { ADAU17X1_DAC_CONTROL1,                0x00 },
 106        { ADAU17X1_DAC_CONTROL2,                0x00 },
 107        { ADAU17X1_SERIAL_PORT_PAD,             0xaa },
 108        { ADAU17X1_CONTROL_PORT_PAD0,           0xaa },
 109        { ADAU17X1_CONTROL_PORT_PAD1,           0x00 },
 110        { ADAU17X1_DSP_SAMPLING_RATE,           0x01 },
 111        { ADAU17X1_SERIAL_INPUT_ROUTE,          0x00 },
 112        { ADAU17X1_SERIAL_OUTPUT_ROUTE,         0x00 },
 113        { ADAU17X1_DSP_ENABLE,                  0x00 },
 114        { ADAU17X1_DSP_RUN,                     0x00 },
 115        { ADAU17X1_SERIAL_SAMPLING_RATE,        0x00 },
 116};
 117
 118static const DECLARE_TLV_DB_SCALE(adau1761_sing_in_tlv, -1500, 300, 1);
 119static const DECLARE_TLV_DB_SCALE(adau1761_diff_in_tlv, -1200, 75, 0);
 120static const DECLARE_TLV_DB_SCALE(adau1761_out_tlv, -5700, 100, 0);
 121static const DECLARE_TLV_DB_SCALE(adau1761_sidetone_tlv, -1800, 300, 1);
 122static const DECLARE_TLV_DB_SCALE(adau1761_boost_tlv, -600, 600, 1);
 123static const DECLARE_TLV_DB_SCALE(adau1761_pga_boost_tlv, -2000, 2000, 1);
 124
 125static const unsigned int adau1761_bias_select_values[] = {
 126        0, 2, 3,
 127};
 128
 129static const char * const adau1761_bias_select_text[] = {
 130        "Normal operation", "Enhanced performance", "Power saving",
 131};
 132
 133static const char * const adau1761_bias_select_extreme_text[] = {
 134        "Normal operation", "Extreme power saving", "Enhanced performance",
 135        "Power saving",
 136};
 137
 138static SOC_ENUM_SINGLE_DECL(adau1761_adc_bias_enum,
 139                ADAU17X1_REC_POWER_MGMT, 3, adau1761_bias_select_extreme_text);
 140static SOC_ENUM_SINGLE_DECL(adau1761_hp_bias_enum,
 141                ADAU17X1_PLAY_POWER_MGMT, 6, adau1761_bias_select_extreme_text);
 142static SOC_ENUM_SINGLE_DECL(adau1761_dac_bias_enum,
 143                ADAU17X1_PLAY_POWER_MGMT, 4, adau1761_bias_select_extreme_text);
 144static SOC_VALUE_ENUM_SINGLE_DECL(adau1761_playback_bias_enum,
 145                ADAU17X1_PLAY_POWER_MGMT, 2, 0x3, adau1761_bias_select_text,
 146                adau1761_bias_select_values);
 147static SOC_VALUE_ENUM_SINGLE_DECL(adau1761_capture_bias_enum,
 148                ADAU17X1_REC_POWER_MGMT, 1, 0x3, adau1761_bias_select_text,
 149                adau1761_bias_select_values);
 150
 151static const struct snd_kcontrol_new adau1761_jack_detect_controls[] = {
 152        SOC_SINGLE("Speaker Auto-mute Switch", ADAU1761_DIGMIC_JACKDETECT,
 153                4, 1, 0),
 154};
 155
 156static const struct snd_kcontrol_new adau1761_differential_mode_controls[] = {
 157        SOC_DOUBLE_R_TLV("Capture Volume", ADAU1761_LEFT_DIFF_INPUT_VOL,
 158                ADAU1761_RIGHT_DIFF_INPUT_VOL, 2, 0x3f, 0,
 159                adau1761_diff_in_tlv),
 160        SOC_DOUBLE_R("Capture Switch", ADAU1761_LEFT_DIFF_INPUT_VOL,
 161                ADAU1761_RIGHT_DIFF_INPUT_VOL, 1, 1, 0),
 162
 163        SOC_DOUBLE_R_TLV("PGA Boost Capture Volume", ADAU1761_REC_MIXER_LEFT1,
 164                ADAU1761_REC_MIXER_RIGHT1, 3, 2, 0, adau1761_pga_boost_tlv),
 165};
 166
 167static const struct snd_kcontrol_new adau1761_single_mode_controls[] = {
 168        SOC_SINGLE_TLV("Input 1 Capture Volume", ADAU1761_REC_MIXER_LEFT0,
 169                4, 7, 0, adau1761_sing_in_tlv),
 170        SOC_SINGLE_TLV("Input 2 Capture Volume", ADAU1761_REC_MIXER_LEFT0,
 171                1, 7, 0, adau1761_sing_in_tlv),
 172        SOC_SINGLE_TLV("Input 3 Capture Volume", ADAU1761_REC_MIXER_RIGHT0,
 173                4, 7, 0, adau1761_sing_in_tlv),
 174        SOC_SINGLE_TLV("Input 4 Capture Volume", ADAU1761_REC_MIXER_RIGHT0,
 175                1, 7, 0, adau1761_sing_in_tlv),
 176};
 177
 178static const struct snd_kcontrol_new adau1761_controls[] = {
 179        SOC_DOUBLE_R_TLV("Aux Capture Volume", ADAU1761_REC_MIXER_LEFT1,
 180                ADAU1761_REC_MIXER_RIGHT1, 0, 7, 0, adau1761_sing_in_tlv),
 181
 182        SOC_DOUBLE_R_TLV("Headphone Playback Volume", ADAU1761_PLAY_HP_LEFT_VOL,
 183                ADAU1761_PLAY_HP_RIGHT_VOL, 2, 0x3f, 0, adau1761_out_tlv),
 184        SOC_DOUBLE_R("Headphone Playback Switch", ADAU1761_PLAY_HP_LEFT_VOL,
 185                ADAU1761_PLAY_HP_RIGHT_VOL, 1, 1, 0),
 186        SOC_DOUBLE_R_TLV("Lineout Playback Volume", ADAU1761_PLAY_LINE_LEFT_VOL,
 187                ADAU1761_PLAY_LINE_RIGHT_VOL, 2, 0x3f, 0, adau1761_out_tlv),
 188        SOC_DOUBLE_R("Lineout Playback Switch", ADAU1761_PLAY_LINE_LEFT_VOL,
 189                ADAU1761_PLAY_LINE_RIGHT_VOL, 1, 1, 0),
 190
 191        SOC_ENUM("ADC Bias", adau1761_adc_bias_enum),
 192        SOC_ENUM("DAC Bias", adau1761_dac_bias_enum),
 193        SOC_ENUM("Capture Bias", adau1761_capture_bias_enum),
 194        SOC_ENUM("Playback Bias", adau1761_playback_bias_enum),
 195        SOC_ENUM("Headphone Bias", adau1761_hp_bias_enum),
 196};
 197
 198static const struct snd_kcontrol_new adau1761_mono_controls[] = {
 199        SOC_SINGLE_TLV("Mono Playback Volume", ADAU1761_PLAY_MONO_OUTPUT_VOL,
 200                2, 0x3f, 0, adau1761_out_tlv),
 201        SOC_SINGLE("Mono Playback Switch", ADAU1761_PLAY_MONO_OUTPUT_VOL,
 202                1, 1, 0),
 203};
 204
 205static const struct snd_kcontrol_new adau1761_left_mixer_controls[] = {
 206        SOC_DAPM_SINGLE_AUTODISABLE("Left DAC Switch",
 207                ADAU1761_PLAY_MIXER_LEFT0, 5, 1, 0),
 208        SOC_DAPM_SINGLE_AUTODISABLE("Right DAC Switch",
 209                ADAU1761_PLAY_MIXER_LEFT0, 6, 1, 0),
 210        SOC_DAPM_SINGLE_TLV("Aux Bypass Volume",
 211                ADAU1761_PLAY_MIXER_LEFT0, 1, 8, 0, adau1761_sidetone_tlv),
 212        SOC_DAPM_SINGLE_TLV("Right Bypass Volume",
 213                ADAU1761_PLAY_MIXER_LEFT1, 4, 8, 0, adau1761_sidetone_tlv),
 214        SOC_DAPM_SINGLE_TLV("Left Bypass Volume",
 215                ADAU1761_PLAY_MIXER_LEFT1, 0, 8, 0, adau1761_sidetone_tlv),
 216};
 217
 218static const struct snd_kcontrol_new adau1761_right_mixer_controls[] = {
 219        SOC_DAPM_SINGLE_AUTODISABLE("Left DAC Switch",
 220                ADAU1761_PLAY_MIXER_RIGHT0, 5, 1, 0),
 221        SOC_DAPM_SINGLE_AUTODISABLE("Right DAC Switch",
 222                ADAU1761_PLAY_MIXER_RIGHT0, 6, 1, 0),
 223        SOC_DAPM_SINGLE_TLV("Aux Bypass Volume",
 224                ADAU1761_PLAY_MIXER_RIGHT0, 1, 8, 0, adau1761_sidetone_tlv),
 225        SOC_DAPM_SINGLE_TLV("Right Bypass Volume",
 226                ADAU1761_PLAY_MIXER_RIGHT1, 4, 8, 0, adau1761_sidetone_tlv),
 227        SOC_DAPM_SINGLE_TLV("Left Bypass Volume",
 228                ADAU1761_PLAY_MIXER_RIGHT1, 0, 8, 0, adau1761_sidetone_tlv),
 229};
 230
 231static const struct snd_kcontrol_new adau1761_left_lr_mixer_controls[] = {
 232        SOC_DAPM_SINGLE_TLV("Left Volume",
 233                ADAU1761_PLAY_LR_MIXER_LEFT, 1, 2, 0, adau1761_boost_tlv),
 234        SOC_DAPM_SINGLE_TLV("Right Volume",
 235                ADAU1761_PLAY_LR_MIXER_LEFT, 3, 2, 0, adau1761_boost_tlv),
 236};
 237
 238static const struct snd_kcontrol_new adau1761_right_lr_mixer_controls[] = {
 239        SOC_DAPM_SINGLE_TLV("Left Volume",
 240                ADAU1761_PLAY_LR_MIXER_RIGHT, 1, 2, 0, adau1761_boost_tlv),
 241        SOC_DAPM_SINGLE_TLV("Right Volume",
 242                ADAU1761_PLAY_LR_MIXER_RIGHT, 3, 2, 0, adau1761_boost_tlv),
 243};
 244
 245static const char * const adau1761_input_mux_text[] = {
 246        "ADC", "DMIC",
 247};
 248
 249static SOC_ENUM_SINGLE_DECL(adau1761_input_mux_enum,
 250        ADAU17X1_ADC_CONTROL, 2, adau1761_input_mux_text);
 251
 252static const struct snd_kcontrol_new adau1761_input_mux_control =
 253        SOC_DAPM_ENUM("Input Select", adau1761_input_mux_enum);
 254
 255static int adau1761_dejitter_fixup(struct snd_soc_dapm_widget *w,
 256        struct snd_kcontrol *kcontrol, int event)
 257{
 258        struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 259        struct adau *adau = snd_soc_component_get_drvdata(component);
 260
 261        /* After any power changes have been made the dejitter circuit
 262         * has to be reinitialized. */
 263        regmap_write(adau->regmap, ADAU1761_DEJITTER, 0);
 264        if (!adau->master)
 265                regmap_write(adau->regmap, ADAU1761_DEJITTER, 3);
 266
 267        return 0;
 268}
 269
 270static const struct snd_soc_dapm_widget adau1x61_dapm_widgets[] = {
 271        SND_SOC_DAPM_MIXER("Left Input Mixer", ADAU1761_REC_MIXER_LEFT0, 0, 0,
 272                NULL, 0),
 273        SND_SOC_DAPM_MIXER("Right Input Mixer", ADAU1761_REC_MIXER_RIGHT0, 0, 0,
 274                NULL, 0),
 275
 276        SOC_MIXER_ARRAY("Left Playback Mixer", ADAU1761_PLAY_MIXER_LEFT0,
 277                0, 0, adau1761_left_mixer_controls),
 278        SOC_MIXER_ARRAY("Right Playback Mixer", ADAU1761_PLAY_MIXER_RIGHT0,
 279                0, 0, adau1761_right_mixer_controls),
 280        SOC_MIXER_ARRAY("Left LR Playback Mixer", ADAU1761_PLAY_LR_MIXER_LEFT,
 281                0, 0, adau1761_left_lr_mixer_controls),
 282        SOC_MIXER_ARRAY("Right LR Playback Mixer", ADAU1761_PLAY_LR_MIXER_RIGHT,
 283                0, 0, adau1761_right_lr_mixer_controls),
 284
 285        SND_SOC_DAPM_SUPPLY("Headphone", ADAU1761_PLAY_HP_LEFT_VOL,
 286                0, 0, NULL, 0),
 287
 288        SND_SOC_DAPM_SUPPLY_S("SYSCLK", 2, SND_SOC_NOPM, 0, 0, NULL, 0),
 289
 290        SND_SOC_DAPM_POST("Dejitter fixup", adau1761_dejitter_fixup),
 291
 292        SND_SOC_DAPM_INPUT("LAUX"),
 293        SND_SOC_DAPM_INPUT("RAUX"),
 294        SND_SOC_DAPM_INPUT("LINP"),
 295        SND_SOC_DAPM_INPUT("LINN"),
 296        SND_SOC_DAPM_INPUT("RINP"),
 297        SND_SOC_DAPM_INPUT("RINN"),
 298
 299        SND_SOC_DAPM_OUTPUT("LOUT"),
 300        SND_SOC_DAPM_OUTPUT("ROUT"),
 301        SND_SOC_DAPM_OUTPUT("LHP"),
 302        SND_SOC_DAPM_OUTPUT("RHP"),
 303};
 304
 305static const struct snd_soc_dapm_widget adau1761_mono_dapm_widgets[] = {
 306        SND_SOC_DAPM_MIXER("Mono Playback Mixer", ADAU1761_PLAY_MIXER_MONO,
 307                0, 0, NULL, 0),
 308
 309        SND_SOC_DAPM_OUTPUT("MONOOUT"),
 310};
 311
 312static const struct snd_soc_dapm_widget adau1761_capless_dapm_widgets[] = {
 313        SND_SOC_DAPM_SUPPLY_S("Headphone VGND", 1, ADAU1761_PLAY_MIXER_MONO,
 314                0, 0, NULL, 0),
 315};
 316
 317static const struct snd_soc_dapm_route adau1x61_dapm_routes[] = {
 318        { "Left Input Mixer", NULL, "LINP" },
 319        { "Left Input Mixer", NULL, "LINN" },
 320        { "Left Input Mixer", NULL, "LAUX" },
 321
 322        { "Right Input Mixer", NULL, "RINP" },
 323        { "Right Input Mixer", NULL, "RINN" },
 324        { "Right Input Mixer", NULL, "RAUX" },
 325
 326        { "Left Playback Mixer", NULL, "Left Playback Enable"},
 327        { "Right Playback Mixer", NULL, "Right Playback Enable"},
 328        { "Left LR Playback Mixer", NULL, "Left Playback Enable"},
 329        { "Right LR Playback Mixer", NULL, "Right Playback Enable"},
 330
 331        { "Left Playback Mixer", "Left DAC Switch", "Left DAC" },
 332        { "Left Playback Mixer", "Right DAC Switch", "Right DAC" },
 333
 334        { "Right Playback Mixer", "Left DAC Switch", "Left DAC" },
 335        { "Right Playback Mixer", "Right DAC Switch", "Right DAC" },
 336
 337        { "Left LR Playback Mixer", "Left Volume", "Left Playback Mixer" },
 338        { "Left LR Playback Mixer", "Right Volume", "Right Playback Mixer" },
 339
 340        { "Right LR Playback Mixer", "Left Volume", "Left Playback Mixer" },
 341        { "Right LR Playback Mixer", "Right Volume", "Right Playback Mixer" },
 342
 343        { "LHP", NULL, "Left Playback Mixer" },
 344        { "RHP", NULL, "Right Playback Mixer" },
 345
 346        { "LHP", NULL, "Headphone" },
 347        { "RHP", NULL, "Headphone" },
 348
 349        { "LOUT", NULL, "Left LR Playback Mixer" },
 350        { "ROUT", NULL, "Right LR Playback Mixer" },
 351
 352        { "Left Playback Mixer", "Aux Bypass Volume", "LAUX" },
 353        { "Left Playback Mixer", "Left Bypass Volume", "Left Input Mixer" },
 354        { "Left Playback Mixer", "Right Bypass Volume", "Right Input Mixer" },
 355        { "Right Playback Mixer", "Aux Bypass Volume", "RAUX" },
 356        { "Right Playback Mixer", "Left Bypass Volume", "Left Input Mixer" },
 357        { "Right Playback Mixer", "Right Bypass Volume", "Right Input Mixer" },
 358};
 359
 360static const struct snd_soc_dapm_route adau1761_mono_dapm_routes[] = {
 361        { "Mono Playback Mixer", NULL, "Left Playback Mixer" },
 362        { "Mono Playback Mixer", NULL, "Right Playback Mixer" },
 363
 364        { "MONOOUT", NULL, "Mono Playback Mixer" },
 365};
 366
 367static const struct snd_soc_dapm_route adau1761_capless_dapm_routes[] = {
 368        { "Headphone", NULL, "Headphone VGND" },
 369};
 370
 371static const struct snd_soc_dapm_widget adau1761_dmic_widgets[] = {
 372        SND_SOC_DAPM_MUX("Left Decimator Mux", SND_SOC_NOPM, 0, 0,
 373                &adau1761_input_mux_control),
 374        SND_SOC_DAPM_MUX("Right Decimator Mux", SND_SOC_NOPM, 0, 0,
 375                &adau1761_input_mux_control),
 376
 377        SND_SOC_DAPM_INPUT("DMIC"),
 378};
 379
 380static const struct snd_soc_dapm_route adau1761_dmic_routes[] = {
 381        { "Left Decimator Mux", "ADC", "Left Input Mixer" },
 382        { "Left Decimator Mux", "DMIC", "DMIC" },
 383        { "Right Decimator Mux", "ADC", "Right Input Mixer" },
 384        { "Right Decimator Mux", "DMIC", "DMIC" },
 385
 386        { "Left Decimator", NULL, "Left Decimator Mux" },
 387        { "Right Decimator", NULL, "Right Decimator Mux" },
 388};
 389
 390static const struct snd_soc_dapm_route adau1761_no_dmic_routes[] = {
 391        { "Left Decimator", NULL, "Left Input Mixer" },
 392        { "Right Decimator", NULL, "Right Input Mixer" },
 393};
 394
 395static const struct snd_soc_dapm_widget adau1761_dapm_widgets[] = {
 396        SND_SOC_DAPM_SUPPLY("Serial Port Clock", ADAU1761_CLK_ENABLE0,
 397                0, 0, NULL, 0),
 398        SND_SOC_DAPM_SUPPLY("Serial Input Routing Clock", ADAU1761_CLK_ENABLE0,
 399                1, 0, NULL, 0),
 400        SND_SOC_DAPM_SUPPLY("Serial Output Routing Clock", ADAU1761_CLK_ENABLE0,
 401                3, 0, NULL, 0),
 402
 403        SND_SOC_DAPM_SUPPLY("Decimator Resync Clock", ADAU1761_CLK_ENABLE0,
 404                4, 0, NULL, 0),
 405        SND_SOC_DAPM_SUPPLY("Interpolator Resync Clock", ADAU1761_CLK_ENABLE0,
 406                2, 0, NULL, 0),
 407
 408        SND_SOC_DAPM_SUPPLY("Slew Clock", ADAU1761_CLK_ENABLE0, 6, 0, NULL, 0),
 409        SND_SOC_DAPM_SUPPLY("ALC Clock", ADAU1761_CLK_ENABLE0, 5, 0, NULL, 0),
 410
 411        SND_SOC_DAPM_SUPPLY_S("Digital Clock 0", 1, ADAU1761_CLK_ENABLE1,
 412                0, 0, NULL, 0),
 413        SND_SOC_DAPM_SUPPLY_S("Digital Clock 1", 1, ADAU1761_CLK_ENABLE1,
 414                1, 0, NULL, 0),
 415};
 416
 417static const struct snd_soc_dapm_route adau1761_dapm_routes[] = {
 418        { "Left Decimator", NULL, "Digital Clock 0", },
 419        { "Right Decimator", NULL, "Digital Clock 0", },
 420        { "Left DAC", NULL, "Digital Clock 0", },
 421        { "Right DAC", NULL, "Digital Clock 0", },
 422
 423        { "AIFCLK", NULL, "Digital Clock 1" },
 424
 425        { "Playback", NULL, "Serial Port Clock" },
 426        { "Capture", NULL, "Serial Port Clock" },
 427        { "Playback", NULL, "Serial Input Routing Clock" },
 428        { "Capture", NULL, "Serial Output Routing Clock" },
 429
 430        { "Left Decimator", NULL, "Decimator Resync Clock" },
 431        { "Right Decimator", NULL, "Decimator Resync Clock" },
 432        { "Left DAC", NULL, "Interpolator Resync Clock" },
 433        { "Right DAC", NULL, "Interpolator Resync Clock" },
 434
 435        { "DSP", NULL, "Digital Clock 0" },
 436
 437        { "Slew Clock", NULL, "Digital Clock 0" },
 438        { "Right Playback Mixer", NULL, "Slew Clock" },
 439        { "Left Playback Mixer", NULL, "Slew Clock" },
 440
 441        { "Left Input Mixer", NULL, "ALC Clock" },
 442        { "Right Input Mixer", NULL, "ALC Clock" },
 443
 444        { "Digital Clock 0", NULL, "SYSCLK" },
 445        { "Digital Clock 1", NULL, "SYSCLK" },
 446};
 447
 448static int adau1761_set_bias_level(struct snd_soc_component *component,
 449                                 enum snd_soc_bias_level level)
 450{
 451        struct adau *adau = snd_soc_component_get_drvdata(component);
 452
 453        switch (level) {
 454        case SND_SOC_BIAS_ON:
 455                break;
 456        case SND_SOC_BIAS_PREPARE:
 457                break;
 458        case SND_SOC_BIAS_STANDBY:
 459                regcache_cache_only(adau->regmap, false);
 460                regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
 461                        ADAU17X1_CLOCK_CONTROL_SYSCLK_EN,
 462                        ADAU17X1_CLOCK_CONTROL_SYSCLK_EN);
 463                if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
 464                        regcache_sync(adau->regmap);
 465                break;
 466        case SND_SOC_BIAS_OFF:
 467                regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
 468                        ADAU17X1_CLOCK_CONTROL_SYSCLK_EN, 0);
 469                regcache_cache_only(adau->regmap, true);
 470                break;
 471
 472        }
 473        return 0;
 474}
 475
 476static enum adau1761_output_mode adau1761_get_lineout_mode(
 477        struct snd_soc_component *component)
 478{
 479        struct adau1761_platform_data *pdata = component->dev->platform_data;
 480
 481        if (pdata)
 482                return pdata->lineout_mode;
 483
 484        return ADAU1761_OUTPUT_MODE_LINE;
 485}
 486
 487static int adau1761_setup_digmic_jackdetect(struct snd_soc_component *component)
 488{
 489        struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 490        struct adau1761_platform_data *pdata = component->dev->platform_data;
 491        struct adau *adau = snd_soc_component_get_drvdata(component);
 492        enum adau1761_digmic_jackdet_pin_mode mode;
 493        unsigned int val = 0;
 494        int ret;
 495
 496        if (pdata)
 497                mode = pdata->digmic_jackdetect_pin_mode;
 498        else
 499                mode = ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE;
 500
 501        switch (mode) {
 502        case ADAU1761_DIGMIC_JACKDET_PIN_MODE_JACKDETECT:
 503                switch (pdata->jackdetect_debounce_time) {
 504                case ADAU1761_JACKDETECT_DEBOUNCE_5MS:
 505                case ADAU1761_JACKDETECT_DEBOUNCE_10MS:
 506                case ADAU1761_JACKDETECT_DEBOUNCE_20MS:
 507                case ADAU1761_JACKDETECT_DEBOUNCE_40MS:
 508                        val |= pdata->jackdetect_debounce_time << 6;
 509                        break;
 510                default:
 511                        return -EINVAL;
 512                }
 513                if (pdata->jackdetect_active_low)
 514                        val |= ADAU1761_DIGMIC_JACKDETECT_ACTIVE_LOW;
 515
 516                ret = snd_soc_add_component_controls(component,
 517                        adau1761_jack_detect_controls,
 518                        ARRAY_SIZE(adau1761_jack_detect_controls));
 519                if (ret)
 520                        return ret;
 521                /* fall through */
 522        case ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE:
 523                ret = snd_soc_dapm_add_routes(dapm, adau1761_no_dmic_routes,
 524                        ARRAY_SIZE(adau1761_no_dmic_routes));
 525                if (ret)
 526                        return ret;
 527                break;
 528        case ADAU1761_DIGMIC_JACKDET_PIN_MODE_DIGMIC:
 529                ret = snd_soc_dapm_new_controls(dapm, adau1761_dmic_widgets,
 530                        ARRAY_SIZE(adau1761_dmic_widgets));
 531                if (ret)
 532                        return ret;
 533
 534                ret = snd_soc_dapm_add_routes(dapm, adau1761_dmic_routes,
 535                        ARRAY_SIZE(adau1761_dmic_routes));
 536                if (ret)
 537                        return ret;
 538
 539                val |= ADAU1761_DIGMIC_JACKDETECT_DIGMIC;
 540                break;
 541        default:
 542                return -EINVAL;
 543        }
 544
 545        regmap_write(adau->regmap, ADAU1761_DIGMIC_JACKDETECT, val);
 546
 547        return 0;
 548}
 549
 550static int adau1761_setup_headphone_mode(struct snd_soc_component *component)
 551{
 552        struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 553        struct adau *adau = snd_soc_component_get_drvdata(component);
 554        struct adau1761_platform_data *pdata = component->dev->platform_data;
 555        enum adau1761_output_mode mode;
 556        int ret;
 557
 558        if (pdata)
 559                mode = pdata->headphone_mode;
 560        else
 561                mode = ADAU1761_OUTPUT_MODE_HEADPHONE;
 562
 563        switch (mode) {
 564        case ADAU1761_OUTPUT_MODE_LINE:
 565                break;
 566        case ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS:
 567                regmap_update_bits(adau->regmap, ADAU1761_PLAY_MONO_OUTPUT_VOL,
 568                        ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP |
 569                        ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE,
 570                        ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP |
 571                        ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE);
 572                /* fallthrough */
 573        case ADAU1761_OUTPUT_MODE_HEADPHONE:
 574                regmap_update_bits(adau->regmap, ADAU1761_PLAY_HP_RIGHT_VOL,
 575                        ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP,
 576                        ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP);
 577                break;
 578        default:
 579                return -EINVAL;
 580        }
 581
 582        if (mode == ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS) {
 583                ret = snd_soc_dapm_new_controls(dapm,
 584                        adau1761_capless_dapm_widgets,
 585                        ARRAY_SIZE(adau1761_capless_dapm_widgets));
 586                if (ret)
 587                        return ret;
 588                ret = snd_soc_dapm_add_routes(dapm,
 589                        adau1761_capless_dapm_routes,
 590                        ARRAY_SIZE(adau1761_capless_dapm_routes));
 591        } else {
 592                ret = snd_soc_add_component_controls(component, adau1761_mono_controls,
 593                        ARRAY_SIZE(adau1761_mono_controls));
 594                if (ret)
 595                        return ret;
 596                ret = snd_soc_dapm_new_controls(dapm,
 597                        adau1761_mono_dapm_widgets,
 598                        ARRAY_SIZE(adau1761_mono_dapm_widgets));
 599                if (ret)
 600                        return ret;
 601                ret = snd_soc_dapm_add_routes(dapm,
 602                        adau1761_mono_dapm_routes,
 603                        ARRAY_SIZE(adau1761_mono_dapm_routes));
 604        }
 605
 606        return ret;
 607}
 608
 609static bool adau1761_readable_register(struct device *dev, unsigned int reg)
 610{
 611        switch (reg) {
 612        case ADAU1761_DIGMIC_JACKDETECT:
 613        case ADAU1761_REC_MIXER_LEFT0:
 614        case ADAU1761_REC_MIXER_LEFT1:
 615        case ADAU1761_REC_MIXER_RIGHT0:
 616        case ADAU1761_REC_MIXER_RIGHT1:
 617        case ADAU1761_LEFT_DIFF_INPUT_VOL:
 618        case ADAU1761_RIGHT_DIFF_INPUT_VOL:
 619        case ADAU1761_PLAY_LR_MIXER_LEFT:
 620        case ADAU1761_PLAY_MIXER_LEFT0:
 621        case ADAU1761_PLAY_MIXER_LEFT1:
 622        case ADAU1761_PLAY_MIXER_RIGHT0:
 623        case ADAU1761_PLAY_MIXER_RIGHT1:
 624        case ADAU1761_PLAY_LR_MIXER_RIGHT:
 625        case ADAU1761_PLAY_MIXER_MONO:
 626        case ADAU1761_PLAY_HP_LEFT_VOL:
 627        case ADAU1761_PLAY_HP_RIGHT_VOL:
 628        case ADAU1761_PLAY_LINE_LEFT_VOL:
 629        case ADAU1761_PLAY_LINE_RIGHT_VOL:
 630        case ADAU1761_PLAY_MONO_OUTPUT_VOL:
 631        case ADAU1761_POP_CLICK_SUPPRESS:
 632        case ADAU1761_JACK_DETECT_PIN:
 633        case ADAU1761_DEJITTER:
 634        case ADAU1761_CLK_ENABLE0:
 635        case ADAU1761_CLK_ENABLE1:
 636                return true;
 637        default:
 638                break;
 639        }
 640
 641        return adau17x1_readable_register(dev, reg);
 642}
 643
 644static int adau1761_component_probe(struct snd_soc_component *component)
 645{
 646        struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
 647        struct adau1761_platform_data *pdata = component->dev->platform_data;
 648        struct adau *adau = snd_soc_component_get_drvdata(component);
 649        int ret;
 650
 651        ret = adau17x1_add_widgets(component);
 652        if (ret < 0)
 653                return ret;
 654
 655        if (pdata && pdata->input_differential) {
 656                regmap_update_bits(adau->regmap, ADAU1761_LEFT_DIFF_INPUT_VOL,
 657                        ADAU1761_DIFF_INPUT_VOL_LDEN,
 658                        ADAU1761_DIFF_INPUT_VOL_LDEN);
 659                regmap_update_bits(adau->regmap, ADAU1761_RIGHT_DIFF_INPUT_VOL,
 660                        ADAU1761_DIFF_INPUT_VOL_LDEN,
 661                        ADAU1761_DIFF_INPUT_VOL_LDEN);
 662                ret = snd_soc_add_component_controls(component,
 663                        adau1761_differential_mode_controls,
 664                        ARRAY_SIZE(adau1761_differential_mode_controls));
 665                if (ret)
 666                        return ret;
 667        } else {
 668                ret = snd_soc_add_component_controls(component,
 669                        adau1761_single_mode_controls,
 670                        ARRAY_SIZE(adau1761_single_mode_controls));
 671                if (ret)
 672                        return ret;
 673        }
 674
 675        switch (adau1761_get_lineout_mode(component)) {
 676        case ADAU1761_OUTPUT_MODE_LINE:
 677                break;
 678        case ADAU1761_OUTPUT_MODE_HEADPHONE:
 679                regmap_update_bits(adau->regmap, ADAU1761_PLAY_LINE_LEFT_VOL,
 680                        ADAU1761_PLAY_LINE_LEFT_VOL_MODE_HP,
 681                        ADAU1761_PLAY_LINE_LEFT_VOL_MODE_HP);
 682                regmap_update_bits(adau->regmap, ADAU1761_PLAY_LINE_RIGHT_VOL,
 683                        ADAU1761_PLAY_LINE_RIGHT_VOL_MODE_HP,
 684                        ADAU1761_PLAY_LINE_RIGHT_VOL_MODE_HP);
 685                break;
 686        default:
 687                return -EINVAL;
 688        }
 689
 690        ret = adau1761_setup_headphone_mode(component);
 691        if (ret)
 692                return ret;
 693
 694        ret = adau1761_setup_digmic_jackdetect(component);
 695        if (ret)
 696                return ret;
 697
 698        if (adau->type == ADAU1761) {
 699                ret = snd_soc_dapm_new_controls(dapm, adau1761_dapm_widgets,
 700                        ARRAY_SIZE(adau1761_dapm_widgets));
 701                if (ret)
 702                        return ret;
 703
 704                ret = snd_soc_dapm_add_routes(dapm, adau1761_dapm_routes,
 705                        ARRAY_SIZE(adau1761_dapm_routes));
 706                if (ret)
 707                        return ret;
 708        }
 709
 710        ret = adau17x1_add_routes(component);
 711        if (ret < 0)
 712                return ret;
 713
 714        return 0;
 715}
 716
 717static const struct snd_soc_component_driver adau1761_component_driver = {
 718        .probe                  = adau1761_component_probe,
 719        .resume                 = adau17x1_resume,
 720        .set_bias_level         = adau1761_set_bias_level,
 721        .controls               = adau1761_controls,
 722        .num_controls           = ARRAY_SIZE(adau1761_controls),
 723        .dapm_widgets           = adau1x61_dapm_widgets,
 724        .num_dapm_widgets       = ARRAY_SIZE(adau1x61_dapm_widgets),
 725        .dapm_routes            = adau1x61_dapm_routes,
 726        .num_dapm_routes        = ARRAY_SIZE(adau1x61_dapm_routes),
 727        .suspend_bias_off       = 1,
 728        .idle_bias_on           = 1,
 729        .use_pmdown_time        = 1,
 730        .endianness             = 1,
 731        .non_legacy_dai_naming  = 1,
 732};
 733
 734#define ADAU1761_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
 735        SNDRV_PCM_FMTBIT_S32_LE)
 736
 737static struct snd_soc_dai_driver adau1361_dai_driver = {
 738        .name = "adau-hifi",
 739        .playback = {
 740                .stream_name = "Playback",
 741                .channels_min = 2,
 742                .channels_max = 4,
 743                .rates = SNDRV_PCM_RATE_8000_96000,
 744                .formats = ADAU1761_FORMATS,
 745        },
 746        .capture = {
 747                .stream_name = "Capture",
 748                .channels_min = 2,
 749                .channels_max = 4,
 750                .rates = SNDRV_PCM_RATE_8000_96000,
 751                .formats = ADAU1761_FORMATS,
 752        },
 753        .ops = &adau17x1_dai_ops,
 754};
 755
 756static struct snd_soc_dai_driver adau1761_dai_driver = {
 757        .name = "adau-hifi",
 758        .playback = {
 759                .stream_name = "Playback",
 760                .channels_min = 2,
 761                .channels_max = 8,
 762                .rates = SNDRV_PCM_RATE_8000_96000,
 763                .formats = ADAU1761_FORMATS,
 764        },
 765        .capture = {
 766                .stream_name = "Capture",
 767                .channels_min = 2,
 768                .channels_max = 8,
 769                .rates = SNDRV_PCM_RATE_8000_96000,
 770                .formats = ADAU1761_FORMATS,
 771        },
 772        .ops = &adau17x1_dai_ops,
 773};
 774
 775int adau1761_probe(struct device *dev, struct regmap *regmap,
 776        enum adau17x1_type type, void (*switch_mode)(struct device *dev))
 777{
 778        struct snd_soc_dai_driver *dai_drv;
 779        const char *firmware_name;
 780        int ret;
 781
 782        if (type == ADAU1361) {
 783                dai_drv = &adau1361_dai_driver;
 784                firmware_name = NULL;
 785        } else {
 786                dai_drv = &adau1761_dai_driver;
 787                firmware_name = ADAU1761_FIRMWARE;
 788        }
 789
 790        ret = adau17x1_probe(dev, regmap, type, switch_mode, firmware_name);
 791        if (ret)
 792                return ret;
 793
 794        /* Enable cache only mode as we could miss writes before bias level
 795         * reaches standby and the core clock is enabled */
 796        regcache_cache_only(regmap, true);
 797
 798        return devm_snd_soc_register_component(dev, &adau1761_component_driver,
 799                                               dai_drv, 1);
 800}
 801EXPORT_SYMBOL_GPL(adau1761_probe);
 802
 803const struct regmap_config adau1761_regmap_config = {
 804        .val_bits = 8,
 805        .reg_bits = 16,
 806        .max_register = 0x40fa,
 807        .reg_defaults = adau1761_reg_defaults,
 808        .num_reg_defaults = ARRAY_SIZE(adau1761_reg_defaults),
 809        .readable_reg = adau1761_readable_register,
 810        .volatile_reg = adau17x1_volatile_register,
 811        .precious_reg = adau17x1_precious_register,
 812        .cache_type = REGCACHE_RBTREE,
 813};
 814EXPORT_SYMBOL_GPL(adau1761_regmap_config);
 815
 816MODULE_DESCRIPTION("ASoC ADAU1361/ADAU1461/ADAU1761/ADAU1961 CODEC driver");
 817MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 818MODULE_LICENSE("GPL");
 819