Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: Add ADAU1373 codec support

This patch adds support for the Analog Devices ADAU1373 audio codec.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

authored by

Lars-Peter Clausen and committed by
Mark Brown
ddd7a260 f0b182b0

+1483
+34
include/sound/adau1373.h
··· 1 + /* 2 + * Analog Devices ADAU1373 Audio Codec drive 3 + * 4 + * Copyright 2011 Analog Devices Inc. 5 + * Author: Lars-Peter Clausen <lars@metafoo.de> 6 + * 7 + * Licensed under the GPL-2 or later. 8 + */ 9 + 10 + #ifndef __SOUND_ADAU1373_H__ 11 + #define __SOUND_ADAU1373_H__ 12 + 13 + enum adau1373_micbias_voltage { 14 + ADAU1373_MICBIAS_2_9V = 0, 15 + ADAU1373_MICBIAS_2_2V = 1, 16 + ADAU1373_MICBIAS_2_6V = 2, 17 + ADAU1373_MICBIAS_1_8V = 3, 18 + }; 19 + 20 + #define ADAU1373_DRC_SIZE 13 21 + 22 + struct adau1373_platform_data { 23 + bool input_differential[4]; 24 + bool lineout_differential; 25 + bool lineout_ground_sense; 26 + 27 + unsigned int num_drc; 28 + uint8_t drc_setting[3][ADAU1373_DRC_SIZE]; 29 + 30 + enum adau1373_micbias_voltage micbias1; 31 + enum adau1373_micbias_voltage micbias2; 32 + }; 33 + 34 + #endif
+4
sound/soc/codecs/Kconfig
··· 17 17 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI 18 18 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 19 19 select SND_SOC_AD73311 20 + select SND_SOC_ADAU1373 if I2C 20 21 select SND_SOC_ADAV80X 21 22 select SND_SOC_ADS117X 22 23 select SND_SOC_AK4104 if SPI_MASTER ··· 138 137 139 138 config SND_SOC_ADAU1701 140 139 select SIGMA 140 + tristate 141 + 142 + config SND_SOC_ADAU1373 141 143 tristate 142 144 143 145 config SND_SOC_ADAV80X
+2
sound/soc/codecs/Makefile
··· 5 5 snd-soc-ad1980-objs := ad1980.o 6 6 snd-soc-ad73311-objs := ad73311.o 7 7 snd-soc-adau1701-objs := adau1701.o 8 + snd-soc-adau1373-objs := adau1373.o 8 9 snd-soc-adav80x-objs := adav80x.o 9 10 snd-soc-ads117x-objs := ads117x.o 10 11 snd-soc-ak4104-objs := ak4104.o ··· 101 100 obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o 102 101 obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o 103 102 obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o 103 + obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o 104 104 obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o 105 105 obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o 106 106 obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
+1414
sound/soc/codecs/adau1373.c
··· 1 + /* 2 + * Analog Devices ADAU1373 Audio Codec drive 3 + * 4 + * Copyright 2011 Analog Devices Inc. 5 + * Author: Lars-Peter Clausen <lars@metafoo.de> 6 + * 7 + * Licensed under the GPL-2 or later. 8 + */ 9 + 10 + #include <linux/module.h> 11 + #include <linux/init.h> 12 + #include <linux/delay.h> 13 + #include <linux/pm.h> 14 + #include <linux/i2c.h> 15 + #include <linux/slab.h> 16 + #include <linux/gcd.h> 17 + 18 + #include <sound/core.h> 19 + #include <sound/pcm.h> 20 + #include <sound/pcm_params.h> 21 + #include <sound/tlv.h> 22 + #include <sound/soc.h> 23 + #include <sound/adau1373.h> 24 + 25 + #include "adau1373.h" 26 + 27 + struct adau1373_dai { 28 + unsigned int clk_src; 29 + unsigned int sysclk; 30 + bool enable_src; 31 + bool master; 32 + }; 33 + 34 + struct adau1373 { 35 + struct adau1373_dai dais[3]; 36 + }; 37 + 38 + #define ADAU1373_INPUT_MODE 0x00 39 + #define ADAU1373_AINL_CTRL(x) (0x01 + (x) * 2) 40 + #define ADAU1373_AINR_CTRL(x) (0x02 + (x) * 2) 41 + #define ADAU1373_LLINE_OUT(x) (0x9 + (x) * 2) 42 + #define ADAU1373_RLINE_OUT(x) (0xa + (x) * 2) 43 + #define ADAU1373_LSPK_OUT 0x0d 44 + #define ADAU1373_RSPK_OUT 0x0e 45 + #define ADAU1373_LHP_OUT 0x0f 46 + #define ADAU1373_RHP_OUT 0x10 47 + #define ADAU1373_ADC_GAIN 0x11 48 + #define ADAU1373_LADC_MIXER 0x12 49 + #define ADAU1373_RADC_MIXER 0x13 50 + #define ADAU1373_LLINE1_MIX 0x14 51 + #define ADAU1373_RLINE1_MIX 0x15 52 + #define ADAU1373_LLINE2_MIX 0x16 53 + #define ADAU1373_RLINE2_MIX 0x17 54 + #define ADAU1373_LSPK_MIX 0x18 55 + #define ADAU1373_RSPK_MIX 0x19 56 + #define ADAU1373_LHP_MIX 0x1a 57 + #define ADAU1373_RHP_MIX 0x1b 58 + #define ADAU1373_EP_MIX 0x1c 59 + #define ADAU1373_HP_CTRL 0x1d 60 + #define ADAU1373_HP_CTRL2 0x1e 61 + #define ADAU1373_LS_CTRL 0x1f 62 + #define ADAU1373_EP_CTRL 0x21 63 + #define ADAU1373_MICBIAS_CTRL1 0x22 64 + #define ADAU1373_MICBIAS_CTRL2 0x23 65 + #define ADAU1373_OUTPUT_CTRL 0x24 66 + #define ADAU1373_PWDN_CTRL1 0x25 67 + #define ADAU1373_PWDN_CTRL2 0x26 68 + #define ADAU1373_PWDN_CTRL3 0x27 69 + #define ADAU1373_DPLL_CTRL(x) (0x28 + (x) * 7) 70 + #define ADAU1373_PLL_CTRL1(x) (0x29 + (x) * 7) 71 + #define ADAU1373_PLL_CTRL2(x) (0x2a + (x) * 7) 72 + #define ADAU1373_PLL_CTRL3(x) (0x2b + (x) * 7) 73 + #define ADAU1373_PLL_CTRL4(x) (0x2c + (x) * 7) 74 + #define ADAU1373_PLL_CTRL5(x) (0x2d + (x) * 7) 75 + #define ADAU1373_PLL_CTRL6(x) (0x2e + (x) * 7) 76 + #define ADAU1373_PLL_CTRL7(x) (0x2f + (x) * 7) 77 + #define ADAU1373_HEADDECT 0x36 78 + #define ADAU1373_ADC_DAC_STATUS 0x37 79 + #define ADAU1373_ADC_CTRL 0x3c 80 + #define ADAU1373_DAI(x) (0x44 + (x)) 81 + #define ADAU1373_CLK_SRC_DIV(x) (0x40 + (x) * 2) 82 + #define ADAU1373_BCLKDIV(x) (0x47 + (x)) 83 + #define ADAU1373_SRC_RATIOA(x) (0x4a + (x) * 2) 84 + #define ADAU1373_SRC_RATIOB(x) (0x4b + (x) * 2) 85 + #define ADAU1373_DEEMP_CTRL 0x50 86 + #define ADAU1373_SRC_DAI_CTRL(x) (0x51 + (x)) 87 + #define ADAU1373_DIN_MIX_CTRL(x) (0x56 + (x)) 88 + #define ADAU1373_DOUT_MIX_CTRL(x) (0x5b + (x)) 89 + #define ADAU1373_DAI_PBL_VOL(x) (0x62 + (x) * 2) 90 + #define ADAU1373_DAI_PBR_VOL(x) (0x63 + (x) * 2) 91 + #define ADAU1373_DAI_RECL_VOL(x) (0x68 + (x) * 2) 92 + #define ADAU1373_DAI_RECR_VOL(x) (0x69 + (x) * 2) 93 + #define ADAU1373_DAC1_PBL_VOL 0x6e 94 + #define ADAU1373_DAC1_PBR_VOL 0x6f 95 + #define ADAU1373_DAC2_PBL_VOL 0x70 96 + #define ADAU1373_DAC2_PBR_VOL 0x71 97 + #define ADAU1373_ADC_RECL_VOL 0x72 98 + #define ADAU1373_ADC_RECR_VOL 0x73 99 + #define ADAU1373_DMIC_RECL_VOL 0x74 100 + #define ADAU1373_DMIC_RECR_VOL 0x75 101 + #define ADAU1373_VOL_GAIN1 0x76 102 + #define ADAU1373_VOL_GAIN2 0x77 103 + #define ADAU1373_VOL_GAIN3 0x78 104 + #define ADAU1373_HPF_CTRL 0x7d 105 + #define ADAU1373_BASS1 0x7e 106 + #define ADAU1373_BASS2 0x7f 107 + #define ADAU1373_DRC(x) (0x80 + (x) * 0x10) 108 + #define ADAU1373_3D_CTRL1 0xc0 109 + #define ADAU1373_3D_CTRL2 0xc1 110 + #define ADAU1373_FDSP_SEL1 0xdc 111 + #define ADAU1373_FDSP_SEL2 0xdd 112 + #define ADAU1373_FDSP_SEL3 0xde 113 + #define ADAU1373_FDSP_SEL4 0xdf 114 + #define ADAU1373_DIGMICCTRL 0xe2 115 + #define ADAU1373_DIGEN 0xeb 116 + #define ADAU1373_SOFT_RESET 0xff 117 + 118 + 119 + #define ADAU1373_PLL_CTRL6_DPLL_BYPASS BIT(1) 120 + #define ADAU1373_PLL_CTRL6_PLL_EN BIT(0) 121 + 122 + #define ADAU1373_DAI_INVERT_BCLK BIT(7) 123 + #define ADAU1373_DAI_MASTER BIT(6) 124 + #define ADAU1373_DAI_INVERT_LRCLK BIT(4) 125 + #define ADAU1373_DAI_WLEN_16 0x0 126 + #define ADAU1373_DAI_WLEN_20 0x4 127 + #define ADAU1373_DAI_WLEN_24 0x8 128 + #define ADAU1373_DAI_WLEN_32 0xc 129 + #define ADAU1373_DAI_WLEN_MASK 0xc 130 + #define ADAU1373_DAI_FORMAT_RIGHT_J 0x0 131 + #define ADAU1373_DAI_FORMAT_LEFT_J 0x1 132 + #define ADAU1373_DAI_FORMAT_I2S 0x2 133 + #define ADAU1373_DAI_FORMAT_DSP 0x3 134 + 135 + #define ADAU1373_BCLKDIV_SOURCE BIT(5) 136 + #define ADAU1373_BCLKDIV_32 0x03 137 + #define ADAU1373_BCLKDIV_64 0x02 138 + #define ADAU1373_BCLKDIV_128 0x01 139 + #define ADAU1373_BCLKDIV_256 0x00 140 + 141 + #define ADAU1373_ADC_CTRL_PEAK_DETECT BIT(0) 142 + #define ADAU1373_ADC_CTRL_RESET BIT(1) 143 + #define ADAU1373_ADC_CTRL_RESET_FORCE BIT(2) 144 + 145 + #define ADAU1373_OUTPUT_CTRL_LDIFF BIT(3) 146 + #define ADAU1373_OUTPUT_CTRL_LNFBEN BIT(2) 147 + 148 + #define ADAU1373_PWDN_CTRL3_PWR_EN BIT(0) 149 + 150 + #define ADAU1373_EP_CTRL_MICBIAS1_OFFSET 4 151 + #define ADAU1373_EP_CTRL_MICBIAS2_OFFSET 2 152 + 153 + static const uint8_t adau1373_default_regs[] = { 154 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00 */ 155 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 156 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10 */ 157 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 158 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20 */ 159 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 160 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* 0x30 */ 161 + 0x00, 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00, 162 + 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x00, /* 0x40 */ 163 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 164 + 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, /* 0x50 */ 165 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 166 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60 */ 167 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 168 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 */ 169 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 170 + 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0x80 */ 171 + 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00, 172 + 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0x90 */ 173 + 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00, 174 + 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0xa0 */ 175 + 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00, 176 + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb0 */ 177 + 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 178 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 */ 179 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 180 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0 */ 181 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 182 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* 0xe0 */ 183 + 0x00, 0x1f, 0x0f, 0x00, 0x00, 184 + }; 185 + 186 + static const unsigned int adau1373_out_tlv[] = { 187 + TLV_DB_RANGE_HEAD(4), 188 + 0, 7, TLV_DB_SCALE_ITEM(-7900, 400, 1), 189 + 8, 15, TLV_DB_SCALE_ITEM(-4700, 300, 0), 190 + 16, 23, TLV_DB_SCALE_ITEM(-2300, 200, 0), 191 + 24, 31, TLV_DB_SCALE_ITEM(-700, 100, 0), 192 + }; 193 + 194 + static const DECLARE_TLV_DB_MINMAX(adau1373_digital_tlv, -9563, 0); 195 + static const DECLARE_TLV_DB_SCALE(adau1373_in_pga_tlv, -1300, 100, 1); 196 + static const DECLARE_TLV_DB_SCALE(adau1373_ep_tlv, -600, 600, 1); 197 + 198 + static const DECLARE_TLV_DB_SCALE(adau1373_input_boost_tlv, 0, 2000, 0); 199 + static const DECLARE_TLV_DB_SCALE(adau1373_gain_boost_tlv, 0, 600, 0); 200 + static const DECLARE_TLV_DB_SCALE(adau1373_speaker_boost_tlv, 1200, 600, 0); 201 + 202 + static const char *adau1373_fdsp_sel_text[] = { 203 + "None", 204 + "Channel 1", 205 + "Channel 2", 206 + "Channel 3", 207 + "Channel 4", 208 + "Channel 5", 209 + }; 210 + 211 + static const SOC_ENUM_SINGLE_DECL(adau1373_drc1_channel_enum, 212 + ADAU1373_FDSP_SEL1, 4, adau1373_fdsp_sel_text); 213 + static const SOC_ENUM_SINGLE_DECL(adau1373_drc2_channel_enum, 214 + ADAU1373_FDSP_SEL1, 0, adau1373_fdsp_sel_text); 215 + static const SOC_ENUM_SINGLE_DECL(adau1373_drc3_channel_enum, 216 + ADAU1373_FDSP_SEL2, 0, adau1373_fdsp_sel_text); 217 + static const SOC_ENUM_SINGLE_DECL(adau1373_hpf_channel_enum, 218 + ADAU1373_FDSP_SEL3, 0, adau1373_fdsp_sel_text); 219 + static const SOC_ENUM_SINGLE_DECL(adau1373_bass_channel_enum, 220 + ADAU1373_FDSP_SEL4, 4, adau1373_fdsp_sel_text); 221 + 222 + static const char *adau1373_hpf_cutoff_text[] = { 223 + "3.7Hz", "50Hz", "100Hz", "150Hz", "200Hz", "250Hz", "300Hz", "350Hz", 224 + "400Hz", "450Hz", "500Hz", "550Hz", "600Hz", "650Hz", "700Hz", "750Hz", 225 + "800Hz", 226 + }; 227 + 228 + static const SOC_ENUM_SINGLE_DECL(adau1373_hpf_cutoff_enum, 229 + ADAU1373_HPF_CTRL, 3, adau1373_hpf_cutoff_text); 230 + 231 + static const char *adau1373_bass_lpf_cutoff_text[] = { 232 + "801Hz", "1001Hz", 233 + }; 234 + 235 + static const char *adau1373_bass_clip_level_text[] = { 236 + "0.125", "0.250", "0.370", "0.500", "0.625", "0.750", "0.875", 237 + }; 238 + 239 + static const unsigned int adau1373_bass_clip_level_values[] = { 240 + 1, 2, 3, 4, 5, 6, 7, 241 + }; 242 + 243 + static const char *adau1373_bass_hpf_cutoff_text[] = { 244 + "158Hz", "232Hz", "347Hz", "520Hz", 245 + }; 246 + 247 + static const unsigned int adau1373_bass_tlv[] = { 248 + TLV_DB_RANGE_HEAD(4), 249 + 0, 2, TLV_DB_SCALE_ITEM(-600, 600, 1), 250 + 3, 4, TLV_DB_SCALE_ITEM(950, 250, 0), 251 + 5, 7, TLV_DB_SCALE_ITEM(1400, 150, 0), 252 + }; 253 + 254 + static const SOC_ENUM_SINGLE_DECL(adau1373_bass_lpf_cutoff_enum, 255 + ADAU1373_BASS1, 5, adau1373_bass_lpf_cutoff_text); 256 + 257 + static const SOC_VALUE_ENUM_SINGLE_DECL(adau1373_bass_clip_level_enum, 258 + ADAU1373_BASS1, 2, 7, adau1373_bass_clip_level_text, 259 + adau1373_bass_clip_level_values); 260 + 261 + static const SOC_ENUM_SINGLE_DECL(adau1373_bass_hpf_cutoff_enum, 262 + ADAU1373_BASS1, 0, adau1373_bass_hpf_cutoff_text); 263 + 264 + static const char *adau1373_3d_level_text[] = { 265 + "0%", "6.67%", "13.33%", "20%", "26.67%", "33.33%", 266 + "40%", "46.67%", "53.33%", "60%", "66.67%", "73.33%", 267 + "80%", "86.67", "99.33%", "100%" 268 + }; 269 + 270 + static const char *adau1373_3d_cutoff_text[] = { 271 + "No 3D", "0.03125 fs", "0.04583 fs", "0.075 fs", "0.11458 fs", 272 + "0.16875 fs", "0.27083 fs" 273 + }; 274 + 275 + static const SOC_ENUM_SINGLE_DECL(adau1373_3d_level_enum, 276 + ADAU1373_3D_CTRL1, 4, adau1373_3d_level_text); 277 + static const SOC_ENUM_SINGLE_DECL(adau1373_3d_cutoff_enum, 278 + ADAU1373_3D_CTRL1, 0, adau1373_3d_cutoff_text); 279 + 280 + static const unsigned int adau1373_3d_tlv[] = { 281 + TLV_DB_RANGE_HEAD(2), 282 + 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), 283 + 1, 7, TLV_DB_LINEAR_ITEM(-1800, -120), 284 + }; 285 + 286 + static const char *adau1373_lr_mux_text[] = { 287 + "Mute", 288 + "Right Channel (L+R)", 289 + "Left Channel (L+R)", 290 + "Stereo", 291 + }; 292 + 293 + static const SOC_ENUM_SINGLE_DECL(adau1373_lineout1_lr_mux_enum, 294 + ADAU1373_OUTPUT_CTRL, 4, adau1373_lr_mux_text); 295 + static const SOC_ENUM_SINGLE_DECL(adau1373_lineout2_lr_mux_enum, 296 + ADAU1373_OUTPUT_CTRL, 6, adau1373_lr_mux_text); 297 + static const SOC_ENUM_SINGLE_DECL(adau1373_speaker_lr_mux_enum, 298 + ADAU1373_LS_CTRL, 4, adau1373_lr_mux_text); 299 + 300 + static const struct snd_kcontrol_new adau1373_controls[] = { 301 + SOC_DOUBLE_R_TLV("AIF1 Capture Volume", ADAU1373_DAI_RECL_VOL(0), 302 + ADAU1373_DAI_RECR_VOL(0), 0, 0xff, 1, adau1373_digital_tlv), 303 + SOC_DOUBLE_R_TLV("AIF2 Capture Volume", ADAU1373_DAI_RECL_VOL(1), 304 + ADAU1373_DAI_RECR_VOL(1), 0, 0xff, 1, adau1373_digital_tlv), 305 + SOC_DOUBLE_R_TLV("AIF3 Capture Volume", ADAU1373_DAI_RECL_VOL(2), 306 + ADAU1373_DAI_RECR_VOL(2), 0, 0xff, 1, adau1373_digital_tlv), 307 + 308 + SOC_DOUBLE_R_TLV("ADC Capture Volume", ADAU1373_ADC_RECL_VOL, 309 + ADAU1373_ADC_RECR_VOL, 0, 0xff, 1, adau1373_digital_tlv), 310 + SOC_DOUBLE_R_TLV("DMIC Capture Volume", ADAU1373_DMIC_RECL_VOL, 311 + ADAU1373_DMIC_RECR_VOL, 0, 0xff, 1, adau1373_digital_tlv), 312 + 313 + SOC_DOUBLE_R_TLV("AIF1 Playback Volume", ADAU1373_DAI_PBL_VOL(0), 314 + ADAU1373_DAI_PBR_VOL(0), 0, 0xff, 1, adau1373_digital_tlv), 315 + SOC_DOUBLE_R_TLV("AIF2 Playback Volume", ADAU1373_DAI_PBL_VOL(1), 316 + ADAU1373_DAI_PBR_VOL(1), 0, 0xff, 1, adau1373_digital_tlv), 317 + SOC_DOUBLE_R_TLV("AIF3 Playback Volume", ADAU1373_DAI_PBL_VOL(2), 318 + ADAU1373_DAI_PBR_VOL(2), 0, 0xff, 1, adau1373_digital_tlv), 319 + 320 + SOC_DOUBLE_R_TLV("DAC1 Playback Volume", ADAU1373_DAC1_PBL_VOL, 321 + ADAU1373_DAC1_PBR_VOL, 0, 0xff, 1, adau1373_digital_tlv), 322 + SOC_DOUBLE_R_TLV("DAC2 Playback Volume", ADAU1373_DAC2_PBL_VOL, 323 + ADAU1373_DAC2_PBR_VOL, 0, 0xff, 1, adau1373_digital_tlv), 324 + 325 + SOC_DOUBLE_R_TLV("Lineout1 Playback Volume", ADAU1373_LLINE_OUT(0), 326 + ADAU1373_RLINE_OUT(0), 0, 0x1f, 0, adau1373_out_tlv), 327 + SOC_DOUBLE_R_TLV("Speaker Playback Volume", ADAU1373_LSPK_OUT, 328 + ADAU1373_RSPK_OUT, 0, 0x1f, 0, adau1373_out_tlv), 329 + SOC_DOUBLE_R_TLV("Headphone Playback Volume", ADAU1373_LHP_OUT, 330 + ADAU1373_RHP_OUT, 0, 0x1f, 0, adau1373_out_tlv), 331 + 332 + SOC_DOUBLE_R_TLV("Input 1 Capture Volume", ADAU1373_AINL_CTRL(0), 333 + ADAU1373_AINR_CTRL(0), 0, 0x1f, 0, adau1373_in_pga_tlv), 334 + SOC_DOUBLE_R_TLV("Input 2 Capture Volume", ADAU1373_AINL_CTRL(1), 335 + ADAU1373_AINR_CTRL(1), 0, 0x1f, 0, adau1373_in_pga_tlv), 336 + SOC_DOUBLE_R_TLV("Input 3 Capture Volume", ADAU1373_AINL_CTRL(2), 337 + ADAU1373_AINR_CTRL(2), 0, 0x1f, 0, adau1373_in_pga_tlv), 338 + SOC_DOUBLE_R_TLV("Input 4 Capture Volume", ADAU1373_AINL_CTRL(3), 339 + ADAU1373_AINR_CTRL(3), 0, 0x1f, 0, adau1373_in_pga_tlv), 340 + 341 + SOC_SINGLE_TLV("Earpiece Playback Volume", ADAU1373_EP_CTRL, 0, 3, 0, 342 + adau1373_ep_tlv), 343 + 344 + SOC_DOUBLE_TLV("AIF3 Boost Playback Volume", ADAU1373_VOL_GAIN1, 4, 5, 345 + 1, 0, adau1373_gain_boost_tlv), 346 + SOC_DOUBLE_TLV("AIF2 Boost Playback Volume", ADAU1373_VOL_GAIN1, 2, 3, 347 + 1, 0, adau1373_gain_boost_tlv), 348 + SOC_DOUBLE_TLV("AIF1 Boost Playback Volume", ADAU1373_VOL_GAIN1, 0, 1, 349 + 1, 0, adau1373_gain_boost_tlv), 350 + SOC_DOUBLE_TLV("AIF3 Boost Capture Volume", ADAU1373_VOL_GAIN2, 4, 5, 351 + 1, 0, adau1373_gain_boost_tlv), 352 + SOC_DOUBLE_TLV("AIF2 Boost Capture Volume", ADAU1373_VOL_GAIN2, 2, 3, 353 + 1, 0, adau1373_gain_boost_tlv), 354 + SOC_DOUBLE_TLV("AIF1 Boost Capture Volume", ADAU1373_VOL_GAIN2, 0, 1, 355 + 1, 0, adau1373_gain_boost_tlv), 356 + SOC_DOUBLE_TLV("DMIC Boost Capture Volume", ADAU1373_VOL_GAIN3, 6, 7, 357 + 1, 0, adau1373_gain_boost_tlv), 358 + SOC_DOUBLE_TLV("ADC Boost Capture Volume", ADAU1373_VOL_GAIN3, 4, 5, 359 + 1, 0, adau1373_gain_boost_tlv), 360 + SOC_DOUBLE_TLV("DAC2 Boost Playback Volume", ADAU1373_VOL_GAIN3, 2, 3, 361 + 1, 0, adau1373_gain_boost_tlv), 362 + SOC_DOUBLE_TLV("DAC1 Boost Playback Volume", ADAU1373_VOL_GAIN3, 0, 1, 363 + 1, 0, adau1373_gain_boost_tlv), 364 + 365 + SOC_DOUBLE_TLV("Input 1 Boost Capture Volume", ADAU1373_ADC_GAIN, 0, 4, 366 + 1, 0, adau1373_input_boost_tlv), 367 + SOC_DOUBLE_TLV("Input 2 Boost Capture Volume", ADAU1373_ADC_GAIN, 1, 5, 368 + 1, 0, adau1373_input_boost_tlv), 369 + SOC_DOUBLE_TLV("Input 3 Boost Capture Volume", ADAU1373_ADC_GAIN, 2, 6, 370 + 1, 0, adau1373_input_boost_tlv), 371 + SOC_DOUBLE_TLV("Input 4 Boost Capture Volume", ADAU1373_ADC_GAIN, 3, 7, 372 + 1, 0, adau1373_input_boost_tlv), 373 + 374 + SOC_DOUBLE_TLV("Speaker Boost Playback Volume", ADAU1373_LS_CTRL, 2, 3, 375 + 1, 0, adau1373_speaker_boost_tlv), 376 + 377 + SOC_ENUM("Lineout1 LR Mux", adau1373_lineout1_lr_mux_enum), 378 + SOC_ENUM("Speaker LR Mux", adau1373_speaker_lr_mux_enum), 379 + 380 + SOC_ENUM("HPF Cutoff", adau1373_hpf_cutoff_enum), 381 + SOC_DOUBLE("HPF Switch", ADAU1373_HPF_CTRL, 1, 0, 1, 0), 382 + SOC_ENUM("HPF Channel", adau1373_hpf_channel_enum), 383 + 384 + SOC_ENUM("Bass HPF Cutoff", adau1373_bass_hpf_cutoff_enum), 385 + SOC_VALUE_ENUM("Bass Clip Level Threshold", 386 + adau1373_bass_clip_level_enum), 387 + SOC_ENUM("Bass LPF Cutoff", adau1373_bass_lpf_cutoff_enum), 388 + SOC_DOUBLE("Bass Playback Switch", ADAU1373_BASS2, 0, 1, 1, 0), 389 + SOC_SINGLE_TLV("Bass Playback Volume", ADAU1373_BASS2, 2, 7, 0, 390 + adau1373_bass_tlv), 391 + SOC_ENUM("Bass Channel", adau1373_bass_channel_enum), 392 + 393 + SOC_ENUM("3D Freq", adau1373_3d_cutoff_enum), 394 + SOC_ENUM("3D Level", adau1373_3d_level_enum), 395 + SOC_SINGLE("3D Playback Switch", ADAU1373_3D_CTRL2, 0, 1, 0), 396 + SOC_SINGLE_TLV("3D Playback Volume", ADAU1373_3D_CTRL2, 2, 7, 0, 397 + adau1373_3d_tlv), 398 + SOC_ENUM("3D Channel", adau1373_bass_channel_enum), 399 + 400 + SOC_SINGLE("Zero Cross Switch", ADAU1373_PWDN_CTRL3, 7, 1, 0), 401 + }; 402 + 403 + static const struct snd_kcontrol_new adau1373_lineout2_controls[] = { 404 + SOC_DOUBLE_R_TLV("Lineout2 Playback Volume", ADAU1373_LLINE_OUT(1), 405 + ADAU1373_RLINE_OUT(1), 0, 0x1f, 0, adau1373_out_tlv), 406 + SOC_ENUM("Lineout2 LR Mux", adau1373_lineout2_lr_mux_enum), 407 + }; 408 + 409 + static const struct snd_kcontrol_new adau1373_drc_controls[] = { 410 + SOC_ENUM("DRC1 Channel", adau1373_drc1_channel_enum), 411 + SOC_ENUM("DRC2 Channel", adau1373_drc2_channel_enum), 412 + SOC_ENUM("DRC3 Channel", adau1373_drc3_channel_enum), 413 + }; 414 + 415 + static int adau1373_pll_event(struct snd_soc_dapm_widget *w, 416 + struct snd_kcontrol *kcontrol, int event) 417 + { 418 + struct snd_soc_codec *codec = w->codec; 419 + unsigned int pll_id = w->name[3] - '1'; 420 + unsigned int val; 421 + 422 + if (SND_SOC_DAPM_EVENT_ON(event)) 423 + val = ADAU1373_PLL_CTRL6_PLL_EN; 424 + else 425 + val = 0; 426 + 427 + snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id), 428 + ADAU1373_PLL_CTRL6_PLL_EN, val); 429 + 430 + if (SND_SOC_DAPM_EVENT_ON(event)) 431 + mdelay(5); 432 + 433 + return 0; 434 + } 435 + 436 + static const char *adau1373_decimator_text[] = { 437 + "ADC", 438 + "DMIC1", 439 + }; 440 + 441 + static const struct soc_enum adau1373_decimator_enum = 442 + SOC_ENUM_SINGLE(0, 0, 2, adau1373_decimator_text); 443 + 444 + static const struct snd_kcontrol_new adau1373_decimator_mux = 445 + SOC_DAPM_ENUM_VIRT("Decimator Mux", adau1373_decimator_enum); 446 + 447 + static const struct snd_kcontrol_new adau1373_left_adc_mixer_controls[] = { 448 + SOC_DAPM_SINGLE("DAC1 Switch", ADAU1373_LADC_MIXER, 4, 1, 0), 449 + SOC_DAPM_SINGLE("Input 4 Switch", ADAU1373_LADC_MIXER, 3, 1, 0), 450 + SOC_DAPM_SINGLE("Input 3 Switch", ADAU1373_LADC_MIXER, 2, 1, 0), 451 + SOC_DAPM_SINGLE("Input 2 Switch", ADAU1373_LADC_MIXER, 1, 1, 0), 452 + SOC_DAPM_SINGLE("Input 1 Switch", ADAU1373_LADC_MIXER, 0, 1, 0), 453 + }; 454 + 455 + static const struct snd_kcontrol_new adau1373_right_adc_mixer_controls[] = { 456 + SOC_DAPM_SINGLE("DAC1 Switch", ADAU1373_RADC_MIXER, 4, 1, 0), 457 + SOC_DAPM_SINGLE("Input 4 Switch", ADAU1373_RADC_MIXER, 3, 1, 0), 458 + SOC_DAPM_SINGLE("Input 3 Switch", ADAU1373_RADC_MIXER, 2, 1, 0), 459 + SOC_DAPM_SINGLE("Input 2 Switch", ADAU1373_RADC_MIXER, 1, 1, 0), 460 + SOC_DAPM_SINGLE("Input 1 Switch", ADAU1373_RADC_MIXER, 0, 1, 0), 461 + }; 462 + 463 + #define DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(_name, _reg) \ 464 + const struct snd_kcontrol_new _name[] = { \ 465 + SOC_DAPM_SINGLE("Left DAC2 Switch", _reg, 7, 1, 0), \ 466 + SOC_DAPM_SINGLE("Right DAC2 Switch", _reg, 6, 1, 0), \ 467 + SOC_DAPM_SINGLE("Left DAC1 Switch", _reg, 5, 1, 0), \ 468 + SOC_DAPM_SINGLE("Right DAC1 Switch", _reg, 4, 1, 0), \ 469 + SOC_DAPM_SINGLE("Input 4 Bypass Switch", _reg, 3, 1, 0), \ 470 + SOC_DAPM_SINGLE("Input 3 Bypass Switch", _reg, 2, 1, 0), \ 471 + SOC_DAPM_SINGLE("Input 2 Bypass Switch", _reg, 1, 1, 0), \ 472 + SOC_DAPM_SINGLE("Input 1 Bypass Switch", _reg, 0, 1, 0), \ 473 + } 474 + 475 + static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_line1_mixer_controls, 476 + ADAU1373_LLINE1_MIX); 477 + static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_line1_mixer_controls, 478 + ADAU1373_RLINE1_MIX); 479 + static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_line2_mixer_controls, 480 + ADAU1373_LLINE2_MIX); 481 + static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_line2_mixer_controls, 482 + ADAU1373_RLINE2_MIX); 483 + static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_spk_mixer_controls, 484 + ADAU1373_LSPK_MIX); 485 + static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_spk_mixer_controls, 486 + ADAU1373_RSPK_MIX); 487 + static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_ep_mixer_controls, 488 + ADAU1373_EP_MIX); 489 + 490 + static const struct snd_kcontrol_new adau1373_left_hp_mixer_controls[] = { 491 + SOC_DAPM_SINGLE("Left DAC1 Switch", ADAU1373_LHP_MIX, 5, 1, 0), 492 + SOC_DAPM_SINGLE("Left DAC2 Switch", ADAU1373_LHP_MIX, 4, 1, 0), 493 + SOC_DAPM_SINGLE("Input 4 Bypass Switch", ADAU1373_LHP_MIX, 3, 1, 0), 494 + SOC_DAPM_SINGLE("Input 3 Bypass Switch", ADAU1373_LHP_MIX, 2, 1, 0), 495 + SOC_DAPM_SINGLE("Input 2 Bypass Switch", ADAU1373_LHP_MIX, 1, 1, 0), 496 + SOC_DAPM_SINGLE("Input 1 Bypass Switch", ADAU1373_LHP_MIX, 0, 1, 0), 497 + }; 498 + 499 + static const struct snd_kcontrol_new adau1373_right_hp_mixer_controls[] = { 500 + SOC_DAPM_SINGLE("Right DAC1 Switch", ADAU1373_RHP_MIX, 5, 1, 0), 501 + SOC_DAPM_SINGLE("Right DAC2 Switch", ADAU1373_RHP_MIX, 4, 1, 0), 502 + SOC_DAPM_SINGLE("Input 4 Bypass Switch", ADAU1373_RHP_MIX, 3, 1, 0), 503 + SOC_DAPM_SINGLE("Input 3 Bypass Switch", ADAU1373_RHP_MIX, 2, 1, 0), 504 + SOC_DAPM_SINGLE("Input 2 Bypass Switch", ADAU1373_RHP_MIX, 1, 1, 0), 505 + SOC_DAPM_SINGLE("Input 1 Bypass Switch", ADAU1373_RHP_MIX, 0, 1, 0), 506 + }; 507 + 508 + #define DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(_name, _reg) \ 509 + const struct snd_kcontrol_new _name[] = { \ 510 + SOC_DAPM_SINGLE("DMIC2 Swapped Switch", _reg, 6, 1, 0), \ 511 + SOC_DAPM_SINGLE("DMIC2 Switch", _reg, 5, 1, 0), \ 512 + SOC_DAPM_SINGLE("ADC/DMIC1 Swapped Switch", _reg, 4, 1, 0), \ 513 + SOC_DAPM_SINGLE("ADC/DMIC1 Switch", _reg, 3, 1, 0), \ 514 + SOC_DAPM_SINGLE("AIF3 Switch", _reg, 2, 1, 0), \ 515 + SOC_DAPM_SINGLE("AIF2 Switch", _reg, 1, 1, 0), \ 516 + SOC_DAPM_SINGLE("AIF1 Switch", _reg, 0, 1, 0), \ 517 + } 518 + 519 + static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel1_mixer_controls, 520 + ADAU1373_DIN_MIX_CTRL(0)); 521 + static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel2_mixer_controls, 522 + ADAU1373_DIN_MIX_CTRL(1)); 523 + static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel3_mixer_controls, 524 + ADAU1373_DIN_MIX_CTRL(2)); 525 + static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel4_mixer_controls, 526 + ADAU1373_DIN_MIX_CTRL(3)); 527 + static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel5_mixer_controls, 528 + ADAU1373_DIN_MIX_CTRL(4)); 529 + 530 + #define DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(_name, _reg) \ 531 + const struct snd_kcontrol_new _name[] = { \ 532 + SOC_DAPM_SINGLE("DSP Channel5 Switch", _reg, 4, 1, 0), \ 533 + SOC_DAPM_SINGLE("DSP Channel4 Switch", _reg, 3, 1, 0), \ 534 + SOC_DAPM_SINGLE("DSP Channel3 Switch", _reg, 2, 1, 0), \ 535 + SOC_DAPM_SINGLE("DSP Channel2 Switch", _reg, 1, 1, 0), \ 536 + SOC_DAPM_SINGLE("DSP Channel1 Switch", _reg, 0, 1, 0), \ 537 + } 538 + 539 + static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif1_mixer_controls, 540 + ADAU1373_DOUT_MIX_CTRL(0)); 541 + static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif2_mixer_controls, 542 + ADAU1373_DOUT_MIX_CTRL(1)); 543 + static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif3_mixer_controls, 544 + ADAU1373_DOUT_MIX_CTRL(2)); 545 + static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_dac1_mixer_controls, 546 + ADAU1373_DOUT_MIX_CTRL(3)); 547 + static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_dac2_mixer_controls, 548 + ADAU1373_DOUT_MIX_CTRL(4)); 549 + 550 + static const struct snd_soc_dapm_widget adau1373_dapm_widgets[] = { 551 + /* Datasheet claims Left ADC is bit 6 and Right ADC is bit 7, but that 552 + * doesn't seem to be the case. */ 553 + SND_SOC_DAPM_ADC("Left ADC", NULL, ADAU1373_PWDN_CTRL1, 7, 0), 554 + SND_SOC_DAPM_ADC("Right ADC", NULL, ADAU1373_PWDN_CTRL1, 6, 0), 555 + 556 + SND_SOC_DAPM_ADC("DMIC1", NULL, ADAU1373_DIGMICCTRL, 0, 0), 557 + SND_SOC_DAPM_ADC("DMIC2", NULL, ADAU1373_DIGMICCTRL, 2, 0), 558 + 559 + SND_SOC_DAPM_VIRT_MUX("Decimator Mux", SND_SOC_NOPM, 0, 0, 560 + &adau1373_decimator_mux), 561 + 562 + SND_SOC_DAPM_SUPPLY("MICBIAS2", ADAU1373_PWDN_CTRL1, 5, 0, NULL, 0), 563 + SND_SOC_DAPM_SUPPLY("MICBIAS1", ADAU1373_PWDN_CTRL1, 4, 0, NULL, 0), 564 + 565 + SND_SOC_DAPM_PGA("IN4PGA", ADAU1373_PWDN_CTRL1, 3, 0, NULL, 0), 566 + SND_SOC_DAPM_PGA("IN3PGA", ADAU1373_PWDN_CTRL1, 2, 0, NULL, 0), 567 + SND_SOC_DAPM_PGA("IN2PGA", ADAU1373_PWDN_CTRL1, 1, 0, NULL, 0), 568 + SND_SOC_DAPM_PGA("IN1PGA", ADAU1373_PWDN_CTRL1, 0, 0, NULL, 0), 569 + 570 + SND_SOC_DAPM_DAC("Left DAC2", NULL, ADAU1373_PWDN_CTRL2, 7, 0), 571 + SND_SOC_DAPM_DAC("Right DAC2", NULL, ADAU1373_PWDN_CTRL2, 6, 0), 572 + SND_SOC_DAPM_DAC("Left DAC1", NULL, ADAU1373_PWDN_CTRL2, 5, 0), 573 + SND_SOC_DAPM_DAC("Right DAC1", NULL, ADAU1373_PWDN_CTRL2, 4, 0), 574 + 575 + SOC_MIXER_ARRAY("Left ADC Mixer", SND_SOC_NOPM, 0, 0, 576 + adau1373_left_adc_mixer_controls), 577 + SOC_MIXER_ARRAY("Right ADC Mixer", SND_SOC_NOPM, 0, 0, 578 + adau1373_right_adc_mixer_controls), 579 + 580 + SOC_MIXER_ARRAY("Left Lineout2 Mixer", ADAU1373_PWDN_CTRL2, 3, 0, 581 + adau1373_left_line2_mixer_controls), 582 + SOC_MIXER_ARRAY("Right Lineout2 Mixer", ADAU1373_PWDN_CTRL2, 2, 0, 583 + adau1373_right_line2_mixer_controls), 584 + SOC_MIXER_ARRAY("Left Lineout1 Mixer", ADAU1373_PWDN_CTRL2, 1, 0, 585 + adau1373_left_line1_mixer_controls), 586 + SOC_MIXER_ARRAY("Right Lineout1 Mixer", ADAU1373_PWDN_CTRL2, 0, 0, 587 + adau1373_right_line1_mixer_controls), 588 + 589 + SOC_MIXER_ARRAY("Earpiece Mixer", ADAU1373_PWDN_CTRL3, 4, 0, 590 + adau1373_ep_mixer_controls), 591 + SOC_MIXER_ARRAY("Left Speaker Mixer", ADAU1373_PWDN_CTRL3, 3, 0, 592 + adau1373_left_spk_mixer_controls), 593 + SOC_MIXER_ARRAY("Right Speaker Mixer", ADAU1373_PWDN_CTRL3, 2, 0, 594 + adau1373_right_spk_mixer_controls), 595 + SOC_MIXER_ARRAY("Left Headphone Mixer", SND_SOC_NOPM, 0, 0, 596 + adau1373_left_hp_mixer_controls), 597 + SOC_MIXER_ARRAY("Right Headphone Mixer", SND_SOC_NOPM, 0, 0, 598 + adau1373_right_hp_mixer_controls), 599 + SND_SOC_DAPM_SUPPLY("Headphone Enable", ADAU1373_PWDN_CTRL3, 1, 0, 600 + NULL, 0), 601 + 602 + SND_SOC_DAPM_SUPPLY("AIF1 CLK", ADAU1373_SRC_DAI_CTRL(0), 0, 0, 603 + NULL, 0), 604 + SND_SOC_DAPM_SUPPLY("AIF2 CLK", ADAU1373_SRC_DAI_CTRL(1), 0, 0, 605 + NULL, 0), 606 + SND_SOC_DAPM_SUPPLY("AIF3 CLK", ADAU1373_SRC_DAI_CTRL(2), 0, 0, 607 + NULL, 0), 608 + SND_SOC_DAPM_SUPPLY("AIF1 IN SRC", ADAU1373_SRC_DAI_CTRL(0), 2, 0, 609 + NULL, 0), 610 + SND_SOC_DAPM_SUPPLY("AIF1 OUT SRC", ADAU1373_SRC_DAI_CTRL(0), 1, 0, 611 + NULL, 0), 612 + SND_SOC_DAPM_SUPPLY("AIF2 IN SRC", ADAU1373_SRC_DAI_CTRL(1), 2, 0, 613 + NULL, 0), 614 + SND_SOC_DAPM_SUPPLY("AIF2 OUT SRC", ADAU1373_SRC_DAI_CTRL(1), 1, 0, 615 + NULL, 0), 616 + SND_SOC_DAPM_SUPPLY("AIF3 IN SRC", ADAU1373_SRC_DAI_CTRL(2), 2, 0, 617 + NULL, 0), 618 + SND_SOC_DAPM_SUPPLY("AIF3 OUT SRC", ADAU1373_SRC_DAI_CTRL(2), 1, 0, 619 + NULL, 0), 620 + 621 + SND_SOC_DAPM_AIF_IN("AIF1 IN", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), 622 + SND_SOC_DAPM_AIF_OUT("AIF1 OUT", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), 623 + SND_SOC_DAPM_AIF_IN("AIF2 IN", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), 624 + SND_SOC_DAPM_AIF_OUT("AIF2 OUT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), 625 + SND_SOC_DAPM_AIF_IN("AIF3 IN", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0), 626 + SND_SOC_DAPM_AIF_OUT("AIF3 OUT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0), 627 + 628 + SOC_MIXER_ARRAY("DSP Channel1 Mixer", SND_SOC_NOPM, 0, 0, 629 + adau1373_dsp_channel1_mixer_controls), 630 + SOC_MIXER_ARRAY("DSP Channel2 Mixer", SND_SOC_NOPM, 0, 0, 631 + adau1373_dsp_channel2_mixer_controls), 632 + SOC_MIXER_ARRAY("DSP Channel3 Mixer", SND_SOC_NOPM, 0, 0, 633 + adau1373_dsp_channel3_mixer_controls), 634 + SOC_MIXER_ARRAY("DSP Channel4 Mixer", SND_SOC_NOPM, 0, 0, 635 + adau1373_dsp_channel4_mixer_controls), 636 + SOC_MIXER_ARRAY("DSP Channel5 Mixer", SND_SOC_NOPM, 0, 0, 637 + adau1373_dsp_channel5_mixer_controls), 638 + 639 + SOC_MIXER_ARRAY("AIF1 Mixer", SND_SOC_NOPM, 0, 0, 640 + adau1373_aif1_mixer_controls), 641 + SOC_MIXER_ARRAY("AIF2 Mixer", SND_SOC_NOPM, 0, 0, 642 + adau1373_aif2_mixer_controls), 643 + SOC_MIXER_ARRAY("AIF3 Mixer", SND_SOC_NOPM, 0, 0, 644 + adau1373_aif3_mixer_controls), 645 + SOC_MIXER_ARRAY("DAC1 Mixer", SND_SOC_NOPM, 0, 0, 646 + adau1373_dac1_mixer_controls), 647 + SOC_MIXER_ARRAY("DAC2 Mixer", SND_SOC_NOPM, 0, 0, 648 + adau1373_dac2_mixer_controls), 649 + 650 + SND_SOC_DAPM_SUPPLY("DSP", ADAU1373_DIGEN, 4, 0, NULL, 0), 651 + SND_SOC_DAPM_SUPPLY("Recording Engine B", ADAU1373_DIGEN, 3, 0, NULL, 0), 652 + SND_SOC_DAPM_SUPPLY("Recording Engine A", ADAU1373_DIGEN, 2, 0, NULL, 0), 653 + SND_SOC_DAPM_SUPPLY("Playback Engine B", ADAU1373_DIGEN, 1, 0, NULL, 0), 654 + SND_SOC_DAPM_SUPPLY("Playback Engine A", ADAU1373_DIGEN, 0, 0, NULL, 0), 655 + 656 + SND_SOC_DAPM_SUPPLY("PLL1", SND_SOC_NOPM, 0, 0, adau1373_pll_event, 657 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 658 + SND_SOC_DAPM_SUPPLY("PLL2", SND_SOC_NOPM, 0, 0, adau1373_pll_event, 659 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 660 + SND_SOC_DAPM_SUPPLY("SYSCLK1", ADAU1373_CLK_SRC_DIV(0), 7, 0, NULL, 0), 661 + SND_SOC_DAPM_SUPPLY("SYSCLK2", ADAU1373_CLK_SRC_DIV(1), 7, 0, NULL, 0), 662 + 663 + SND_SOC_DAPM_INPUT("AIN1L"), 664 + SND_SOC_DAPM_INPUT("AIN1R"), 665 + SND_SOC_DAPM_INPUT("AIN2L"), 666 + SND_SOC_DAPM_INPUT("AIN2R"), 667 + SND_SOC_DAPM_INPUT("AIN3L"), 668 + SND_SOC_DAPM_INPUT("AIN3R"), 669 + SND_SOC_DAPM_INPUT("AIN4L"), 670 + SND_SOC_DAPM_INPUT("AIN4R"), 671 + 672 + SND_SOC_DAPM_INPUT("DMIC1DAT"), 673 + SND_SOC_DAPM_INPUT("DMIC2DAT"), 674 + 675 + SND_SOC_DAPM_OUTPUT("LOUT1L"), 676 + SND_SOC_DAPM_OUTPUT("LOUT1R"), 677 + SND_SOC_DAPM_OUTPUT("LOUT2L"), 678 + SND_SOC_DAPM_OUTPUT("LOUT2R"), 679 + SND_SOC_DAPM_OUTPUT("HPL"), 680 + SND_SOC_DAPM_OUTPUT("HPR"), 681 + SND_SOC_DAPM_OUTPUT("SPKL"), 682 + SND_SOC_DAPM_OUTPUT("SPKR"), 683 + SND_SOC_DAPM_OUTPUT("EP"), 684 + }; 685 + 686 + static int adau1373_check_aif_clk(struct snd_soc_dapm_widget *source, 687 + struct snd_soc_dapm_widget *sink) 688 + { 689 + struct snd_soc_codec *codec = source->codec; 690 + struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec); 691 + unsigned int dai; 692 + const char *clk; 693 + 694 + dai = sink->name[3] - '1'; 695 + 696 + if (!adau1373->dais[dai].master) 697 + return 0; 698 + 699 + if (adau1373->dais[dai].clk_src == ADAU1373_CLK_SRC_PLL1) 700 + clk = "SYSCLK1"; 701 + else 702 + clk = "SYSCLK2"; 703 + 704 + return strcmp(source->name, clk) == 0; 705 + } 706 + 707 + static int adau1373_check_src(struct snd_soc_dapm_widget *source, 708 + struct snd_soc_dapm_widget *sink) 709 + { 710 + struct snd_soc_codec *codec = source->codec; 711 + struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec); 712 + unsigned int dai; 713 + 714 + dai = sink->name[3] - '1'; 715 + 716 + return adau1373->dais[dai].enable_src; 717 + } 718 + 719 + #define DSP_CHANNEL_MIXER_ROUTES(_sink) \ 720 + { _sink, "DMIC2 Swapped Switch", "DMIC2" }, \ 721 + { _sink, "DMIC2 Switch", "DMIC2" }, \ 722 + { _sink, "ADC/DMIC1 Swapped Switch", "Decimator Mux" }, \ 723 + { _sink, "ADC/DMIC1 Switch", "Decimator Mux" }, \ 724 + { _sink, "AIF1 Switch", "AIF1 IN" }, \ 725 + { _sink, "AIF2 Switch", "AIF2 IN" }, \ 726 + { _sink, "AIF3 Switch", "AIF3 IN" } 727 + 728 + #define DSP_OUTPUT_MIXER_ROUTES(_sink) \ 729 + { _sink, "DSP Channel1 Switch", "DSP Channel1 Mixer" }, \ 730 + { _sink, "DSP Channel2 Switch", "DSP Channel2 Mixer" }, \ 731 + { _sink, "DSP Channel3 Switch", "DSP Channel3 Mixer" }, \ 732 + { _sink, "DSP Channel4 Switch", "DSP Channel4 Mixer" }, \ 733 + { _sink, "DSP Channel5 Switch", "DSP Channel5 Mixer" } 734 + 735 + #define LEFT_OUTPUT_MIXER_ROUTES(_sink) \ 736 + { _sink, "Right DAC2 Switch", "Right DAC2" }, \ 737 + { _sink, "Left DAC2 Switch", "Left DAC2" }, \ 738 + { _sink, "Right DAC1 Switch", "Right DAC1" }, \ 739 + { _sink, "Left DAC1 Switch", "Left DAC1" }, \ 740 + { _sink, "Input 1 Bypass Switch", "IN1PGA" }, \ 741 + { _sink, "Input 2 Bypass Switch", "IN2PGA" }, \ 742 + { _sink, "Input 3 Bypass Switch", "IN3PGA" }, \ 743 + { _sink, "Input 4 Bypass Switch", "IN4PGA" } 744 + 745 + #define RIGHT_OUTPUT_MIXER_ROUTES(_sink) \ 746 + { _sink, "Right DAC2 Switch", "Right DAC2" }, \ 747 + { _sink, "Left DAC2 Switch", "Left DAC2" }, \ 748 + { _sink, "Right DAC1 Switch", "Right DAC1" }, \ 749 + { _sink, "Left DAC1 Switch", "Left DAC1" }, \ 750 + { _sink, "Input 1 Bypass Switch", "IN1PGA" }, \ 751 + { _sink, "Input 2 Bypass Switch", "IN2PGA" }, \ 752 + { _sink, "Input 3 Bypass Switch", "IN3PGA" }, \ 753 + { _sink, "Input 4 Bypass Switch", "IN4PGA" } 754 + 755 + static const struct snd_soc_dapm_route adau1373_dapm_routes[] = { 756 + { "Left ADC Mixer", "DAC1 Switch", "Left DAC1" }, 757 + { "Left ADC Mixer", "Input 1 Switch", "IN1PGA" }, 758 + { "Left ADC Mixer", "Input 2 Switch", "IN2PGA" }, 759 + { "Left ADC Mixer", "Input 3 Switch", "IN3PGA" }, 760 + { "Left ADC Mixer", "Input 4 Switch", "IN4PGA" }, 761 + 762 + { "Right ADC Mixer", "DAC1 Switch", "Right DAC1" }, 763 + { "Right ADC Mixer", "Input 1 Switch", "IN1PGA" }, 764 + { "Right ADC Mixer", "Input 2 Switch", "IN2PGA" }, 765 + { "Right ADC Mixer", "Input 3 Switch", "IN3PGA" }, 766 + { "Right ADC Mixer", "Input 4 Switch", "IN4PGA" }, 767 + 768 + { "Left ADC", NULL, "Left ADC Mixer" }, 769 + { "Right ADC", NULL, "Right ADC Mixer" }, 770 + 771 + { "Decimator Mux", "ADC", "Left ADC" }, 772 + { "Decimator Mux", "ADC", "Right ADC" }, 773 + { "Decimator Mux", "DMIC1", "DMIC1" }, 774 + 775 + DSP_CHANNEL_MIXER_ROUTES("DSP Channel1 Mixer"), 776 + DSP_CHANNEL_MIXER_ROUTES("DSP Channel2 Mixer"), 777 + DSP_CHANNEL_MIXER_ROUTES("DSP Channel3 Mixer"), 778 + DSP_CHANNEL_MIXER_ROUTES("DSP Channel4 Mixer"), 779 + DSP_CHANNEL_MIXER_ROUTES("DSP Channel5 Mixer"), 780 + 781 + DSP_OUTPUT_MIXER_ROUTES("AIF1 Mixer"), 782 + DSP_OUTPUT_MIXER_ROUTES("AIF2 Mixer"), 783 + DSP_OUTPUT_MIXER_ROUTES("AIF3 Mixer"), 784 + DSP_OUTPUT_MIXER_ROUTES("DAC1 Mixer"), 785 + DSP_OUTPUT_MIXER_ROUTES("DAC2 Mixer"), 786 + 787 + { "AIF1 OUT", NULL, "AIF1 Mixer" }, 788 + { "AIF2 OUT", NULL, "AIF2 Mixer" }, 789 + { "AIF3 OUT", NULL, "AIF3 Mixer" }, 790 + { "Left DAC1", NULL, "DAC1 Mixer" }, 791 + { "Right DAC1", NULL, "DAC1 Mixer" }, 792 + { "Left DAC2", NULL, "DAC2 Mixer" }, 793 + { "Right DAC2", NULL, "DAC2 Mixer" }, 794 + 795 + LEFT_OUTPUT_MIXER_ROUTES("Left Lineout1 Mixer"), 796 + RIGHT_OUTPUT_MIXER_ROUTES("Right Lineout1 Mixer"), 797 + LEFT_OUTPUT_MIXER_ROUTES("Left Lineout2 Mixer"), 798 + RIGHT_OUTPUT_MIXER_ROUTES("Right Lineout2 Mixer"), 799 + LEFT_OUTPUT_MIXER_ROUTES("Left Speaker Mixer"), 800 + RIGHT_OUTPUT_MIXER_ROUTES("Right Speaker Mixer"), 801 + 802 + { "Left Headphone Mixer", "Left DAC2 Switch", "Left DAC2" }, 803 + { "Left Headphone Mixer", "Left DAC1 Switch", "Left DAC1" }, 804 + { "Left Headphone Mixer", "Input 1 Bypass Switch", "IN1PGA" }, 805 + { "Left Headphone Mixer", "Input 2 Bypass Switch", "IN2PGA" }, 806 + { "Left Headphone Mixer", "Input 3 Bypass Switch", "IN3PGA" }, 807 + { "Left Headphone Mixer", "Input 4 Bypass Switch", "IN4PGA" }, 808 + { "Right Headphone Mixer", "Right DAC2 Switch", "Right DAC2" }, 809 + { "Right Headphone Mixer", "Right DAC1 Switch", "Right DAC1" }, 810 + { "Right Headphone Mixer", "Input 1 Bypass Switch", "IN1PGA" }, 811 + { "Right Headphone Mixer", "Input 2 Bypass Switch", "IN2PGA" }, 812 + { "Right Headphone Mixer", "Input 3 Bypass Switch", "IN3PGA" }, 813 + { "Right Headphone Mixer", "Input 4 Bypass Switch", "IN4PGA" }, 814 + 815 + { "Left Headphone Mixer", NULL, "Headphone Enable" }, 816 + { "Right Headphone Mixer", NULL, "Headphone Enable" }, 817 + 818 + { "Earpiece Mixer", "Right DAC2 Switch", "Right DAC2" }, 819 + { "Earpiece Mixer", "Left DAC2 Switch", "Left DAC2" }, 820 + { "Earpiece Mixer", "Right DAC1 Switch", "Right DAC1" }, 821 + { "Earpiece Mixer", "Left DAC1 Switch", "Left DAC1" }, 822 + { "Earpiece Mixer", "Input 1 Bypass Switch", "IN1PGA" }, 823 + { "Earpiece Mixer", "Input 2 Bypass Switch", "IN2PGA" }, 824 + { "Earpiece Mixer", "Input 3 Bypass Switch", "IN3PGA" }, 825 + { "Earpiece Mixer", "Input 4 Bypass Switch", "IN4PGA" }, 826 + 827 + { "LOUT1L", NULL, "Left Lineout1 Mixer" }, 828 + { "LOUT1R", NULL, "Right Lineout1 Mixer" }, 829 + { "LOUT2L", NULL, "Left Lineout2 Mixer" }, 830 + { "LOUT2R", NULL, "Right Lineout2 Mixer" }, 831 + { "SPKL", NULL, "Left Speaker Mixer" }, 832 + { "SPKR", NULL, "Right Speaker Mixer" }, 833 + { "HPL", NULL, "Left Headphone Mixer" }, 834 + { "HPR", NULL, "Right Headphone Mixer" }, 835 + { "EP", NULL, "Earpiece Mixer" }, 836 + 837 + { "IN1PGA", NULL, "AIN1L" }, 838 + { "IN2PGA", NULL, "AIN2L" }, 839 + { "IN3PGA", NULL, "AIN3L" }, 840 + { "IN4PGA", NULL, "AIN4L" }, 841 + { "IN1PGA", NULL, "AIN1R" }, 842 + { "IN2PGA", NULL, "AIN2R" }, 843 + { "IN3PGA", NULL, "AIN3R" }, 844 + { "IN4PGA", NULL, "AIN4R" }, 845 + 846 + { "SYSCLK1", NULL, "PLL1" }, 847 + { "SYSCLK2", NULL, "PLL2" }, 848 + 849 + { "Left DAC1", NULL, "SYSCLK1" }, 850 + { "Right DAC1", NULL, "SYSCLK1" }, 851 + { "Left DAC2", NULL, "SYSCLK1" }, 852 + { "Right DAC2", NULL, "SYSCLK1" }, 853 + { "Left ADC", NULL, "SYSCLK1" }, 854 + { "Right ADC", NULL, "SYSCLK1" }, 855 + 856 + { "DSP", NULL, "SYSCLK1" }, 857 + 858 + { "AIF1 Mixer", NULL, "DSP" }, 859 + { "AIF2 Mixer", NULL, "DSP" }, 860 + { "AIF3 Mixer", NULL, "DSP" }, 861 + { "DAC1 Mixer", NULL, "DSP" }, 862 + { "DAC2 Mixer", NULL, "DSP" }, 863 + { "DAC1 Mixer", NULL, "Playback Engine A" }, 864 + { "DAC2 Mixer", NULL, "Playback Engine B" }, 865 + { "Left ADC Mixer", NULL, "Recording Engine A" }, 866 + { "Right ADC Mixer", NULL, "Recording Engine A" }, 867 + 868 + { "AIF1 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk }, 869 + { "AIF2 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk }, 870 + { "AIF3 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk }, 871 + { "AIF1 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk }, 872 + { "AIF2 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk }, 873 + { "AIF3 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk }, 874 + 875 + { "AIF1 IN", NULL, "AIF1 CLK" }, 876 + { "AIF1 OUT", NULL, "AIF1 CLK" }, 877 + { "AIF2 IN", NULL, "AIF2 CLK" }, 878 + { "AIF2 OUT", NULL, "AIF2 CLK" }, 879 + { "AIF3 IN", NULL, "AIF3 CLK" }, 880 + { "AIF3 OUT", NULL, "AIF3 CLK" }, 881 + { "AIF1 IN", NULL, "AIF1 IN SRC", adau1373_check_src }, 882 + { "AIF1 OUT", NULL, "AIF1 OUT SRC", adau1373_check_src }, 883 + { "AIF2 IN", NULL, "AIF2 IN SRC", adau1373_check_src }, 884 + { "AIF2 OUT", NULL, "AIF2 OUT SRC", adau1373_check_src }, 885 + { "AIF3 IN", NULL, "AIF3 IN SRC", adau1373_check_src }, 886 + { "AIF3 OUT", NULL, "AIF3 OUT SRC", adau1373_check_src }, 887 + 888 + { "DMIC1", NULL, "DMIC1DAT" }, 889 + { "DMIC1", NULL, "SYSCLK1" }, 890 + { "DMIC1", NULL, "Recording Engine A" }, 891 + { "DMIC2", NULL, "DMIC2DAT" }, 892 + { "DMIC2", NULL, "SYSCLK1" }, 893 + { "DMIC2", NULL, "Recording Engine B" }, 894 + }; 895 + 896 + static int adau1373_hw_params(struct snd_pcm_substream *substream, 897 + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 898 + { 899 + struct snd_soc_codec *codec = dai->codec; 900 + struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec); 901 + struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id]; 902 + unsigned int div; 903 + unsigned int freq; 904 + unsigned int ctrl; 905 + 906 + freq = adau1373_dai->sysclk; 907 + 908 + if (freq % params_rate(params) != 0) 909 + return -EINVAL; 910 + 911 + switch (freq / params_rate(params)) { 912 + case 1024: /* sysclk / 256 */ 913 + div = 0; 914 + break; 915 + case 1536: /* 2/3 sysclk / 256 */ 916 + div = 1; 917 + break; 918 + case 2048: /* 1/2 sysclk / 256 */ 919 + div = 2; 920 + break; 921 + case 3072: /* 1/3 sysclk / 256 */ 922 + div = 3; 923 + break; 924 + case 4096: /* 1/4 sysclk / 256 */ 925 + div = 4; 926 + break; 927 + case 6144: /* 1/6 sysclk / 256 */ 928 + div = 5; 929 + break; 930 + case 5632: /* 2/11 sysclk / 256 */ 931 + div = 6; 932 + break; 933 + default: 934 + return -EINVAL; 935 + } 936 + 937 + adau1373_dai->enable_src = (div != 0); 938 + 939 + snd_soc_update_bits(codec, ADAU1373_BCLKDIV(dai->id), 940 + ~ADAU1373_BCLKDIV_SOURCE, (div << 2) | ADAU1373_BCLKDIV_64); 941 + 942 + switch (params_format(params)) { 943 + case SNDRV_PCM_FORMAT_S16_LE: 944 + ctrl = ADAU1373_DAI_WLEN_16; 945 + break; 946 + case SNDRV_PCM_FORMAT_S20_3LE: 947 + ctrl = ADAU1373_DAI_WLEN_20; 948 + break; 949 + case SNDRV_PCM_FORMAT_S24_LE: 950 + ctrl = ADAU1373_DAI_WLEN_24; 951 + break; 952 + case SNDRV_PCM_FORMAT_S32_LE: 953 + ctrl = ADAU1373_DAI_WLEN_32; 954 + break; 955 + default: 956 + return -EINVAL; 957 + } 958 + 959 + return snd_soc_update_bits(codec, ADAU1373_DAI(dai->id), 960 + ADAU1373_DAI_WLEN_MASK, ctrl); 961 + } 962 + 963 + static int adau1373_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) 964 + { 965 + struct snd_soc_codec *codec = dai->codec; 966 + struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec); 967 + struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id]; 968 + unsigned int ctrl; 969 + 970 + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 971 + case SND_SOC_DAIFMT_CBM_CFM: 972 + ctrl = ADAU1373_DAI_MASTER; 973 + adau1373_dai->master = true; 974 + break; 975 + case SND_SOC_DAIFMT_CBS_CFS: 976 + ctrl = 0; 977 + adau1373_dai->master = true; 978 + break; 979 + default: 980 + return -EINVAL; 981 + } 982 + 983 + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 984 + case SND_SOC_DAIFMT_I2S: 985 + ctrl |= ADAU1373_DAI_FORMAT_I2S; 986 + break; 987 + case SND_SOC_DAIFMT_LEFT_J: 988 + ctrl |= ADAU1373_DAI_FORMAT_LEFT_J; 989 + break; 990 + case SND_SOC_DAIFMT_RIGHT_J: 991 + ctrl |= ADAU1373_DAI_FORMAT_RIGHT_J; 992 + break; 993 + case SND_SOC_DAIFMT_DSP_B: 994 + ctrl |= ADAU1373_DAI_FORMAT_DSP; 995 + break; 996 + default: 997 + return -EINVAL; 998 + } 999 + 1000 + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 1001 + case SND_SOC_DAIFMT_NB_NF: 1002 + break; 1003 + case SND_SOC_DAIFMT_IB_NF: 1004 + ctrl |= ADAU1373_DAI_INVERT_BCLK; 1005 + break; 1006 + case SND_SOC_DAIFMT_NB_IF: 1007 + ctrl |= ADAU1373_DAI_INVERT_LRCLK; 1008 + break; 1009 + case SND_SOC_DAIFMT_IB_IF: 1010 + ctrl |= ADAU1373_DAI_INVERT_LRCLK | ADAU1373_DAI_INVERT_BCLK; 1011 + break; 1012 + default: 1013 + return -EINVAL; 1014 + } 1015 + 1016 + snd_soc_update_bits(codec, ADAU1373_DAI(dai->id), 1017 + ~ADAU1373_DAI_WLEN_MASK, ctrl); 1018 + 1019 + return 0; 1020 + } 1021 + 1022 + static int adau1373_set_dai_sysclk(struct snd_soc_dai *dai, 1023 + int clk_id, unsigned int freq, int dir) 1024 + { 1025 + struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(dai->codec); 1026 + struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id]; 1027 + 1028 + switch (clk_id) { 1029 + case ADAU1373_CLK_SRC_PLL1: 1030 + case ADAU1373_CLK_SRC_PLL2: 1031 + break; 1032 + default: 1033 + return -EINVAL; 1034 + } 1035 + 1036 + adau1373_dai->sysclk = freq; 1037 + adau1373_dai->clk_src = clk_id; 1038 + 1039 + snd_soc_update_bits(dai->codec, ADAU1373_BCLKDIV(dai->id), 1040 + ADAU1373_BCLKDIV_SOURCE, clk_id << 5); 1041 + 1042 + return 0; 1043 + } 1044 + 1045 + static const struct snd_soc_dai_ops adau1373_dai_ops = { 1046 + .hw_params = adau1373_hw_params, 1047 + .set_sysclk = adau1373_set_dai_sysclk, 1048 + .set_fmt = adau1373_set_dai_fmt, 1049 + }; 1050 + 1051 + #define ADAU1373_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 1052 + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 1053 + 1054 + static struct snd_soc_dai_driver adau1373_dai_driver[] = { 1055 + { 1056 + .id = 0, 1057 + .name = "adau1373-aif1", 1058 + .playback = { 1059 + .stream_name = "AIF1 Playback", 1060 + .channels_min = 2, 1061 + .channels_max = 2, 1062 + .rates = SNDRV_PCM_RATE_8000_48000, 1063 + .formats = ADAU1373_FORMATS, 1064 + }, 1065 + .capture = { 1066 + .stream_name = "AIF1 Capture", 1067 + .channels_min = 2, 1068 + .channels_max = 2, 1069 + .rates = SNDRV_PCM_RATE_8000_48000, 1070 + .formats = ADAU1373_FORMATS, 1071 + }, 1072 + .ops = &adau1373_dai_ops, 1073 + .symmetric_rates = 1, 1074 + }, 1075 + { 1076 + .id = 1, 1077 + .name = "adau1373-aif2", 1078 + .playback = { 1079 + .stream_name = "AIF2 Playback", 1080 + .channels_min = 2, 1081 + .channels_max = 2, 1082 + .rates = SNDRV_PCM_RATE_8000_48000, 1083 + .formats = ADAU1373_FORMATS, 1084 + }, 1085 + .capture = { 1086 + .stream_name = "AIF2 Capture", 1087 + .channels_min = 2, 1088 + .channels_max = 2, 1089 + .rates = SNDRV_PCM_RATE_8000_48000, 1090 + .formats = ADAU1373_FORMATS, 1091 + }, 1092 + .ops = &adau1373_dai_ops, 1093 + .symmetric_rates = 1, 1094 + }, 1095 + { 1096 + .id = 2, 1097 + .name = "adau1373-aif3", 1098 + .playback = { 1099 + .stream_name = "AIF3 Playback", 1100 + .channels_min = 2, 1101 + .channels_max = 2, 1102 + .rates = SNDRV_PCM_RATE_8000_48000, 1103 + .formats = ADAU1373_FORMATS, 1104 + }, 1105 + .capture = { 1106 + .stream_name = "AIF3 Capture", 1107 + .channels_min = 2, 1108 + .channels_max = 2, 1109 + .rates = SNDRV_PCM_RATE_8000_48000, 1110 + .formats = ADAU1373_FORMATS, 1111 + }, 1112 + .ops = &adau1373_dai_ops, 1113 + .symmetric_rates = 1, 1114 + }, 1115 + }; 1116 + 1117 + static int adau1373_set_pll(struct snd_soc_codec *codec, int pll_id, 1118 + int source, unsigned int freq_in, unsigned int freq_out) 1119 + { 1120 + unsigned int dpll_div = 0; 1121 + unsigned int x, r, n, m, i, j, mode; 1122 + 1123 + switch (pll_id) { 1124 + case ADAU1373_PLL1: 1125 + case ADAU1373_PLL2: 1126 + break; 1127 + default: 1128 + return -EINVAL; 1129 + } 1130 + 1131 + switch (source) { 1132 + case ADAU1373_PLL_SRC_BCLK1: 1133 + case ADAU1373_PLL_SRC_BCLK2: 1134 + case ADAU1373_PLL_SRC_BCLK3: 1135 + case ADAU1373_PLL_SRC_LRCLK1: 1136 + case ADAU1373_PLL_SRC_LRCLK2: 1137 + case ADAU1373_PLL_SRC_LRCLK3: 1138 + case ADAU1373_PLL_SRC_MCLK1: 1139 + case ADAU1373_PLL_SRC_MCLK2: 1140 + case ADAU1373_PLL_SRC_GPIO1: 1141 + case ADAU1373_PLL_SRC_GPIO2: 1142 + case ADAU1373_PLL_SRC_GPIO3: 1143 + case ADAU1373_PLL_SRC_GPIO4: 1144 + break; 1145 + default: 1146 + return -EINVAL; 1147 + } 1148 + 1149 + if (freq_in < 7813 || freq_in > 27000000) 1150 + return -EINVAL; 1151 + 1152 + if (freq_out < 45158000 || freq_out > 49152000) 1153 + return -EINVAL; 1154 + 1155 + /* APLL input needs to be >= 8Mhz, so in case freq_in is less we use the 1156 + * DPLL to get it there. DPLL_out = (DPLL_in / div) * 1024 */ 1157 + while (freq_in < 8000000) { 1158 + freq_in *= 2; 1159 + dpll_div++; 1160 + } 1161 + 1162 + if (freq_out % freq_in != 0) { 1163 + /* fout = fin * (r + (n/m)) / x */ 1164 + x = DIV_ROUND_UP(freq_in, 13500000); 1165 + freq_in /= x; 1166 + r = freq_out / freq_in; 1167 + i = freq_out % freq_in; 1168 + j = gcd(i, freq_in); 1169 + n = i / j; 1170 + m = freq_in / j; 1171 + x--; 1172 + mode = 1; 1173 + } else { 1174 + /* fout = fin / r */ 1175 + r = freq_out / freq_in; 1176 + n = 0; 1177 + m = 0; 1178 + x = 0; 1179 + mode = 0; 1180 + } 1181 + 1182 + if (r < 2 || r > 8 || x > 3 || m > 0xffff || n > 0xffff) 1183 + return -EINVAL; 1184 + 1185 + if (dpll_div) { 1186 + dpll_div = 11 - dpll_div; 1187 + snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id), 1188 + ADAU1373_PLL_CTRL6_DPLL_BYPASS, 0); 1189 + } else { 1190 + snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id), 1191 + ADAU1373_PLL_CTRL6_DPLL_BYPASS, 1192 + ADAU1373_PLL_CTRL6_DPLL_BYPASS); 1193 + } 1194 + 1195 + snd_soc_write(codec, ADAU1373_DPLL_CTRL(pll_id), 1196 + (source << 4) | dpll_div); 1197 + snd_soc_write(codec, ADAU1373_PLL_CTRL1(pll_id), (m >> 8) & 0xff); 1198 + snd_soc_write(codec, ADAU1373_PLL_CTRL2(pll_id), m & 0xff); 1199 + snd_soc_write(codec, ADAU1373_PLL_CTRL3(pll_id), (n >> 8) & 0xff); 1200 + snd_soc_write(codec, ADAU1373_PLL_CTRL4(pll_id), n & 0xff); 1201 + snd_soc_write(codec, ADAU1373_PLL_CTRL5(pll_id), 1202 + (r << 3) | (x << 1) | mode); 1203 + 1204 + /* Set sysclk to pll_rate / 4 */ 1205 + snd_soc_update_bits(codec, ADAU1373_CLK_SRC_DIV(pll_id), 0x3f, 0x09); 1206 + 1207 + return 0; 1208 + } 1209 + 1210 + static void adau1373_load_drc_settings(struct snd_soc_codec *codec, 1211 + unsigned int nr, uint8_t *drc) 1212 + { 1213 + unsigned int i; 1214 + 1215 + for (i = 0; i < ADAU1373_DRC_SIZE; ++i) 1216 + snd_soc_write(codec, ADAU1373_DRC(nr) + i, drc[i]); 1217 + } 1218 + 1219 + static bool adau1373_valid_micbias(enum adau1373_micbias_voltage micbias) 1220 + { 1221 + switch (micbias) { 1222 + case ADAU1373_MICBIAS_2_9V: 1223 + case ADAU1373_MICBIAS_2_2V: 1224 + case ADAU1373_MICBIAS_2_6V: 1225 + case ADAU1373_MICBIAS_1_8V: 1226 + return true; 1227 + default: 1228 + break; 1229 + } 1230 + return false; 1231 + } 1232 + 1233 + static int adau1373_probe(struct snd_soc_codec *codec) 1234 + { 1235 + struct adau1373_platform_data *pdata = codec->dev->platform_data; 1236 + bool lineout_differential = false; 1237 + unsigned int val; 1238 + int ret; 1239 + int i; 1240 + 1241 + ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); 1242 + if (ret) { 1243 + dev_err(codec->dev, "failed to set cache I/O: %d\n", ret); 1244 + return ret; 1245 + } 1246 + 1247 + codec->dapm.idle_bias_off = true; 1248 + 1249 + if (pdata) { 1250 + if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting)) 1251 + return -EINVAL; 1252 + 1253 + if (!adau1373_valid_micbias(pdata->micbias1) || 1254 + !adau1373_valid_micbias(pdata->micbias2)) 1255 + return -EINVAL; 1256 + 1257 + for (i = 0; i < pdata->num_drc; ++i) { 1258 + adau1373_load_drc_settings(codec, i, 1259 + pdata->drc_setting[i]); 1260 + } 1261 + 1262 + snd_soc_add_controls(codec, adau1373_drc_controls, 1263 + pdata->num_drc); 1264 + 1265 + val = 0; 1266 + for (i = 0; i < 4; ++i) { 1267 + if (pdata->input_differential[i]) 1268 + val |= BIT(i); 1269 + } 1270 + snd_soc_write(codec, ADAU1373_INPUT_MODE, val); 1271 + 1272 + val = 0; 1273 + if (pdata->lineout_differential) 1274 + val |= ADAU1373_OUTPUT_CTRL_LDIFF; 1275 + if (pdata->lineout_ground_sense) 1276 + val |= ADAU1373_OUTPUT_CTRL_LNFBEN; 1277 + snd_soc_write(codec, ADAU1373_OUTPUT_CTRL, val); 1278 + 1279 + lineout_differential = pdata->lineout_differential; 1280 + 1281 + snd_soc_write(codec, ADAU1373_EP_CTRL, 1282 + (pdata->micbias1 << ADAU1373_EP_CTRL_MICBIAS1_OFFSET) | 1283 + (pdata->micbias2 << ADAU1373_EP_CTRL_MICBIAS2_OFFSET)); 1284 + } 1285 + 1286 + if (!lineout_differential) { 1287 + snd_soc_add_controls(codec, adau1373_lineout2_controls, 1288 + ARRAY_SIZE(adau1373_lineout2_controls)); 1289 + } 1290 + 1291 + snd_soc_write(codec, ADAU1373_ADC_CTRL, 1292 + ADAU1373_ADC_CTRL_RESET_FORCE | ADAU1373_ADC_CTRL_PEAK_DETECT); 1293 + 1294 + return 0; 1295 + } 1296 + 1297 + static int adau1373_set_bias_level(struct snd_soc_codec *codec, 1298 + enum snd_soc_bias_level level) 1299 + { 1300 + switch (level) { 1301 + case SND_SOC_BIAS_ON: 1302 + break; 1303 + case SND_SOC_BIAS_PREPARE: 1304 + break; 1305 + case SND_SOC_BIAS_STANDBY: 1306 + snd_soc_update_bits(codec, ADAU1373_PWDN_CTRL3, 1307 + ADAU1373_PWDN_CTRL3_PWR_EN, ADAU1373_PWDN_CTRL3_PWR_EN); 1308 + break; 1309 + case SND_SOC_BIAS_OFF: 1310 + snd_soc_update_bits(codec, ADAU1373_PWDN_CTRL3, 1311 + ADAU1373_PWDN_CTRL3_PWR_EN, 0); 1312 + break; 1313 + } 1314 + codec->dapm.bias_level = level; 1315 + return 0; 1316 + } 1317 + 1318 + static int adau1373_remove(struct snd_soc_codec *codec) 1319 + { 1320 + adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF); 1321 + return 0; 1322 + } 1323 + 1324 + static int adau1373_suspend(struct snd_soc_codec *codec, pm_message_t state) 1325 + { 1326 + return adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF); 1327 + } 1328 + 1329 + static int adau1373_resume(struct snd_soc_codec *codec) 1330 + { 1331 + adau1373_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1332 + snd_soc_cache_sync(codec); 1333 + 1334 + return 0; 1335 + } 1336 + 1337 + static struct snd_soc_codec_driver adau1373_codec_driver = { 1338 + .probe = adau1373_probe, 1339 + .remove = adau1373_remove, 1340 + .suspend = adau1373_suspend, 1341 + .resume = adau1373_resume, 1342 + .set_bias_level = adau1373_set_bias_level, 1343 + .reg_cache_size = ARRAY_SIZE(adau1373_default_regs), 1344 + .reg_cache_default = adau1373_default_regs, 1345 + .reg_word_size = sizeof(uint8_t), 1346 + 1347 + .set_pll = adau1373_set_pll, 1348 + 1349 + .controls = adau1373_controls, 1350 + .num_controls = ARRAY_SIZE(adau1373_controls), 1351 + .dapm_widgets = adau1373_dapm_widgets, 1352 + .num_dapm_widgets = ARRAY_SIZE(adau1373_dapm_widgets), 1353 + .dapm_routes = adau1373_dapm_routes, 1354 + .num_dapm_routes = ARRAY_SIZE(adau1373_dapm_routes), 1355 + }; 1356 + 1357 + static int __devinit adau1373_i2c_probe(struct i2c_client *client, 1358 + const struct i2c_device_id *id) 1359 + { 1360 + struct adau1373 *adau1373; 1361 + int ret; 1362 + 1363 + adau1373 = kzalloc(sizeof(*adau1373), GFP_KERNEL); 1364 + if (!adau1373) 1365 + return -ENOMEM; 1366 + 1367 + dev_set_drvdata(&client->dev, adau1373); 1368 + 1369 + ret = snd_soc_register_codec(&client->dev, &adau1373_codec_driver, 1370 + adau1373_dai_driver, ARRAY_SIZE(adau1373_dai_driver)); 1371 + if (ret < 0) 1372 + kfree(adau1373); 1373 + 1374 + return ret; 1375 + } 1376 + 1377 + static int __devexit adau1373_i2c_remove(struct i2c_client *client) 1378 + { 1379 + snd_soc_unregister_codec(&client->dev); 1380 + kfree(dev_get_drvdata(&client->dev)); 1381 + return 0; 1382 + } 1383 + 1384 + static const struct i2c_device_id adau1373_i2c_id[] = { 1385 + { "adau1373", 0 }, 1386 + { } 1387 + }; 1388 + MODULE_DEVICE_TABLE(i2c, adau1373_i2c_id); 1389 + 1390 + static struct i2c_driver adau1373_i2c_driver = { 1391 + .driver = { 1392 + .name = "adau1373", 1393 + .owner = THIS_MODULE, 1394 + }, 1395 + .probe = adau1373_i2c_probe, 1396 + .remove = __devexit_p(adau1373_i2c_remove), 1397 + .id_table = adau1373_i2c_id, 1398 + }; 1399 + 1400 + static int __init adau1373_init(void) 1401 + { 1402 + return i2c_add_driver(&adau1373_i2c_driver); 1403 + } 1404 + module_init(adau1373_init); 1405 + 1406 + static void __exit adau1373_exit(void) 1407 + { 1408 + i2c_del_driver(&adau1373_i2c_driver); 1409 + } 1410 + module_exit(adau1373_exit); 1411 + 1412 + MODULE_DESCRIPTION("ASoC ADAU1373 driver"); 1413 + MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 1414 + MODULE_LICENSE("GPL");
+29
sound/soc/codecs/adau1373.h
··· 1 + #ifndef __ADAU1373_H__ 2 + #define __ADAU1373_H__ 3 + 4 + enum adau1373_pll_src { 5 + ADAU1373_PLL_SRC_MCLK1 = 0, 6 + ADAU1373_PLL_SRC_BCLK1 = 1, 7 + ADAU1373_PLL_SRC_BCLK2 = 2, 8 + ADAU1373_PLL_SRC_BCLK3 = 3, 9 + ADAU1373_PLL_SRC_LRCLK1 = 4, 10 + ADAU1373_PLL_SRC_LRCLK2 = 5, 11 + ADAU1373_PLL_SRC_LRCLK3 = 6, 12 + ADAU1373_PLL_SRC_GPIO1 = 7, 13 + ADAU1373_PLL_SRC_GPIO2 = 8, 14 + ADAU1373_PLL_SRC_GPIO3 = 9, 15 + ADAU1373_PLL_SRC_GPIO4 = 10, 16 + ADAU1373_PLL_SRC_MCLK2 = 11, 17 + }; 18 + 19 + enum adau1373_pll { 20 + ADAU1373_PLL1 = 0, 21 + ADAU1373_PLL2 = 1, 22 + }; 23 + 24 + enum adau1373_clk_src { 25 + ADAU1373_CLK_SRC_PLL1 = 0, 26 + ADAU1373_CLK_SRC_PLL2 = 1, 27 + }; 28 + 29 + #endif