root/sound/soc/codecs/adau1761.c

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

DEFINITIONS

This source file includes following definitions.
  1. adau1761_dejitter_fixup
  2. adau1761_set_bias_level
  3. adau1761_get_lineout_mode
  4. adau1761_setup_digmic_jackdetect
  5. adau1761_setup_headphone_mode
  6. adau1761_readable_register
  7. adau1761_component_probe
  8. adau1761_probe

   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 
  66 static 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 
 117 static const DECLARE_TLV_DB_SCALE(adau1761_sing_in_tlv, -1500, 300, 1);
 118 static const DECLARE_TLV_DB_SCALE(adau1761_diff_in_tlv, -1200, 75, 0);
 119 static const DECLARE_TLV_DB_SCALE(adau1761_out_tlv, -5700, 100, 0);
 120 static const DECLARE_TLV_DB_SCALE(adau1761_sidetone_tlv, -1800, 300, 1);
 121 static const DECLARE_TLV_DB_SCALE(adau1761_boost_tlv, -600, 600, 1);
 122 static const DECLARE_TLV_DB_SCALE(adau1761_pga_boost_tlv, -2000, 2000, 1);
 123 
 124 static const unsigned int adau1761_bias_select_values[] = {
 125         0, 2, 3,
 126 };
 127 
 128 static const char * const adau1761_bias_select_text[] = {
 129         "Normal operation", "Enhanced performance", "Power saving",
 130 };
 131 
 132 static const char * const adau1761_bias_select_extreme_text[] = {
 133         "Normal operation", "Extreme power saving", "Enhanced performance",
 134         "Power saving",
 135 };
 136 
 137 static SOC_ENUM_SINGLE_DECL(adau1761_adc_bias_enum,
 138                 ADAU17X1_REC_POWER_MGMT, 3, adau1761_bias_select_extreme_text);
 139 static SOC_ENUM_SINGLE_DECL(adau1761_hp_bias_enum,
 140                 ADAU17X1_PLAY_POWER_MGMT, 6, adau1761_bias_select_extreme_text);
 141 static SOC_ENUM_SINGLE_DECL(adau1761_dac_bias_enum,
 142                 ADAU17X1_PLAY_POWER_MGMT, 4, adau1761_bias_select_extreme_text);
 143 static 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);
 146 static 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 
 150 static 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 
 155 static 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 
 166 static 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 
 177 static 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 
 197 static 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 
 204 static 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 
 217 static 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 
 230 static 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 
 237 static 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 
 244 static const char * const adau1761_input_mux_text[] = {
 245         "ADC", "DMIC",
 246 };
 247 
 248 static SOC_ENUM_SINGLE_DECL(adau1761_input_mux_enum,
 249         ADAU17X1_ADC_CONTROL, 2, adau1761_input_mux_text);
 250 
 251 static const struct snd_kcontrol_new adau1761_input_mux_control =
 252         SOC_DAPM_ENUM("Input Select", adau1761_input_mux_enum);
 253 
 254 static 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 
 269 static 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 
 304 static 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 
 311 static 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 
 316 static 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 
 359 static 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 
 366 static const struct snd_soc_dapm_route adau1761_capless_dapm_routes[] = {
 367         { "Headphone", NULL, "Headphone VGND" },
 368 };
 369 
 370 static 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 
 379 static 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 
 389 static 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 
 394 static 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 
 416 static 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 
 447 static 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 
 475 static 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 
 486 static 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 
 549 static 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 
 608 static 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 
 643 static 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 
 716 static 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 
 736 static 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 
 755 static 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 
 774 int 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 }
 800 EXPORT_SYMBOL_GPL(adau1761_probe);
 801 
 802 const 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 };
 813 EXPORT_SYMBOL_GPL(adau1761_regmap_config);
 814 
 815 MODULE_DESCRIPTION("ASoC ADAU1361/ADAU1461/ADAU1761/ADAU1961 CODEC driver");
 816 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 817 MODULE_LICENSE("GPL");

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