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_codec *codec = snd_soc_dapm_to_codec(w->dapm);
 259        struct adau *adau = snd_soc_codec_get_drvdata(codec);
 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_codec *codec,
 449                                 enum snd_soc_bias_level level)
 450{
 451        struct adau *adau = snd_soc_codec_get_drvdata(codec);
 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_codec_get_bias_level(codec) == 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_codec *codec)
 478{
 479        struct adau1761_platform_data *pdata = codec->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_codec *codec)
 488{
 489        struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 490        struct adau1761_platform_data *pdata = codec->dev->platform_data;
 491        struct adau *adau = snd_soc_codec_get_drvdata(codec);
 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_codec_controls(codec,
 517                        adau1761_jack_detect_controls,
 518                        ARRAY_SIZE(adau1761_jack_detect_controls));
 519                if (ret)
 520                        return ret;
 521        case ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE: /* fallthrough */
 522                ret = snd_soc_dapm_add_routes(dapm, adau1761_no_dmic_routes,
 523                        ARRAY_SIZE(adau1761_no_dmic_routes));
 524                if (ret)
 525                        return ret;
 526                break;
 527        case ADAU1761_DIGMIC_JACKDET_PIN_MODE_DIGMIC:
 528                ret = snd_soc_dapm_new_controls(dapm, adau1761_dmic_widgets,
 529                        ARRAY_SIZE(adau1761_dmic_widgets));
 530                if (ret)
 531                        return ret;
 532
 533                ret = snd_soc_dapm_add_routes(dapm, adau1761_dmic_routes,
 534                        ARRAY_SIZE(adau1761_dmic_routes));
 535                if (ret)
 536                        return ret;
 537
 538                val |= ADAU1761_DIGMIC_JACKDETECT_DIGMIC;
 539                break;
 540        default:
 541                return -EINVAL;
 542        }
 543
 544        regmap_write(adau->regmap, ADAU1761_DIGMIC_JACKDETECT, val);
 545
 546        return 0;
 547}
 548
 549static int adau1761_setup_headphone_mode(struct snd_soc_codec *codec)
 550{
 551        struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 552        struct adau *adau = snd_soc_codec_get_drvdata(codec);
 553        struct adau1761_platform_data *pdata = codec->dev->platform_data;
 554        enum adau1761_output_mode mode;
 555        int ret;
 556
 557        if (pdata)
 558                mode = pdata->headphone_mode;
 559        else
 560                mode = ADAU1761_OUTPUT_MODE_HEADPHONE;
 561
 562        switch (mode) {
 563        case ADAU1761_OUTPUT_MODE_LINE:
 564                break;
 565        case ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS:
 566                regmap_update_bits(adau->regmap, ADAU1761_PLAY_MONO_OUTPUT_VOL,
 567                        ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP |
 568                        ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE,
 569                        ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP |
 570                        ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE);
 571                /* fallthrough */
 572        case ADAU1761_OUTPUT_MODE_HEADPHONE:
 573                regmap_update_bits(adau->regmap, ADAU1761_PLAY_HP_RIGHT_VOL,
 574                        ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP,
 575                        ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP);
 576                break;
 577        default:
 578                return -EINVAL;
 579        }
 580
 581        if (mode == ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS) {
 582                ret = snd_soc_dapm_new_controls(dapm,
 583                        adau1761_capless_dapm_widgets,
 584                        ARRAY_SIZE(adau1761_capless_dapm_widgets));
 585                if (ret)
 586                        return ret;
 587                ret = snd_soc_dapm_add_routes(dapm,
 588                        adau1761_capless_dapm_routes,
 589                        ARRAY_SIZE(adau1761_capless_dapm_routes));
 590        } else {
 591                ret = snd_soc_add_codec_controls(codec, adau1761_mono_controls,
 592                        ARRAY_SIZE(adau1761_mono_controls));
 593                if (ret)
 594                        return ret;
 595                ret = snd_soc_dapm_new_controls(dapm,
 596                        adau1761_mono_dapm_widgets,
 597                        ARRAY_SIZE(adau1761_mono_dapm_widgets));
 598                if (ret)
 599                        return ret;
 600                ret = snd_soc_dapm_add_routes(dapm,
 601                        adau1761_mono_dapm_routes,
 602                        ARRAY_SIZE(adau1761_mono_dapm_routes));
 603        }
 604
 605        return ret;
 606}
 607
 608static bool adau1761_readable_register(struct device *dev, unsigned int reg)
 609{
 610        switch (reg) {
 611        case ADAU1761_DIGMIC_JACKDETECT:
 612        case ADAU1761_REC_MIXER_LEFT0:
 613        case ADAU1761_REC_MIXER_LEFT1:
 614        case ADAU1761_REC_MIXER_RIGHT0:
 615        case ADAU1761_REC_MIXER_RIGHT1:
 616        case ADAU1761_LEFT_DIFF_INPUT_VOL:
 617        case ADAU1761_RIGHT_DIFF_INPUT_VOL:
 618        case ADAU1761_PLAY_LR_MIXER_LEFT:
 619        case ADAU1761_PLAY_MIXER_LEFT0:
 620        case ADAU1761_PLAY_MIXER_LEFT1:
 621        case ADAU1761_PLAY_MIXER_RIGHT0:
 622        case ADAU1761_PLAY_MIXER_RIGHT1:
 623        case ADAU1761_PLAY_LR_MIXER_RIGHT:
 624        case ADAU1761_PLAY_MIXER_MONO:
 625        case ADAU1761_PLAY_HP_LEFT_VOL:
 626        case ADAU1761_PLAY_HP_RIGHT_VOL:
 627        case ADAU1761_PLAY_LINE_LEFT_VOL:
 628        case ADAU1761_PLAY_LINE_RIGHT_VOL:
 629        case ADAU1761_PLAY_MONO_OUTPUT_VOL:
 630        case ADAU1761_POP_CLICK_SUPPRESS:
 631        case ADAU1761_JACK_DETECT_PIN:
 632        case ADAU1761_DEJITTER:
 633        case ADAU1761_CLK_ENABLE0:
 634        case ADAU1761_CLK_ENABLE1:
 635                return true;
 636        default:
 637                break;
 638        }
 639
 640        return adau17x1_readable_register(dev, reg);
 641}
 642
 643static int adau1761_codec_probe(struct snd_soc_codec *codec)
 644{
 645        struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
 646        struct adau1761_platform_data *pdata = codec->dev->platform_data;
 647        struct adau *adau = snd_soc_codec_get_drvdata(codec);
 648        int ret;
 649
 650        ret = adau17x1_add_widgets(codec);
 651        if (ret < 0)
 652                return ret;
 653
 654        if (pdata && pdata->input_differential) {
 655                regmap_update_bits(adau->regmap, ADAU1761_LEFT_DIFF_INPUT_VOL,
 656                        ADAU1761_DIFF_INPUT_VOL_LDEN,
 657                        ADAU1761_DIFF_INPUT_VOL_LDEN);
 658                regmap_update_bits(adau->regmap, ADAU1761_RIGHT_DIFF_INPUT_VOL,
 659                        ADAU1761_DIFF_INPUT_VOL_LDEN,
 660                        ADAU1761_DIFF_INPUT_VOL_LDEN);
 661                ret = snd_soc_add_codec_controls(codec,
 662                        adau1761_differential_mode_controls,
 663                        ARRAY_SIZE(adau1761_differential_mode_controls));
 664                if (ret)
 665                        return ret;
 666        } else {
 667                ret = snd_soc_add_codec_controls(codec,
 668                        adau1761_single_mode_controls,
 669                        ARRAY_SIZE(adau1761_single_mode_controls));
 670                if (ret)
 671                        return ret;
 672        }
 673
 674        switch (adau1761_get_lineout_mode(codec)) {
 675        case ADAU1761_OUTPUT_MODE_LINE:
 676                break;
 677        case ADAU1761_OUTPUT_MODE_HEADPHONE:
 678                regmap_update_bits(adau->regmap, ADAU1761_PLAY_LINE_LEFT_VOL,
 679                        ADAU1761_PLAY_LINE_LEFT_VOL_MODE_HP,
 680                        ADAU1761_PLAY_LINE_LEFT_VOL_MODE_HP);
 681                regmap_update_bits(adau->regmap, ADAU1761_PLAY_LINE_RIGHT_VOL,
 682                        ADAU1761_PLAY_LINE_RIGHT_VOL_MODE_HP,
 683                        ADAU1761_PLAY_LINE_RIGHT_VOL_MODE_HP);
 684                break;
 685        default:
 686                return -EINVAL;
 687        }
 688
 689        ret = adau1761_setup_headphone_mode(codec);
 690        if (ret)
 691                return ret;
 692
 693        ret = adau1761_setup_digmic_jackdetect(codec);
 694        if (ret)
 695                return ret;
 696
 697        if (adau->type == ADAU1761) {
 698                ret = snd_soc_dapm_new_controls(dapm, adau1761_dapm_widgets,
 699                        ARRAY_SIZE(adau1761_dapm_widgets));
 700                if (ret)
 701                        return ret;
 702
 703                ret = snd_soc_dapm_add_routes(dapm, adau1761_dapm_routes,
 704                        ARRAY_SIZE(adau1761_dapm_routes));
 705                if (ret)
 706                        return ret;
 707        }
 708
 709        ret = adau17x1_add_routes(codec);
 710        if (ret < 0)
 711                return ret;
 712
 713        return 0;
 714}
 715
 716static const struct snd_soc_codec_driver adau1761_codec_driver = {
 717        .probe = adau1761_codec_probe,
 718        .resume = adau17x1_resume,
 719        .set_bias_level = adau1761_set_bias_level,
 720        .suspend_bias_off = true,
 721
 722        .controls = adau1761_controls,
 723        .num_controls = ARRAY_SIZE(adau1761_controls),
 724        .dapm_widgets = adau1x61_dapm_widgets,
 725        .num_dapm_widgets = ARRAY_SIZE(adau1x61_dapm_widgets),
 726        .dapm_routes = adau1x61_dapm_routes,
 727        .num_dapm_routes = ARRAY_SIZE(adau1x61_dapm_routes),
 728};
 729
 730#define ADAU1761_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
 731        SNDRV_PCM_FMTBIT_S32_LE)
 732
 733static struct snd_soc_dai_driver adau1361_dai_driver = {
 734        .name = "adau-hifi",
 735        .playback = {
 736                .stream_name = "Playback",
 737                .channels_min = 2,
 738                .channels_max = 4,
 739                .rates = SNDRV_PCM_RATE_8000_96000,
 740                .formats = ADAU1761_FORMATS,
 741        },
 742        .capture = {
 743                .stream_name = "Capture",
 744                .channels_min = 2,
 745                .channels_max = 4,
 746                .rates = SNDRV_PCM_RATE_8000_96000,
 747                .formats = ADAU1761_FORMATS,
 748        },
 749        .ops = &adau17x1_dai_ops,
 750};
 751
 752static struct snd_soc_dai_driver adau1761_dai_driver = {
 753        .name = "adau-hifi",
 754        .playback = {
 755                .stream_name = "Playback",
 756                .channels_min = 2,
 757                .channels_max = 8,
 758                .rates = SNDRV_PCM_RATE_8000_96000,
 759                .formats = ADAU1761_FORMATS,
 760        },
 761        .capture = {
 762                .stream_name = "Capture",
 763                .channels_min = 2,
 764                .channels_max = 8,
 765                .rates = SNDRV_PCM_RATE_8000_96000,
 766                .formats = ADAU1761_FORMATS,
 767        },
 768        .ops = &adau17x1_dai_ops,
 769};
 770
 771int adau1761_probe(struct device *dev, struct regmap *regmap,
 772        enum adau17x1_type type, void (*switch_mode)(struct device *dev))
 773{
 774        struct snd_soc_dai_driver *dai_drv;
 775        const char *firmware_name;
 776        int ret;
 777
 778        if (type == ADAU1361) {
 779                dai_drv = &adau1361_dai_driver;
 780                firmware_name = NULL;
 781        } else {
 782                dai_drv = &adau1761_dai_driver;
 783                firmware_name = ADAU1761_FIRMWARE;
 784        }
 785
 786        ret = adau17x1_probe(dev, regmap, type, switch_mode, firmware_name);
 787        if (ret)
 788                return ret;
 789
 790        /* Enable cache only mode as we could miss writes before bias level
 791         * reaches standby and the core clock is enabled */
 792        regcache_cache_only(regmap, true);
 793
 794        return snd_soc_register_codec(dev, &adau1761_codec_driver, dai_drv, 1);
 795}
 796EXPORT_SYMBOL_GPL(adau1761_probe);
 797
 798const struct regmap_config adau1761_regmap_config = {
 799        .val_bits = 8,
 800        .reg_bits = 16,
 801        .max_register = 0x40fa,
 802        .reg_defaults = adau1761_reg_defaults,
 803        .num_reg_defaults = ARRAY_SIZE(adau1761_reg_defaults),
 804        .readable_reg = adau1761_readable_register,
 805        .volatile_reg = adau17x1_volatile_register,
 806        .precious_reg = adau17x1_precious_register,
 807        .cache_type = REGCACHE_RBTREE,
 808};
 809EXPORT_SYMBOL_GPL(adau1761_regmap_config);
 810
 811MODULE_DESCRIPTION("ASoC ADAU1361/ADAU1461/ADAU1761/ADAU1961 CODEC driver");
 812MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 813MODULE_LICENSE("GPL");
 814