File Index
Files and directories
Sign in
FILE

adau1761.c

File preview with syntax highlighting.

linux-6.19.14/sound/soc/codecs/adau1761.c C
   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_ALC_CTRL0		0x4011
  32#define ADAU1761_ALC_CTRL1		0x4012
  33#define ADAU1761_ALC_CTRL2		0x4013
  34#define ADAU1761_ALC_CTRL3		0x4014
  35#define ADAU1761_PLAY_LR_MIXER_LEFT	0x4020
  36#define ADAU1761_PLAY_MIXER_LEFT0	0x401c
  37#define ADAU1761_PLAY_MIXER_LEFT1	0x401d
  38#define ADAU1761_PLAY_MIXER_RIGHT0	0x401e
  39#define ADAU1761_PLAY_MIXER_RIGHT1	0x401f
  40#define ADAU1761_PLAY_LR_MIXER_RIGHT	0x4021
  41#define ADAU1761_PLAY_MIXER_MONO	0x4022
  42#define ADAU1761_PLAY_HP_LEFT_VOL	0x4023
  43#define ADAU1761_PLAY_HP_RIGHT_VOL	0x4024
  44#define ADAU1761_PLAY_LINE_LEFT_VOL	0x4025
  45#define ADAU1761_PLAY_LINE_RIGHT_VOL	0x4026
  46#define ADAU1761_PLAY_MONO_OUTPUT_VOL	0x4027
  47#define ADAU1761_POP_CLICK_SUPPRESS	0x4028
  48#define ADAU1761_JACK_DETECT_PIN	0x4031
  49#define ADAU1761_DEJITTER		0x4036
  50#define ADAU1761_CLK_ENABLE0		0x40f9
  51#define ADAU1761_CLK_ENABLE1		0x40fa
  52
  53#define ADAU1761_DIGMIC_JACKDETECT_ACTIVE_LOW	BIT(0)
  54#define ADAU1761_DIGMIC_JACKDETECT_DIGMIC	BIT(5)
  55
  56#define ADAU1761_DIFF_INPUT_VOL_LDEN		BIT(0)
  57
  58#define ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP	BIT(0)
  59#define ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE	BIT(1)
  60
  61#define ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP	BIT(0)
  62
  63#define ADAU1761_PLAY_LINE_LEFT_VOL_MODE_HP	BIT(0)
  64
  65#define ADAU1761_PLAY_LINE_RIGHT_VOL_MODE_HP	BIT(0)
  66
  67
  68#define ADAU1761_FIRMWARE "adau1761.bin"
  69
  70static const struct reg_default adau1761_reg_defaults[] = {
  71	{ ADAU1761_DEJITTER,			0x03 },
  72	{ ADAU1761_DIGMIC_JACKDETECT,		0x00 },
  73	{ ADAU1761_REC_MIXER_LEFT0,		0x00 },
  74	{ ADAU1761_REC_MIXER_LEFT1,		0x00 },
  75	{ ADAU1761_REC_MIXER_RIGHT0,		0x00 },
  76	{ ADAU1761_REC_MIXER_RIGHT1,		0x00 },
  77	{ ADAU1761_LEFT_DIFF_INPUT_VOL,		0x00 },
  78	{ ADAU1761_ALC_CTRL0,			0x00 },
  79	{ ADAU1761_ALC_CTRL1,			0x00 },
  80	{ ADAU1761_ALC_CTRL2,			0x00 },
  81	{ ADAU1761_ALC_CTRL3,			0x00 },
  82	{ ADAU1761_RIGHT_DIFF_INPUT_VOL,	0x00 },
  83	{ ADAU1761_PLAY_LR_MIXER_LEFT,		0x00 },
  84	{ ADAU1761_PLAY_MIXER_LEFT0,		0x00 },
  85	{ ADAU1761_PLAY_MIXER_LEFT1,		0x00 },
  86	{ ADAU1761_PLAY_MIXER_RIGHT0,		0x00 },
  87	{ ADAU1761_PLAY_MIXER_RIGHT1,		0x00 },
  88	{ ADAU1761_PLAY_LR_MIXER_RIGHT,		0x00 },
  89	{ ADAU1761_PLAY_MIXER_MONO,		0x00 },
  90	{ ADAU1761_PLAY_HP_LEFT_VOL,		0x00 },
  91	{ ADAU1761_PLAY_HP_RIGHT_VOL,		0x00 },
  92	{ ADAU1761_PLAY_LINE_LEFT_VOL,		0x00 },
  93	{ ADAU1761_PLAY_LINE_RIGHT_VOL,		0x00 },
  94	{ ADAU1761_PLAY_MONO_OUTPUT_VOL,	0x00 },
  95	{ ADAU1761_POP_CLICK_SUPPRESS,		0x00 },
  96	{ ADAU1761_JACK_DETECT_PIN,		0x00 },
  97	{ ADAU1761_CLK_ENABLE0,			0x00 },
  98	{ ADAU1761_CLK_ENABLE1,			0x00 },
  99	{ ADAU17X1_CLOCK_CONTROL,		0x00 },
 100	{ ADAU17X1_PLL_CONTROL,			0x00 },
 101	{ ADAU17X1_REC_POWER_MGMT,		0x00 },
 102	{ ADAU17X1_MICBIAS,			0x00 },
 103	{ ADAU17X1_SERIAL_PORT0,		0x00 },
 104	{ ADAU17X1_SERIAL_PORT1,		0x00 },
 105	{ ADAU17X1_CONVERTER0,			0x00 },
 106	{ ADAU17X1_CONVERTER1,			0x00 },
 107	{ ADAU17X1_LEFT_INPUT_DIGITAL_VOL,	0x00 },
 108	{ ADAU17X1_RIGHT_INPUT_DIGITAL_VOL,	0x00 },
 109	{ ADAU17X1_ADC_CONTROL,			0x00 },
 110	{ ADAU17X1_PLAY_POWER_MGMT,		0x00 },
 111	{ ADAU17X1_DAC_CONTROL0,		0x00 },
 112	{ ADAU17X1_DAC_CONTROL1,		0x00 },
 113	{ ADAU17X1_DAC_CONTROL2,		0x00 },
 114	{ ADAU17X1_SERIAL_PORT_PAD,		0xaa },
 115	{ ADAU17X1_CONTROL_PORT_PAD0,		0xaa },
 116	{ ADAU17X1_CONTROL_PORT_PAD1,		0x00 },
 117	{ ADAU17X1_DSP_SAMPLING_RATE,		0x01 },
 118	{ ADAU17X1_SERIAL_INPUT_ROUTE,		0x00 },
 119	{ ADAU17X1_SERIAL_OUTPUT_ROUTE,		0x00 },
 120	{ ADAU17X1_DSP_ENABLE,			0x00 },
 121	{ ADAU17X1_DSP_RUN,			0x00 },
 122	{ ADAU17X1_SERIAL_SAMPLING_RATE,	0x00 },
 123};
 124
 125static const DECLARE_TLV_DB_SCALE(adau1761_sing_in_tlv, -1500, 300, 1);
 126static const DECLARE_TLV_DB_SCALE(adau1761_diff_in_tlv, -1200, 75, 0);
 127static const DECLARE_TLV_DB_SCALE(adau1761_out_tlv, -5700, 100, 0);
 128static const DECLARE_TLV_DB_SCALE(adau1761_sidetone_tlv, -1800, 300, 1);
 129static const DECLARE_TLV_DB_SCALE(adau1761_boost_tlv, -600, 600, 1);
 130static const DECLARE_TLV_DB_SCALE(adau1761_pga_boost_tlv, -2000, 2000, 1);
 131
 132static const DECLARE_TLV_DB_SCALE(adau1761_alc_max_gain_tlv, -1200, 600, 0);
 133static const DECLARE_TLV_DB_SCALE(adau1761_alc_target_tlv, -2850, 150, 0);
 134static const DECLARE_TLV_DB_SCALE(adau1761_alc_ng_threshold_tlv, -7650, 150, 0);
 135
 136static const unsigned int adau1761_bias_select_values[] = {
 137	0, 2, 3,
 138};
 139
 140static const char * const adau1761_bias_select_text[] = {
 141	"Normal operation", "Enhanced performance", "Power saving",
 142};
 143
 144static const char * const adau1761_bias_select_extreme_text[] = {
 145	"Normal operation", "Extreme power saving", "Enhanced performance",
 146	"Power saving",
 147};
 148
 149static SOC_ENUM_SINGLE_DECL(adau1761_adc_bias_enum,
 150		ADAU17X1_REC_POWER_MGMT, 3, adau1761_bias_select_extreme_text);
 151static SOC_ENUM_SINGLE_DECL(adau1761_hp_bias_enum,
 152		ADAU17X1_PLAY_POWER_MGMT, 6, adau1761_bias_select_extreme_text);
 153static SOC_ENUM_SINGLE_DECL(adau1761_dac_bias_enum,
 154		ADAU17X1_PLAY_POWER_MGMT, 4, adau1761_bias_select_extreme_text);
 155static SOC_VALUE_ENUM_SINGLE_DECL(adau1761_playback_bias_enum,
 156		ADAU17X1_PLAY_POWER_MGMT, 2, 0x3, adau1761_bias_select_text,
 157		adau1761_bias_select_values);
 158static SOC_VALUE_ENUM_SINGLE_DECL(adau1761_capture_bias_enum,
 159		ADAU17X1_REC_POWER_MGMT, 1, 0x3, adau1761_bias_select_text,
 160		adau1761_bias_select_values);
 161
 162static const unsigned int adau1761_pga_slew_time_values[] = {
 163	3, 0, 1, 2,
 164};
 165
 166static const char * const adau1761_pga_slew_time_text[] = {
 167	"Off",
 168	"24 ms",
 169	"48 ms",
 170	"96 ms",
 171};
 172
 173static const char * const adau1761_alc_function_text[] = {
 174	"Off",
 175	"Right",
 176	"Left",
 177	"Stereo",
 178	"DSP control",
 179};
 180
 181static const char * const adau1761_alc_hold_time_text[] = {
 182	"2.67 ms",
 183	"5.34 ms",
 184	"10.68 ms",
 185	"21.36 ms",
 186	"42.72 ms",
 187	"85.44 ms",
 188	"170.88 ms",
 189	"341.76 ms",
 190	"683.52 ms",
 191	"1367 ms",
 192	"2734.1 ms",
 193	"5468.2 ms",
 194	"10936 ms",
 195	"21873 ms",
 196	"43745 ms",
 197	"87491 ms",
 198};
 199
 200static const char * const adau1761_alc_attack_time_text[] = {
 201	"6 ms",
 202	"12 ms",
 203	"24 ms",
 204	"48 ms",
 205	"96 ms",
 206	"192 ms",
 207	"384 ms",
 208	"768 ms",
 209	"1540 ms",
 210	"3070 ms",
 211	"6140 ms",
 212	"12290 ms",
 213	"24580 ms",
 214	"49150 ms",
 215	"98300 ms",
 216	"196610 ms",
 217};
 218
 219static const char * const adau1761_alc_decay_time_text[] = {
 220	"24 ms",
 221	"48 ms",
 222	"96 ms",
 223	"192 ms",
 224	"384 ms",
 225	"768 ms",
 226	"15400 ms",
 227	"30700 ms",
 228	"61400 ms",
 229	"12290 ms",
 230	"24580 ms",
 231	"49150 ms",
 232	"98300 ms",
 233	"196610 ms",
 234	"393220 ms",
 235	"786430 ms",
 236};
 237
 238static const char * const adau1761_alc_ng_type_text[] = {
 239	"Hold",
 240	"Mute",
 241	"Fade",
 242	"Fade + Mute",
 243};
 244
 245static SOC_VALUE_ENUM_SINGLE_DECL(adau1761_pga_slew_time_enum,
 246		ADAU1761_ALC_CTRL0, 6, 0x3, adau1761_pga_slew_time_text,
 247		adau1761_pga_slew_time_values);
 248static SOC_ENUM_SINGLE_DECL(adau1761_alc_function_enum,
 249		ADAU1761_ALC_CTRL0, 0, adau1761_alc_function_text);
 250static SOC_ENUM_SINGLE_DECL(adau1761_alc_hold_time_enum,
 251		ADAU1761_ALC_CTRL1, 4, adau1761_alc_hold_time_text);
 252static SOC_ENUM_SINGLE_DECL(adau1761_alc_attack_time_enum,
 253		ADAU1761_ALC_CTRL2, 4, adau1761_alc_attack_time_text);
 254static SOC_ENUM_SINGLE_DECL(adau1761_alc_decay_time_enum,
 255		ADAU1761_ALC_CTRL2, 0, adau1761_alc_decay_time_text);
 256static SOC_ENUM_SINGLE_DECL(adau1761_alc_ng_type_enum,
 257		ADAU1761_ALC_CTRL3, 6, adau1761_alc_ng_type_text);
 258
 259static const struct snd_kcontrol_new adau1761_jack_detect_controls[] = {
 260	SOC_SINGLE("Speaker Auto-mute Switch", ADAU1761_DIGMIC_JACKDETECT,
 261		4, 1, 0),
 262};
 263
 264static const struct snd_kcontrol_new adau1761_differential_mode_controls[] = {
 265	SOC_DOUBLE_R_TLV("Capture Volume", ADAU1761_LEFT_DIFF_INPUT_VOL,
 266		ADAU1761_RIGHT_DIFF_INPUT_VOL, 2, 0x3f, 0,
 267		adau1761_diff_in_tlv),
 268	SOC_DOUBLE_R("Capture Switch", ADAU1761_LEFT_DIFF_INPUT_VOL,
 269		ADAU1761_RIGHT_DIFF_INPUT_VOL, 1, 1, 0),
 270
 271	SOC_DOUBLE_R_TLV("PGA Boost Capture Volume", ADAU1761_REC_MIXER_LEFT1,
 272		ADAU1761_REC_MIXER_RIGHT1, 3, 2, 0, adau1761_pga_boost_tlv),
 273
 274	SOC_ENUM("PGA Capture Slew Time", adau1761_pga_slew_time_enum),
 275
 276	SOC_SINGLE_TLV("ALC Capture Max Gain Volume", ADAU1761_ALC_CTRL0,
 277		3, 7, 0, adau1761_alc_max_gain_tlv),
 278	SOC_ENUM("ALC Capture Function", adau1761_alc_function_enum),
 279	SOC_ENUM("ALC Capture Hold Time", adau1761_alc_hold_time_enum),
 280	SOC_SINGLE_TLV("ALC Capture Target Volume", ADAU1761_ALC_CTRL1,
 281		0, 15, 0, adau1761_alc_target_tlv),
 282	SOC_ENUM("ALC Capture Attack Time", adau1761_alc_decay_time_enum),
 283	SOC_ENUM("ALC Capture Decay Time", adau1761_alc_attack_time_enum),
 284	SOC_ENUM("ALC Capture Noise Gate Type", adau1761_alc_ng_type_enum),
 285	SOC_SINGLE("ALC Capture Noise Gate Switch",
 286		ADAU1761_ALC_CTRL3, 5, 1, 0),
 287	SOC_SINGLE_TLV("ALC Capture Noise Gate Threshold Volume",
 288		ADAU1761_ALC_CTRL3, 0, 31, 0, adau1761_alc_ng_threshold_tlv),
 289};
 290
 291static const struct snd_kcontrol_new adau1761_single_mode_controls[] = {
 292	SOC_SINGLE_TLV("Input 1 Capture Volume", ADAU1761_REC_MIXER_LEFT0,
 293		4, 7, 0, adau1761_sing_in_tlv),
 294	SOC_SINGLE_TLV("Input 2 Capture Volume", ADAU1761_REC_MIXER_LEFT0,
 295		1, 7, 0, adau1761_sing_in_tlv),
 296	SOC_SINGLE_TLV("Input 3 Capture Volume", ADAU1761_REC_MIXER_RIGHT0,
 297		4, 7, 0, adau1761_sing_in_tlv),
 298	SOC_SINGLE_TLV("Input 4 Capture Volume", ADAU1761_REC_MIXER_RIGHT0,
 299		1, 7, 0, adau1761_sing_in_tlv),
 300};
 301
 302static const struct snd_kcontrol_new adau1761_controls[] = {
 303	SOC_DOUBLE_R_TLV("Aux Capture Volume", ADAU1761_REC_MIXER_LEFT1,
 304		ADAU1761_REC_MIXER_RIGHT1, 0, 7, 0, adau1761_sing_in_tlv),
 305
 306	SOC_DOUBLE_R_TLV("Headphone Playback Volume", ADAU1761_PLAY_HP_LEFT_VOL,
 307		ADAU1761_PLAY_HP_RIGHT_VOL, 2, 0x3f, 0, adau1761_out_tlv),
 308	SOC_DOUBLE_R("Headphone Playback Switch", ADAU1761_PLAY_HP_LEFT_VOL,
 309		ADAU1761_PLAY_HP_RIGHT_VOL, 1, 1, 0),
 310	SOC_DOUBLE_R_TLV("Lineout Playback Volume", ADAU1761_PLAY_LINE_LEFT_VOL,
 311		ADAU1761_PLAY_LINE_RIGHT_VOL, 2, 0x3f, 0, adau1761_out_tlv),
 312	SOC_DOUBLE_R("Lineout Playback Switch", ADAU1761_PLAY_LINE_LEFT_VOL,
 313		ADAU1761_PLAY_LINE_RIGHT_VOL, 1, 1, 0),
 314
 315	SOC_ENUM("ADC Bias", adau1761_adc_bias_enum),
 316	SOC_ENUM("DAC Bias", adau1761_dac_bias_enum),
 317	SOC_ENUM("Capture Bias", adau1761_capture_bias_enum),
 318	SOC_ENUM("Playback Bias", adau1761_playback_bias_enum),
 319	SOC_ENUM("Headphone Bias", adau1761_hp_bias_enum),
 320};
 321
 322static const struct snd_kcontrol_new adau1761_mono_controls[] = {
 323	SOC_SINGLE_TLV("Mono Playback Volume", ADAU1761_PLAY_MONO_OUTPUT_VOL,
 324		2, 0x3f, 0, adau1761_out_tlv),
 325	SOC_SINGLE("Mono Playback Switch", ADAU1761_PLAY_MONO_OUTPUT_VOL,
 326		1, 1, 0),
 327};
 328
 329static const struct snd_kcontrol_new adau1761_left_mixer_controls[] = {
 330	SOC_DAPM_SINGLE_AUTODISABLE("Left DAC Switch",
 331		ADAU1761_PLAY_MIXER_LEFT0, 5, 1, 0),
 332	SOC_DAPM_SINGLE_AUTODISABLE("Right DAC Switch",
 333		ADAU1761_PLAY_MIXER_LEFT0, 6, 1, 0),
 334	SOC_DAPM_SINGLE_TLV("Aux Bypass Volume",
 335		ADAU1761_PLAY_MIXER_LEFT0, 1, 8, 0, adau1761_sidetone_tlv),
 336	SOC_DAPM_SINGLE_TLV("Right Bypass Volume",
 337		ADAU1761_PLAY_MIXER_LEFT1, 4, 8, 0, adau1761_sidetone_tlv),
 338	SOC_DAPM_SINGLE_TLV("Left Bypass Volume",
 339		ADAU1761_PLAY_MIXER_LEFT1, 0, 8, 0, adau1761_sidetone_tlv),
 340};
 341
 342static const struct snd_kcontrol_new adau1761_right_mixer_controls[] = {
 343	SOC_DAPM_SINGLE_AUTODISABLE("Left DAC Switch",
 344		ADAU1761_PLAY_MIXER_RIGHT0, 5, 1, 0),
 345	SOC_DAPM_SINGLE_AUTODISABLE("Right DAC Switch",
 346		ADAU1761_PLAY_MIXER_RIGHT0, 6, 1, 0),
 347	SOC_DAPM_SINGLE_TLV("Aux Bypass Volume",
 348		ADAU1761_PLAY_MIXER_RIGHT0, 1, 8, 0, adau1761_sidetone_tlv),
 349	SOC_DAPM_SINGLE_TLV("Right Bypass Volume",
 350		ADAU1761_PLAY_MIXER_RIGHT1, 4, 8, 0, adau1761_sidetone_tlv),
 351	SOC_DAPM_SINGLE_TLV("Left Bypass Volume",
 352		ADAU1761_PLAY_MIXER_RIGHT1, 0, 8, 0, adau1761_sidetone_tlv),
 353};
 354
 355static const struct snd_kcontrol_new adau1761_left_lr_mixer_controls[] = {
 356	SOC_DAPM_SINGLE_TLV("Left Volume",
 357		ADAU1761_PLAY_LR_MIXER_LEFT, 1, 2, 0, adau1761_boost_tlv),
 358	SOC_DAPM_SINGLE_TLV("Right Volume",
 359		ADAU1761_PLAY_LR_MIXER_LEFT, 3, 2, 0, adau1761_boost_tlv),
 360};
 361
 362static const struct snd_kcontrol_new adau1761_right_lr_mixer_controls[] = {
 363	SOC_DAPM_SINGLE_TLV("Left Volume",
 364		ADAU1761_PLAY_LR_MIXER_RIGHT, 1, 2, 0, adau1761_boost_tlv),
 365	SOC_DAPM_SINGLE_TLV("Right Volume",
 366		ADAU1761_PLAY_LR_MIXER_RIGHT, 3, 2, 0, adau1761_boost_tlv),
 367};
 368
 369static const char * const adau1761_input_mux_text[] = {
 370	"ADC", "DMIC",
 371};
 372
 373static SOC_ENUM_SINGLE_DECL(adau1761_input_mux_enum,
 374	ADAU17X1_ADC_CONTROL, 2, adau1761_input_mux_text);
 375
 376static const struct snd_kcontrol_new adau1761_input_mux_control =
 377	SOC_DAPM_ENUM("Input Select", adau1761_input_mux_enum);
 378
 379static int adau1761_dejitter_fixup(struct snd_soc_dapm_widget *w,
 380	struct snd_kcontrol *kcontrol, int event)
 381{
 382	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
 383	struct adau *adau = snd_soc_component_get_drvdata(component);
 384
 385	/* After any power changes have been made the dejitter circuit
 386	 * has to be reinitialized. */
 387	regmap_write(adau->regmap, ADAU1761_DEJITTER, 0);
 388	if (!adau->master)
 389		regmap_write(adau->regmap, ADAU1761_DEJITTER, 3);
 390
 391	return 0;
 392}
 393
 394static const struct snd_soc_dapm_widget adau1x61_dapm_widgets[] = {
 395	SND_SOC_DAPM_MIXER("Left Input Mixer", ADAU1761_REC_MIXER_LEFT0, 0, 0,
 396		NULL, 0),
 397	SND_SOC_DAPM_MIXER("Right Input Mixer", ADAU1761_REC_MIXER_RIGHT0, 0, 0,
 398		NULL, 0),
 399
 400	SOC_MIXER_ARRAY("Left Playback Mixer", ADAU1761_PLAY_MIXER_LEFT0,
 401		0, 0, adau1761_left_mixer_controls),
 402	SOC_MIXER_ARRAY("Right Playback Mixer", ADAU1761_PLAY_MIXER_RIGHT0,
 403		0, 0, adau1761_right_mixer_controls),
 404	SOC_MIXER_ARRAY("Left LR Playback Mixer", ADAU1761_PLAY_LR_MIXER_LEFT,
 405		0, 0, adau1761_left_lr_mixer_controls),
 406	SOC_MIXER_ARRAY("Right LR Playback Mixer", ADAU1761_PLAY_LR_MIXER_RIGHT,
 407		0, 0, adau1761_right_lr_mixer_controls),
 408
 409	SND_SOC_DAPM_SUPPLY("Headphone", ADAU1761_PLAY_HP_LEFT_VOL,
 410		0, 0, NULL, 0),
 411
 412	SND_SOC_DAPM_SUPPLY_S("SYSCLK", 2, SND_SOC_NOPM, 0, 0, NULL, 0),
 413
 414	SND_SOC_DAPM_POST("Dejitter fixup", adau1761_dejitter_fixup),
 415
 416	SND_SOC_DAPM_INPUT("LAUX"),
 417	SND_SOC_DAPM_INPUT("RAUX"),
 418	SND_SOC_DAPM_INPUT("LINP"),
 419	SND_SOC_DAPM_INPUT("LINN"),
 420	SND_SOC_DAPM_INPUT("RINP"),
 421	SND_SOC_DAPM_INPUT("RINN"),
 422
 423	SND_SOC_DAPM_OUTPUT("LOUT"),
 424	SND_SOC_DAPM_OUTPUT("ROUT"),
 425	SND_SOC_DAPM_OUTPUT("LHP"),
 426	SND_SOC_DAPM_OUTPUT("RHP"),
 427};
 428
 429static const struct snd_soc_dapm_widget adau1761_mono_dapm_widgets[] = {
 430	SND_SOC_DAPM_MIXER("Mono Playback Mixer", ADAU1761_PLAY_MIXER_MONO,
 431		0, 0, NULL, 0),
 432
 433	SND_SOC_DAPM_OUTPUT("MONOOUT"),
 434};
 435
 436static const struct snd_soc_dapm_widget adau1761_capless_dapm_widgets[] = {
 437	SND_SOC_DAPM_SUPPLY_S("Headphone VGND", 1, ADAU1761_PLAY_MIXER_MONO,
 438		0, 0, NULL, 0),
 439};
 440
 441static const struct snd_soc_dapm_route adau1x61_dapm_routes[] = {
 442	{ "Left Input Mixer", NULL, "LINP" },
 443	{ "Left Input Mixer", NULL, "LINN" },
 444	{ "Left Input Mixer", NULL, "LAUX" },
 445
 446	{ "Right Input Mixer", NULL, "RINP" },
 447	{ "Right Input Mixer", NULL, "RINN" },
 448	{ "Right Input Mixer", NULL, "RAUX" },
 449
 450	{ "Left Playback Mixer", NULL, "Left Playback Enable"},
 451	{ "Right Playback Mixer", NULL, "Right Playback Enable"},
 452	{ "Left LR Playback Mixer", NULL, "Left Playback Enable"},
 453	{ "Right LR Playback Mixer", NULL, "Right Playback Enable"},
 454
 455	{ "Left Playback Mixer", "Left DAC Switch", "Left DAC" },
 456	{ "Left Playback Mixer", "Right DAC Switch", "Right DAC" },
 457
 458	{ "Right Playback Mixer", "Left DAC Switch", "Left DAC" },
 459	{ "Right Playback Mixer", "Right DAC Switch", "Right DAC" },
 460
 461	{ "Left LR Playback Mixer", "Left Volume", "Left Playback Mixer" },
 462	{ "Left LR Playback Mixer", "Right Volume", "Right Playback Mixer" },
 463
 464	{ "Right LR Playback Mixer", "Left Volume", "Left Playback Mixer" },
 465	{ "Right LR Playback Mixer", "Right Volume", "Right Playback Mixer" },
 466
 467	{ "LHP", NULL, "Left Playback Mixer" },
 468	{ "RHP", NULL, "Right Playback Mixer" },
 469
 470	{ "LHP", NULL, "Headphone" },
 471	{ "RHP", NULL, "Headphone" },
 472
 473	{ "LOUT", NULL, "Left LR Playback Mixer" },
 474	{ "ROUT", NULL, "Right LR Playback Mixer" },
 475
 476	{ "Left Playback Mixer", "Aux Bypass Volume", "LAUX" },
 477	{ "Left Playback Mixer", "Left Bypass Volume", "Left Input Mixer" },
 478	{ "Left Playback Mixer", "Right Bypass Volume", "Right Input Mixer" },
 479	{ "Right Playback Mixer", "Aux Bypass Volume", "RAUX" },
 480	{ "Right Playback Mixer", "Left Bypass Volume", "Left Input Mixer" },
 481	{ "Right Playback Mixer", "Right Bypass Volume", "Right Input Mixer" },
 482};
 483
 484static const struct snd_soc_dapm_route adau1761_mono_dapm_routes[] = {
 485	{ "Mono Playback Mixer", NULL, "Left Playback Mixer" },
 486	{ "Mono Playback Mixer", NULL, "Right Playback Mixer" },
 487
 488	{ "MONOOUT", NULL, "Mono Playback Mixer" },
 489};
 490
 491static const struct snd_soc_dapm_route adau1761_capless_dapm_routes[] = {
 492	{ "Headphone", NULL, "Headphone VGND" },
 493};
 494
 495static const struct snd_soc_dapm_widget adau1761_dmic_widgets[] = {
 496	SND_SOC_DAPM_MUX("Left Decimator Mux", SND_SOC_NOPM, 0, 0,
 497		&adau1761_input_mux_control),
 498	SND_SOC_DAPM_MUX("Right Decimator Mux", SND_SOC_NOPM, 0, 0,
 499		&adau1761_input_mux_control),
 500
 501	SND_SOC_DAPM_INPUT("DMIC"),
 502};
 503
 504static const struct snd_soc_dapm_route adau1761_dmic_routes[] = {
 505	{ "Left Decimator Mux", "ADC", "Left Input Mixer" },
 506	{ "Left Decimator Mux", "DMIC", "DMIC" },
 507	{ "Right Decimator Mux", "ADC", "Right Input Mixer" },
 508	{ "Right Decimator Mux", "DMIC", "DMIC" },
 509
 510	{ "Left Decimator", NULL, "Left Decimator Mux" },
 511	{ "Right Decimator", NULL, "Right Decimator Mux" },
 512};
 513
 514static const struct snd_soc_dapm_route adau1761_no_dmic_routes[] = {
 515	{ "Left Decimator", NULL, "Left Input Mixer" },
 516	{ "Right Decimator", NULL, "Right Input Mixer" },
 517};
 518
 519static const struct snd_soc_dapm_widget adau1761_dapm_widgets[] = {
 520	SND_SOC_DAPM_SUPPLY("Serial Port Clock", ADAU1761_CLK_ENABLE0,
 521		0, 0, NULL, 0),
 522	SND_SOC_DAPM_SUPPLY("Serial Input Routing Clock", ADAU1761_CLK_ENABLE0,
 523		1, 0, NULL, 0),
 524	SND_SOC_DAPM_SUPPLY("Serial Output Routing Clock", ADAU1761_CLK_ENABLE0,
 525		3, 0, NULL, 0),
 526
 527	SND_SOC_DAPM_SUPPLY("Decimator Resync Clock", ADAU1761_CLK_ENABLE0,
 528		4, 0, NULL, 0),
 529	SND_SOC_DAPM_SUPPLY("Interpolator Resync Clock", ADAU1761_CLK_ENABLE0,
 530		2, 0, NULL, 0),
 531
 532	SND_SOC_DAPM_SUPPLY("Slew Clock", ADAU1761_CLK_ENABLE0, 6, 0, NULL, 0),
 533	SND_SOC_DAPM_SUPPLY("ALC Clock", ADAU1761_CLK_ENABLE0, 5, 0, NULL, 0),
 534
 535	SND_SOC_DAPM_SUPPLY_S("Digital Clock 0", 1, ADAU1761_CLK_ENABLE1,
 536		0, 0, NULL, 0),
 537	SND_SOC_DAPM_SUPPLY_S("Digital Clock 1", 1, ADAU1761_CLK_ENABLE1,
 538		1, 0, NULL, 0),
 539};
 540
 541static const struct snd_soc_dapm_route adau1761_dapm_routes[] = {
 542	{ "Left Decimator", NULL, "Digital Clock 0", },
 543	{ "Right Decimator", NULL, "Digital Clock 0", },
 544	{ "Left DAC", NULL, "Digital Clock 0", },
 545	{ "Right DAC", NULL, "Digital Clock 0", },
 546
 547	{ "AIFCLK", NULL, "Digital Clock 1" },
 548
 549	{ "Playback", NULL, "Serial Port Clock" },
 550	{ "Capture", NULL, "Serial Port Clock" },
 551	{ "Playback", NULL, "Serial Input Routing Clock" },
 552	{ "Capture", NULL, "Serial Output Routing Clock" },
 553
 554	{ "Left Decimator", NULL, "Decimator Resync Clock" },
 555	{ "Right Decimator", NULL, "Decimator Resync Clock" },
 556	{ "Left DAC", NULL, "Interpolator Resync Clock" },
 557	{ "Right DAC", NULL, "Interpolator Resync Clock" },
 558
 559	{ "Slew Clock", NULL, "Digital Clock 0" },
 560	{ "Right Playback Mixer", NULL, "Slew Clock" },
 561	{ "Left Playback Mixer", NULL, "Slew Clock" },
 562
 563	{ "Left Input Mixer", NULL, "ALC Clock" },
 564	{ "Right Input Mixer", NULL, "ALC Clock" },
 565
 566	{ "Digital Clock 0", NULL, "SYSCLK" },
 567	{ "Digital Clock 1", NULL, "SYSCLK" },
 568};
 569
 570static const struct snd_soc_dapm_route adau1761_dapm_dsp_routes[] = {
 571	{ "DSP", NULL, "Digital Clock 0" },
 572};
 573
 574static int adau1761_compatibility_probe(struct device *dev)
 575{
 576	struct adau *adau = dev_get_drvdata(dev);
 577	struct regmap *regmap = adau->regmap;
 578	int val, ret = 0;
 579
 580	/* Only consider compatibility mode when ADAU1361 was specified. */
 581	if (adau->type != ADAU1361)
 582		return 0;
 583
 584	regcache_cache_bypass(regmap, true);
 585
 586	/*
 587	 * This will enable the core clock and bypass the PLL,
 588	 * so that we can access the registers for probing purposes
 589	 * (without having to set up the PLL).
 590	 */
 591	regmap_write(regmap, ADAU17X1_CLOCK_CONTROL,
 592		ADAU17X1_CLOCK_CONTROL_SYSCLK_EN);
 593
 594	/*
 595	 * ADAU17X1_SERIAL_SAMPLING_RATE doesn't exist in non-DSP chips;
 596	 * reading it results in zero at all times, and write is a no-op.
 597	 * Use this register to probe for ADAU1761.
 598	 */
 599	regmap_write(regmap, ADAU17X1_SERIAL_SAMPLING_RATE, 1);
 600	ret = regmap_read(regmap, ADAU17X1_SERIAL_SAMPLING_RATE, &val);
 601	if (ret)
 602		goto exit;
 603	if (val != 1)
 604		goto exit;
 605	regmap_write(regmap, ADAU17X1_SERIAL_SAMPLING_RATE, 0);
 606	ret = regmap_read(regmap, ADAU17X1_SERIAL_SAMPLING_RATE, &val);
 607	if (ret)
 608		goto exit;
 609	if (val != 0)
 610		goto exit;
 611
 612	adau->type = ADAU1761_AS_1361;
 613exit:
 614	/* Disable core clock after probing. */
 615	regmap_write(regmap, ADAU17X1_CLOCK_CONTROL, 0);
 616	regcache_cache_bypass(regmap, false);
 617	return ret;
 618}
 619
 620static int adau1761_set_bias_level(struct snd_soc_component *component,
 621				 enum snd_soc_bias_level level)
 622{
 623	struct adau *adau = snd_soc_component_get_drvdata(component);
 624	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
 625
 626	switch (level) {
 627	case SND_SOC_BIAS_ON:
 628		break;
 629	case SND_SOC_BIAS_PREPARE:
 630		break;
 631	case SND_SOC_BIAS_STANDBY:
 632		regcache_cache_only(adau->regmap, false);
 633		regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
 634			ADAU17X1_CLOCK_CONTROL_SYSCLK_EN,
 635			ADAU17X1_CLOCK_CONTROL_SYSCLK_EN);
 636		if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF)
 637			regcache_sync(adau->regmap);
 638		break;
 639	case SND_SOC_BIAS_OFF:
 640		regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,
 641			ADAU17X1_CLOCK_CONTROL_SYSCLK_EN, 0);
 642		regcache_cache_only(adau->regmap, true);
 643		break;
 644
 645	}
 646	return 0;
 647}
 648
 649static enum adau1761_output_mode adau1761_get_lineout_mode(
 650	struct snd_soc_component *component)
 651{
 652	struct adau1761_platform_data *pdata = component->dev->platform_data;
 653
 654	if (pdata)
 655		return pdata->lineout_mode;
 656
 657	return ADAU1761_OUTPUT_MODE_LINE;
 658}
 659
 660static int adau1761_setup_digmic_jackdetect(struct snd_soc_component *component)
 661{
 662	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
 663	struct adau1761_platform_data *pdata = component->dev->platform_data;
 664	struct adau *adau = snd_soc_component_get_drvdata(component);
 665	enum adau1761_digmic_jackdet_pin_mode mode;
 666	unsigned int val = 0;
 667	int ret;
 668
 669	if (pdata)
 670		mode = pdata->digmic_jackdetect_pin_mode;
 671	else
 672		mode = ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE;
 673
 674	switch (mode) {
 675	case ADAU1761_DIGMIC_JACKDET_PIN_MODE_JACKDETECT:
 676		switch (pdata->jackdetect_debounce_time) {
 677		case ADAU1761_JACKDETECT_DEBOUNCE_5MS:
 678		case ADAU1761_JACKDETECT_DEBOUNCE_10MS:
 679		case ADAU1761_JACKDETECT_DEBOUNCE_20MS:
 680		case ADAU1761_JACKDETECT_DEBOUNCE_40MS:
 681			val |= pdata->jackdetect_debounce_time << 6;
 682			break;
 683		default:
 684			return -EINVAL;
 685		}
 686		if (pdata->jackdetect_active_low)
 687			val |= ADAU1761_DIGMIC_JACKDETECT_ACTIVE_LOW;
 688
 689		ret = snd_soc_add_component_controls(component,
 690			adau1761_jack_detect_controls,
 691			ARRAY_SIZE(adau1761_jack_detect_controls));
 692		if (ret)
 693			return ret;
 694		fallthrough;
 695	case ADAU1761_DIGMIC_JACKDET_PIN_MODE_NONE:
 696		ret = snd_soc_dapm_add_routes(dapm, adau1761_no_dmic_routes,
 697			ARRAY_SIZE(adau1761_no_dmic_routes));
 698		if (ret)
 699			return ret;
 700		break;
 701	case ADAU1761_DIGMIC_JACKDET_PIN_MODE_DIGMIC:
 702		ret = snd_soc_dapm_new_controls(dapm, adau1761_dmic_widgets,
 703			ARRAY_SIZE(adau1761_dmic_widgets));
 704		if (ret)
 705			return ret;
 706
 707		ret = snd_soc_dapm_add_routes(dapm, adau1761_dmic_routes,
 708			ARRAY_SIZE(adau1761_dmic_routes));
 709		if (ret)
 710			return ret;
 711
 712		val |= ADAU1761_DIGMIC_JACKDETECT_DIGMIC;
 713		break;
 714	default:
 715		return -EINVAL;
 716	}
 717
 718	regmap_write(adau->regmap, ADAU1761_DIGMIC_JACKDETECT, val);
 719
 720	return 0;
 721}
 722
 723static int adau1761_setup_headphone_mode(struct snd_soc_component *component)
 724{
 725	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
 726	struct adau *adau = snd_soc_component_get_drvdata(component);
 727	struct adau1761_platform_data *pdata = component->dev->platform_data;
 728	enum adau1761_output_mode mode;
 729	int ret;
 730
 731	if (pdata)
 732		mode = pdata->headphone_mode;
 733	else
 734		mode = ADAU1761_OUTPUT_MODE_HEADPHONE;
 735
 736	switch (mode) {
 737	case ADAU1761_OUTPUT_MODE_LINE:
 738		break;
 739	case ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS:
 740		regmap_update_bits(adau->regmap, ADAU1761_PLAY_MONO_OUTPUT_VOL,
 741			ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP |
 742			ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE,
 743			ADAU1761_PLAY_MONO_OUTPUT_VOL_MODE_HP |
 744			ADAU1761_PLAY_MONO_OUTPUT_VOL_UNMUTE);
 745		fallthrough;
 746	case ADAU1761_OUTPUT_MODE_HEADPHONE:
 747		regmap_update_bits(adau->regmap, ADAU1761_PLAY_HP_RIGHT_VOL,
 748			ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP,
 749			ADAU1761_PLAY_HP_RIGHT_VOL_MODE_HP);
 750		break;
 751	default:
 752		return -EINVAL;
 753	}
 754
 755	if (mode == ADAU1761_OUTPUT_MODE_HEADPHONE_CAPLESS) {
 756		ret = snd_soc_dapm_new_controls(dapm,
 757			adau1761_capless_dapm_widgets,
 758			ARRAY_SIZE(adau1761_capless_dapm_widgets));
 759		if (ret)
 760			return ret;
 761		ret = snd_soc_dapm_add_routes(dapm,
 762			adau1761_capless_dapm_routes,
 763			ARRAY_SIZE(adau1761_capless_dapm_routes));
 764	} else {
 765		ret = snd_soc_add_component_controls(component, adau1761_mono_controls,
 766			ARRAY_SIZE(adau1761_mono_controls));
 767		if (ret)
 768			return ret;
 769		ret = snd_soc_dapm_new_controls(dapm,
 770			adau1761_mono_dapm_widgets,
 771			ARRAY_SIZE(adau1761_mono_dapm_widgets));
 772		if (ret)
 773			return ret;
 774		ret = snd_soc_dapm_add_routes(dapm,
 775			adau1761_mono_dapm_routes,
 776			ARRAY_SIZE(adau1761_mono_dapm_routes));
 777	}
 778
 779	return ret;
 780}
 781
 782static bool adau1761_readable_register(struct device *dev, unsigned int reg)
 783{
 784	switch (reg) {
 785	case ADAU1761_DIGMIC_JACKDETECT:
 786	case ADAU1761_REC_MIXER_LEFT0:
 787	case ADAU1761_REC_MIXER_LEFT1:
 788	case ADAU1761_REC_MIXER_RIGHT0:
 789	case ADAU1761_REC_MIXER_RIGHT1:
 790	case ADAU1761_LEFT_DIFF_INPUT_VOL:
 791	case ADAU1761_RIGHT_DIFF_INPUT_VOL:
 792	case ADAU1761_PLAY_LR_MIXER_LEFT:
 793	case ADAU1761_PLAY_MIXER_LEFT0:
 794	case ADAU1761_PLAY_MIXER_LEFT1:
 795	case ADAU1761_PLAY_MIXER_RIGHT0:
 796	case ADAU1761_PLAY_MIXER_RIGHT1:
 797	case ADAU1761_PLAY_LR_MIXER_RIGHT:
 798	case ADAU1761_PLAY_MIXER_MONO:
 799	case ADAU1761_PLAY_HP_LEFT_VOL:
 800	case ADAU1761_PLAY_HP_RIGHT_VOL:
 801	case ADAU1761_PLAY_LINE_LEFT_VOL:
 802	case ADAU1761_PLAY_LINE_RIGHT_VOL:
 803	case ADAU1761_PLAY_MONO_OUTPUT_VOL:
 804	case ADAU1761_POP_CLICK_SUPPRESS:
 805	case ADAU1761_JACK_DETECT_PIN:
 806	case ADAU1761_DEJITTER:
 807	case ADAU1761_CLK_ENABLE0:
 808	case ADAU1761_CLK_ENABLE1:
 809	case ADAU1761_ALC_CTRL0:
 810	case ADAU1761_ALC_CTRL1:
 811	case ADAU1761_ALC_CTRL2:
 812	case ADAU1761_ALC_CTRL3:
 813		return true;
 814	default:
 815		break;
 816	}
 817
 818	return adau17x1_readable_register(dev, reg);
 819}
 820
 821static int adau1761_component_probe(struct snd_soc_component *component)
 822{
 823	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
 824	struct adau1761_platform_data *pdata = component->dev->platform_data;
 825	struct adau *adau = snd_soc_component_get_drvdata(component);
 826	int ret;
 827
 828	ret = adau17x1_add_widgets(component);
 829	if (ret < 0)
 830		return ret;
 831
 832	if (pdata && pdata->input_differential) {
 833		regmap_update_bits(adau->regmap, ADAU1761_LEFT_DIFF_INPUT_VOL,
 834			ADAU1761_DIFF_INPUT_VOL_LDEN,
 835			ADAU1761_DIFF_INPUT_VOL_LDEN);
 836		regmap_update_bits(adau->regmap, ADAU1761_RIGHT_DIFF_INPUT_VOL,
 837			ADAU1761_DIFF_INPUT_VOL_LDEN,
 838			ADAU1761_DIFF_INPUT_VOL_LDEN);
 839		ret = snd_soc_add_component_controls(component,
 840			adau1761_differential_mode_controls,
 841			ARRAY_SIZE(adau1761_differential_mode_controls));
 842		if (ret)
 843			return ret;
 844	} else {
 845		ret = snd_soc_add_component_controls(component,
 846			adau1761_single_mode_controls,
 847			ARRAY_SIZE(adau1761_single_mode_controls));
 848		if (ret)
 849			return ret;
 850	}
 851
 852	switch (adau1761_get_lineout_mode(component)) {
 853	case ADAU1761_OUTPUT_MODE_LINE:
 854		break;
 855	case ADAU1761_OUTPUT_MODE_HEADPHONE:
 856		regmap_update_bits(adau->regmap, ADAU1761_PLAY_LINE_LEFT_VOL,
 857			ADAU1761_PLAY_LINE_LEFT_VOL_MODE_HP,
 858			ADAU1761_PLAY_LINE_LEFT_VOL_MODE_HP);
 859		regmap_update_bits(adau->regmap, ADAU1761_PLAY_LINE_RIGHT_VOL,
 860			ADAU1761_PLAY_LINE_RIGHT_VOL_MODE_HP,
 861			ADAU1761_PLAY_LINE_RIGHT_VOL_MODE_HP);
 862		break;
 863	default:
 864		return -EINVAL;
 865	}
 866
 867	ret = adau1761_setup_headphone_mode(component);
 868	if (ret)
 869		return ret;
 870
 871	ret = adau1761_setup_digmic_jackdetect(component);
 872	if (ret)
 873		return ret;
 874
 875	/*
 876	 * If we've got an ADAU1761, or an ADAU1761 operating as an
 877	 * ADAU1361, we need these non-DSP related DAPM widgets and routes.
 878	 */
 879	if (adau->type == ADAU1761 || adau->type == ADAU1761_AS_1361) {
 880		ret = snd_soc_dapm_new_controls(dapm, adau1761_dapm_widgets,
 881			ARRAY_SIZE(adau1761_dapm_widgets));
 882		if (ret)
 883			return ret;
 884
 885		ret = snd_soc_dapm_add_routes(dapm, adau1761_dapm_routes,
 886			ARRAY_SIZE(adau1761_dapm_routes));
 887		if (ret)
 888			return ret;
 889	}
 890	/*
 891	 * These routes are DSP related and only used when we have a
 892	 * bona fide ADAU1761.
 893	 */
 894	if (adau->type == ADAU1761) {
 895		ret = snd_soc_dapm_add_routes(dapm, adau1761_dapm_dsp_routes,
 896			ARRAY_SIZE(adau1761_dapm_dsp_routes));
 897		if (ret)
 898			return ret;
 899	}
 900	/*
 901	 * In the ADAU1761, by default, the AIF is routed to the DSP, whereas
 902	 * for the ADAU1361, the AIF is permanently routed to the ADC and DAC.
 903	 * Thus, if we have an ADAU1761 masquerading as an ADAU1361,
 904	 * we need to explicitly route the AIF to the ADC and DAC.
 905	 * For the ADAU1761, this is normally done by set_tdm_slot, but this
 906	 * function is not necessarily called during stream setup, so set up
 907	 * the compatible AIF routings here from the start.
 908	 */
 909	if  (adau->type == ADAU1761_AS_1361) {
 910		regmap_write(adau->regmap, ADAU17X1_SERIAL_INPUT_ROUTE, 0x01);
 911		regmap_write(adau->regmap, ADAU17X1_SERIAL_OUTPUT_ROUTE, 0x01);
 912	}
 913	ret = adau17x1_add_routes(component);
 914	if (ret < 0)
 915		return ret;
 916
 917	return 0;
 918}
 919
 920static const struct snd_soc_component_driver adau1761_component_driver = {
 921	.probe			= adau1761_component_probe,
 922	.resume			= adau17x1_resume,
 923	.set_bias_level		= adau1761_set_bias_level,
 924	.controls		= adau1761_controls,
 925	.num_controls		= ARRAY_SIZE(adau1761_controls),
 926	.dapm_widgets		= adau1x61_dapm_widgets,
 927	.num_dapm_widgets	= ARRAY_SIZE(adau1x61_dapm_widgets),
 928	.dapm_routes		= adau1x61_dapm_routes,
 929	.num_dapm_routes	= ARRAY_SIZE(adau1x61_dapm_routes),
 930	.suspend_bias_off	= 1,
 931	.idle_bias_on		= 1,
 932	.use_pmdown_time	= 1,
 933	.endianness		= 1,
 934};
 935
 936#define ADAU1761_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
 937	SNDRV_PCM_FMTBIT_S32_LE)
 938
 939static struct snd_soc_dai_driver adau1361_dai_driver = {
 940	.name = "adau-hifi",
 941	.playback = {
 942		.stream_name = "Playback",
 943		.channels_min = 2,
 944		.channels_max = 4,
 945		.rates = SNDRV_PCM_RATE_8000_96000,
 946		.formats = ADAU1761_FORMATS,
 947	},
 948	.capture = {
 949		.stream_name = "Capture",
 950		.channels_min = 2,
 951		.channels_max = 4,
 952		.rates = SNDRV_PCM_RATE_8000_96000,
 953		.formats = ADAU1761_FORMATS,
 954	},
 955	.ops = &adau17x1_dai_ops,
 956};
 957
 958static struct snd_soc_dai_driver adau1761_dai_driver = {
 959	.name = "adau-hifi",
 960	.playback = {
 961		.stream_name = "Playback",
 962		.channels_min = 2,
 963		.channels_max = 8,
 964		.rates = SNDRV_PCM_RATE_8000_96000,
 965		.formats = ADAU1761_FORMATS,
 966	},
 967	.capture = {
 968		.stream_name = "Capture",
 969		.channels_min = 2,
 970		.channels_max = 8,
 971		.rates = SNDRV_PCM_RATE_8000_96000,
 972		.formats = ADAU1761_FORMATS,
 973	},
 974	.ops = &adau17x1_dai_ops,
 975};
 976
 977int adau1761_probe(struct device *dev, struct regmap *regmap,
 978	enum adau17x1_type type, void (*switch_mode)(struct device *dev))
 979{
 980	struct snd_soc_dai_driver *dai_drv;
 981	const char *firmware_name;
 982	int ret;
 983
 984	if (type == ADAU1361) {
 985		dai_drv = &adau1361_dai_driver;
 986		firmware_name = NULL;
 987	} else {
 988		dai_drv = &adau1761_dai_driver;
 989		firmware_name = ADAU1761_FIRMWARE;
 990	}
 991
 992	ret = adau17x1_probe(dev, regmap, type, switch_mode, firmware_name);
 993	if (ret)
 994		return ret;
 995
 996	ret = adau1761_compatibility_probe(dev);
 997	if (ret)
 998		return ret;
 999
1000	/* Enable cache only mode as we could miss writes before bias level
1001	 * reaches standby and the core clock is enabled */
1002	regcache_cache_only(regmap, true);
1003
1004	return devm_snd_soc_register_component(dev, &adau1761_component_driver,
1005					       dai_drv, 1);
1006}
1007EXPORT_SYMBOL_GPL(adau1761_probe);
1008
1009const struct regmap_config adau1761_regmap_config = {
1010	.val_bits = 8,
1011	.reg_bits = 16,
1012	.max_register = 0x40fa,
1013	.reg_defaults = adau1761_reg_defaults,
1014	.num_reg_defaults = ARRAY_SIZE(adau1761_reg_defaults),
1015	.readable_reg = adau1761_readable_register,
1016	.volatile_reg = adau17x1_volatile_register,
1017	.precious_reg = adau17x1_precious_register,
1018	.cache_type = REGCACHE_MAPLE,
1019};
1020EXPORT_SYMBOL_GPL(adau1761_regmap_config);
1021
1022MODULE_DESCRIPTION("ASoC ADAU1361/ADAU1461/ADAU1761/ADAU1961 CODEC driver");
1023MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
1024MODULE_LICENSE("GPL");
~/ Read-only file preview.