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