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

ASoC: tlv320aic31xx: Add basic codec driver implementation

This commit adds a bare bones driver support for TLV320AIC31XX family
audio codecs. The driver adds basic stereo playback trough headphone
and speaker outputs and mono capture trough microphone inputs.

The driver is currently missing support at least for mini DSP features
and jack detection. I have tested the driver only on TLV320AIC3111,
but based on the data sheets TLV320AIC3100, TLV320AIC3110, and
TLV320AIC3120 should work Ok too.

The base for the implementation was taken from:
git@gitorious.org:ti-codecs/ti-codecs.git ajitk/topics/k3.10.1-aic31xx
-branch at commit 77504eba0294764e9e63b4a0c696b44db187cd13.

Signed-off-by: Jyri Sarha <jsarha@ti.com>
Signed-off-by: Mark Brown <broonie@linaro.org>

authored by

Jyri Sarha and committed by
Mark Brown
e00447fa b46f2c5c

+1628
+61
Documentation/devicetree/bindings/sound/tlv320aic31xx.txt
··· 1 + Texas Instruments - tlv320aic31xx Codec module 2 + 3 + The tlv320aic31xx serial control bus communicates through I2C protocols 4 + 5 + Required properties: 6 + 7 + - compatible - "string" - One of: 8 + "ti,tlv320aic310x" - Generic TLV320AIC31xx with mono speaker amp 9 + "ti,tlv320aic311x" - Generic TLV320AIC31xx with stereo speaker amp 10 + "ti,tlv320aic3100" - TLV320AIC3100 (mono speaker amp, no MiniDSP) 11 + "ti,tlv320aic3110" - TLV320AIC3110 (stereo speaker amp, no MiniDSP) 12 + "ti,tlv320aic3120" - TLV320AIC3120 (mono speaker amp, MiniDSP) 13 + "ti,tlv320aic3111" - TLV320AIC3111 (stereo speaker amp, MiniDSP) 14 + 15 + - reg - <int> - I2C slave address 16 + 17 + 18 + Optional properties: 19 + 20 + - gpio-reset - gpio pin number used for codec reset 21 + - ai31xx-micbias-vg - MicBias Voltage setting 22 + 1 or MICBIAS_2_0V - MICBIAS output is powered to 2.0V 23 + 2 or MICBIAS_2_5V - MICBIAS output is powered to 2.5V 24 + 3 or MICBIAS_AVDD - MICBIAS output is connected to AVDD 25 + If this node is not mentioned or if the value is unknown, then 26 + micbias is set to 2.0V. 27 + - HPVDD-supply, SPRVDD-supply, SPLVDD-supply, AVDD-supply, IOVDD-supply, 28 + DVDD-supply : power supplies for the device as covered in 29 + Documentation/devicetree/bindings/regulator/regulator.txt 30 + 31 + CODEC output pins: 32 + * HPL 33 + * HPR 34 + * SPL, devices with stereo speaker amp 35 + * SPR, devices with stereo speaker amp 36 + * SPK, devices with mono speaker amp 37 + * MICBIAS 38 + 39 + CODEC input pins: 40 + * MIC1LP 41 + * MIC1RP 42 + * MIC1LM 43 + 44 + The pins can be used in referring sound node's audio-routing property. 45 + 46 + Example: 47 + #include <dt-bindings/sound/tlv320aic31xx-micbias.h> 48 + 49 + tlv320aic31xx: tlv320aic31xx@18 { 50 + compatible = "ti,tlv320aic311x"; 51 + reg = <0x18>; 52 + 53 + ai31xx-micbias-vg = <MICBIAS_OFF>; 54 + 55 + HPVDD-supply = <&regulator>; 56 + SPRVDD-supply = <&regulator>; 57 + SPLVDD-supply = <&regulator>; 58 + AVDD-supply = <&regulator>; 59 + IOVDD-supply = <&regulator>; 60 + DVDD-supply = <&regulator>; 61 + };
+8
include/dt-bindings/sound/tlv320aic31xx-micbias.h
··· 1 + #ifndef __DT_TLV320AIC31XX_MICBIAS_H 2 + #define __DT_TLV320AIC31XX_MICBIAS_H 3 + 4 + #define MICBIAS_2_0V 1 5 + #define MICBIAS_2_5V 2 6 + #define MICBIAS_AVDDV 3 7 + 8 + #endif /* __DT_TLV320AIC31XX_MICBIAS_H */
+4
sound/soc/codecs/Kconfig
··· 73 73 select SND_SOC_TAS5086 if I2C 74 74 select SND_SOC_TLV320AIC23 if I2C 75 75 select SND_SOC_TLV320AIC26 if SPI_MASTER 76 + select SND_SOC_TLV320AIC31XX if I2C 76 77 select SND_SOC_TLV320AIC32X4 if I2C 77 78 select SND_SOC_TLV320AIC3X if I2C 78 79 select SND_SOC_TPA6130A2 if I2C ··· 361 360 config SND_SOC_TLV320AIC26 362 361 tristate 363 362 depends on SPI 363 + 364 + config SND_SOC_TLV320AIC31XX 365 + tristate 364 366 365 367 config SND_SOC_TLV320AIC32X4 366 368 tristate
+2
sound/soc/codecs/Makefile
··· 64 64 snd-soc-tas5086-objs := tas5086.o 65 65 snd-soc-tlv320aic23-objs := tlv320aic23.o 66 66 snd-soc-tlv320aic26-objs := tlv320aic26.o 67 + snd-soc-tlv320aic31xx-objs := tlv320aic31xx.o 67 68 snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o 68 69 snd-soc-tlv320aic3x-objs := tlv320aic3x.o 69 70 snd-soc-tlv320dac33-objs := tlv320dac33.o ··· 195 194 obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o 196 195 obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 197 196 obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 197 + obj-$(CONFIG_SND_SOC_TLV320AIC31XX) += snd-soc-tlv320aic31xx.o 198 198 obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o 199 199 obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 200 200 obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
+1295
sound/soc/codecs/tlv320aic31xx.c
··· 1 + /* 2 + * ALSA SoC TLV320AIC31XX codec driver 3 + * 4 + * Copyright (C) 2014 Texas Instruments, Inc. 5 + * 6 + * Author: Jyri Sarha <jsarha@ti.com> 7 + * 8 + * Based on ground work by: Ajit Kulkarni <x0175765@ti.com> 9 + * 10 + * This package is free software; you can redistribute it and/or modify 11 + * it under the terms of the GNU General Public License version 2 as 12 + * published by the Free Software Foundation. 13 + * 14 + * THIS PACKAGE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR 15 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 16 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 17 + * 18 + * The TLV320AIC31xx series of audio codec is a low-power, highly integrated 19 + * high performance codec which provides a stereo DAC, a mono ADC, 20 + * and mono/stereo Class-D speaker driver. 21 + */ 22 + 23 + #include <linux/module.h> 24 + #include <linux/moduleparam.h> 25 + #include <linux/init.h> 26 + #include <linux/delay.h> 27 + #include <linux/pm.h> 28 + #include <linux/i2c.h> 29 + #include <linux/gpio.h> 30 + #include <linux/regulator/consumer.h> 31 + #include <linux/of_gpio.h> 32 + #include <linux/slab.h> 33 + #include <sound/core.h> 34 + #include <sound/pcm.h> 35 + #include <sound/pcm_params.h> 36 + #include <sound/soc.h> 37 + #include <sound/initval.h> 38 + #include <sound/tlv.h> 39 + #include <dt-bindings/sound/tlv320aic31xx-micbias.h> 40 + 41 + #include "tlv320aic31xx.h" 42 + 43 + static const struct reg_default aic31xx_reg_defaults[] = { 44 + { AIC31XX_CLKMUX, 0x00 }, 45 + { AIC31XX_PLLPR, 0x11 }, 46 + { AIC31XX_PLLJ, 0x04 }, 47 + { AIC31XX_PLLDMSB, 0x00 }, 48 + { AIC31XX_PLLDLSB, 0x00 }, 49 + { AIC31XX_NDAC, 0x01 }, 50 + { AIC31XX_MDAC, 0x01 }, 51 + { AIC31XX_DOSRMSB, 0x00 }, 52 + { AIC31XX_DOSRLSB, 0x80 }, 53 + { AIC31XX_NADC, 0x01 }, 54 + { AIC31XX_MADC, 0x01 }, 55 + { AIC31XX_AOSR, 0x80 }, 56 + { AIC31XX_IFACE1, 0x00 }, 57 + { AIC31XX_DATA_OFFSET, 0x00 }, 58 + { AIC31XX_IFACE2, 0x00 }, 59 + { AIC31XX_BCLKN, 0x01 }, 60 + { AIC31XX_DACSETUP, 0x14 }, 61 + { AIC31XX_DACMUTE, 0x0c }, 62 + { AIC31XX_LDACVOL, 0x00 }, 63 + { AIC31XX_RDACVOL, 0x00 }, 64 + { AIC31XX_ADCSETUP, 0x00 }, 65 + { AIC31XX_ADCFGA, 0x80 }, 66 + { AIC31XX_ADCVOL, 0x00 }, 67 + { AIC31XX_HPDRIVER, 0x04 }, 68 + { AIC31XX_SPKAMP, 0x06 }, 69 + { AIC31XX_DACMIXERROUTE, 0x00 }, 70 + { AIC31XX_LANALOGHPL, 0x7f }, 71 + { AIC31XX_RANALOGHPR, 0x7f }, 72 + { AIC31XX_LANALOGSPL, 0x7f }, 73 + { AIC31XX_RANALOGSPR, 0x7f }, 74 + { AIC31XX_HPLGAIN, 0x02 }, 75 + { AIC31XX_HPRGAIN, 0x02 }, 76 + { AIC31XX_SPLGAIN, 0x00 }, 77 + { AIC31XX_SPRGAIN, 0x00 }, 78 + { AIC31XX_MICBIAS, 0x00 }, 79 + { AIC31XX_MICPGA, 0x80 }, 80 + { AIC31XX_MICPGAPI, 0x00 }, 81 + { AIC31XX_MICPGAMI, 0x00 }, 82 + }; 83 + 84 + static bool aic31xx_volatile(struct device *dev, unsigned int reg) 85 + { 86 + switch (reg) { 87 + case AIC31XX_PAGECTL: /* regmap implementation requires this */ 88 + case AIC31XX_RESET: /* always clears after write */ 89 + case AIC31XX_OT_FLAG: 90 + case AIC31XX_ADCFLAG: 91 + case AIC31XX_DACFLAG1: 92 + case AIC31XX_DACFLAG2: 93 + case AIC31XX_OFFLAG: /* Sticky interrupt flags */ 94 + case AIC31XX_INTRDACFLAG: /* Sticky interrupt flags */ 95 + case AIC31XX_INTRADCFLAG: /* Sticky interrupt flags */ 96 + case AIC31XX_INTRDACFLAG2: 97 + case AIC31XX_INTRADCFLAG2: 98 + return true; 99 + } 100 + return false; 101 + } 102 + 103 + static bool aic31xx_writeable(struct device *dev, unsigned int reg) 104 + { 105 + switch (reg) { 106 + case AIC31XX_OT_FLAG: 107 + case AIC31XX_ADCFLAG: 108 + case AIC31XX_DACFLAG1: 109 + case AIC31XX_DACFLAG2: 110 + case AIC31XX_OFFLAG: /* Sticky interrupt flags */ 111 + case AIC31XX_INTRDACFLAG: /* Sticky interrupt flags */ 112 + case AIC31XX_INTRADCFLAG: /* Sticky interrupt flags */ 113 + case AIC31XX_INTRDACFLAG2: 114 + case AIC31XX_INTRADCFLAG2: 115 + return false; 116 + } 117 + return true; 118 + } 119 + 120 + static const struct regmap_range_cfg aic31xx_ranges[] = { 121 + { 122 + .range_min = 0, 123 + .range_max = 12 * 128, 124 + .selector_reg = AIC31XX_PAGECTL, 125 + .selector_mask = 0xff, 126 + .selector_shift = 0, 127 + .window_start = 0, 128 + .window_len = 128, 129 + }, 130 + }; 131 + 132 + struct regmap_config aic31xx_i2c_regmap = { 133 + .reg_bits = 8, 134 + .val_bits = 8, 135 + .writeable_reg = aic31xx_writeable, 136 + .volatile_reg = aic31xx_volatile, 137 + .reg_defaults = aic31xx_reg_defaults, 138 + .num_reg_defaults = ARRAY_SIZE(aic31xx_reg_defaults), 139 + .cache_type = REGCACHE_RBTREE, 140 + .ranges = aic31xx_ranges, 141 + .num_ranges = ARRAY_SIZE(aic31xx_ranges), 142 + .max_register = 12 * 128, 143 + }; 144 + 145 + #define AIC31XX_NUM_SUPPLIES 6 146 + static const char * const aic31xx_supply_names[AIC31XX_NUM_SUPPLIES] = { 147 + "HPVDD", 148 + "SPRVDD", 149 + "SPLVDD", 150 + "AVDD", 151 + "IOVDD", 152 + "DVDD", 153 + }; 154 + 155 + struct aic31xx_disable_nb { 156 + struct notifier_block nb; 157 + struct aic31xx_priv *aic31xx; 158 + }; 159 + 160 + struct aic31xx_priv { 161 + struct snd_soc_codec *codec; 162 + u8 i2c_regs_status; 163 + struct device *dev; 164 + struct regmap *regmap; 165 + struct aic31xx_pdata pdata; 166 + struct regulator_bulk_data supplies[AIC31XX_NUM_SUPPLIES]; 167 + struct aic31xx_disable_nb disable_nb[AIC31XX_NUM_SUPPLIES]; 168 + unsigned int sysclk; 169 + int rate_div_line; 170 + }; 171 + 172 + struct aic31xx_rate_divs { 173 + u32 mclk; 174 + u32 rate; 175 + u8 p_val; 176 + u8 pll_j; 177 + u16 pll_d; 178 + u16 dosr; 179 + u8 ndac; 180 + u8 mdac; 181 + u8 aosr; 182 + u8 nadc; 183 + u8 madc; 184 + }; 185 + 186 + /* ADC dividers can be disabled by cofiguring them to 0 */ 187 + static const struct aic31xx_rate_divs aic31xx_divs[] = { 188 + /* mclk rate pll: p j d dosr ndac mdac aors nadc madc */ 189 + /* 8k rate */ 190 + {12000000, 8000, 1, 8, 1920, 128, 48, 2, 128, 48, 2}, 191 + {24000000, 8000, 2, 8, 1920, 128, 48, 2, 128, 48, 2}, 192 + {25000000, 8000, 2, 7, 8643, 128, 48, 2, 128, 48, 2}, 193 + /* 11.025k rate */ 194 + {12000000, 11025, 1, 7, 5264, 128, 32, 2, 128, 32, 2}, 195 + {24000000, 11025, 2, 7, 5264, 128, 32, 2, 128, 32, 2}, 196 + {25000000, 11025, 2, 7, 2253, 128, 32, 2, 128, 32, 2}, 197 + /* 16k rate */ 198 + {12000000, 16000, 1, 8, 1920, 128, 24, 2, 128, 24, 2}, 199 + {24000000, 16000, 2, 8, 1920, 128, 24, 2, 128, 24, 2}, 200 + {25000000, 16000, 2, 7, 8643, 128, 24, 2, 128, 24, 2}, 201 + /* 22.05k rate */ 202 + {12000000, 22050, 1, 7, 5264, 128, 16, 2, 128, 16, 2}, 203 + {24000000, 22050, 2, 7, 5264, 128, 16, 2, 128, 16, 2}, 204 + {25000000, 22050, 2, 7, 2253, 128, 16, 2, 128, 16, 2}, 205 + /* 32k rate */ 206 + {12000000, 32000, 1, 8, 1920, 128, 12, 2, 128, 12, 2}, 207 + {24000000, 32000, 2, 8, 1920, 128, 12, 2, 128, 12, 2}, 208 + {25000000, 32000, 2, 7, 8643, 128, 12, 2, 128, 12, 2}, 209 + /* 44.1k rate */ 210 + {12000000, 44100, 1, 7, 5264, 128, 8, 2, 128, 8, 2}, 211 + {24000000, 44100, 2, 7, 5264, 128, 8, 2, 128, 8, 2}, 212 + {25000000, 44100, 2, 7, 2253, 128, 8, 2, 128, 8, 2}, 213 + /* 48k rate */ 214 + {12000000, 48000, 1, 8, 1920, 128, 8, 2, 128, 8, 2}, 215 + {24000000, 48000, 2, 8, 1920, 128, 8, 2, 128, 8, 2}, 216 + {25000000, 48000, 2, 7, 8643, 128, 8, 2, 128, 8, 2}, 217 + /* 88.2k rate */ 218 + {12000000, 88200, 1, 7, 5264, 64, 8, 2, 64, 8, 2}, 219 + {24000000, 88200, 2, 7, 5264, 64, 8, 2, 64, 8, 2}, 220 + {25000000, 88200, 2, 7, 2253, 64, 8, 2, 64, 8, 2}, 221 + /* 96k rate */ 222 + {12000000, 96000, 1, 8, 1920, 64, 8, 2, 64, 8, 2}, 223 + {24000000, 96000, 2, 8, 1920, 64, 8, 2, 64, 8, 2}, 224 + {25000000, 96000, 2, 7, 8643, 64, 8, 2, 64, 8, 2}, 225 + /* 176.4k rate */ 226 + {12000000, 176400, 1, 7, 5264, 32, 8, 2, 32, 8, 2}, 227 + {24000000, 176400, 2, 7, 5264, 32, 8, 2, 32, 8, 2}, 228 + {25000000, 176400, 2, 7, 2253, 32, 8, 2, 32, 8, 2}, 229 + /* 192k rate */ 230 + {12000000, 192000, 1, 8, 1920, 32, 8, 2, 32, 8, 2}, 231 + {24000000, 192000, 2, 8, 1920, 32, 8, 2, 32, 8, 2}, 232 + {25000000, 192000, 2, 7, 8643, 32, 8, 2, 32, 8, 2}, 233 + }; 234 + 235 + static const char * const ldac_in_text[] = { 236 + "Off", "Left Data", "Right Data", "Mono" 237 + }; 238 + 239 + static const char * const rdac_in_text[] = { 240 + "Off", "Right Data", "Left Data", "Mono" 241 + }; 242 + 243 + static SOC_ENUM_SINGLE_DECL(ldac_in_enum, AIC31XX_DACSETUP, 4, ldac_in_text); 244 + 245 + static SOC_ENUM_SINGLE_DECL(rdac_in_enum, AIC31XX_DACSETUP, 2, rdac_in_text); 246 + 247 + static const char * const mic_select_text[] = { 248 + "Off", "FFR 10 Ohm", "FFR 20 Ohm", "FFR 40 Ohm" 249 + }; 250 + 251 + static const 252 + SOC_ENUM_SINGLE_DECL(mic1lp_p_enum, AIC31XX_MICPGAPI, 6, mic_select_text); 253 + static const 254 + SOC_ENUM_SINGLE_DECL(mic1rp_p_enum, AIC31XX_MICPGAPI, 4, mic_select_text); 255 + static const 256 + SOC_ENUM_SINGLE_DECL(mic1lm_p_enum, AIC31XX_MICPGAPI, 2, mic_select_text); 257 + 258 + static const 259 + SOC_ENUM_SINGLE_DECL(cm_m_enum, AIC31XX_MICPGAMI, 6, mic_select_text); 260 + static const 261 + SOC_ENUM_SINGLE_DECL(mic1lm_m_enum, AIC31XX_MICPGAMI, 4, mic_select_text); 262 + 263 + static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6350, 50, 0); 264 + static const DECLARE_TLV_DB_SCALE(adc_fgain_tlv, 0, 10, 0); 265 + static const DECLARE_TLV_DB_SCALE(adc_cgain_tlv, -2000, 50, 0); 266 + static const DECLARE_TLV_DB_SCALE(mic_pga_tlv, 0, 50, 0); 267 + static const DECLARE_TLV_DB_SCALE(hp_drv_tlv, 0, 100, 0); 268 + static const DECLARE_TLV_DB_SCALE(class_D_drv_tlv, 600, 600, 0); 269 + static const DECLARE_TLV_DB_SCALE(hp_vol_tlv, -6350, 50, 0); 270 + static const DECLARE_TLV_DB_SCALE(sp_vol_tlv, -6350, 50, 0); 271 + 272 + /* 273 + * controls to be exported to the user space 274 + */ 275 + static const struct snd_kcontrol_new aic31xx_snd_controls[] = { 276 + SOC_DOUBLE_R_S_TLV("DAC Playback Volume", AIC31XX_LDACVOL, 277 + AIC31XX_RDACVOL, 0, -127, 48, 7, 0, dac_vol_tlv), 278 + 279 + SOC_SINGLE_TLV("ADC Fine Capture Volume", AIC31XX_ADCFGA, 4, 4, 1, 280 + adc_fgain_tlv), 281 + 282 + SOC_SINGLE("ADC Capture Switch", AIC31XX_ADCFGA, 7, 1, 1), 283 + SOC_DOUBLE_R_S_TLV("ADC Capture Volume", AIC31XX_ADCVOL, AIC31XX_ADCVOL, 284 + 0, -24, 40, 6, 0, adc_cgain_tlv), 285 + 286 + SOC_SINGLE_TLV("Mic PGA Capture Volume", AIC31XX_MICPGA, 0, 287 + 119, 0, mic_pga_tlv), 288 + 289 + SOC_DOUBLE_R("HP Driver Playback Switch", AIC31XX_HPLGAIN, 290 + AIC31XX_HPRGAIN, 2, 1, 0), 291 + SOC_DOUBLE_R_TLV("HP Driver Playback Volume", AIC31XX_HPLGAIN, 292 + AIC31XX_HPRGAIN, 3, 0x09, 0, hp_drv_tlv), 293 + 294 + SOC_DOUBLE_R_TLV("HP Analog Playback Volume", AIC31XX_LANALOGHPL, 295 + AIC31XX_RANALOGHPR, 0, 0x7F, 1, hp_vol_tlv), 296 + }; 297 + 298 + static const struct snd_kcontrol_new aic311x_snd_controls[] = { 299 + SOC_DOUBLE_R("Speaker Driver Playback Switch", AIC31XX_SPLGAIN, 300 + AIC31XX_SPRGAIN, 2, 1, 0), 301 + SOC_DOUBLE_R_TLV("Speaker Driver Playback Volume", AIC31XX_SPLGAIN, 302 + AIC31XX_SPRGAIN, 3, 3, 0, class_D_drv_tlv), 303 + 304 + SOC_DOUBLE_R_TLV("Speaker Analog Playback Volume", AIC31XX_LANALOGSPL, 305 + AIC31XX_RANALOGSPR, 0, 0x7F, 1, sp_vol_tlv), 306 + }; 307 + 308 + static const struct snd_kcontrol_new aic310x_snd_controls[] = { 309 + SOC_SINGLE("Speaker Driver Playback Switch", AIC31XX_SPLGAIN, 310 + 2, 1, 0), 311 + SOC_SINGLE_TLV("Speaker Driver Playback Volume", AIC31XX_SPLGAIN, 312 + 3, 3, 0, class_D_drv_tlv), 313 + 314 + SOC_SINGLE_TLV("Speaker Analog Playback Volume", AIC31XX_LANALOGSPL, 315 + 0, 0x7F, 1, sp_vol_tlv), 316 + }; 317 + 318 + static const struct snd_kcontrol_new ldac_in_control = 319 + SOC_DAPM_ENUM("DAC Left Input", ldac_in_enum); 320 + 321 + static const struct snd_kcontrol_new rdac_in_control = 322 + SOC_DAPM_ENUM("DAC Right Input", rdac_in_enum); 323 + 324 + int aic31xx_wait_bits(struct aic31xx_priv *aic31xx, unsigned int reg, 325 + unsigned int mask, unsigned int wbits, int sleep, 326 + int count) 327 + { 328 + unsigned int bits; 329 + int counter = count; 330 + int ret = regmap_read(aic31xx->regmap, reg, &bits); 331 + while ((bits & mask) != wbits && counter && !ret) { 332 + usleep_range(sleep, sleep * 2); 333 + ret = regmap_read(aic31xx->regmap, reg, &bits); 334 + counter--; 335 + } 336 + if ((bits & mask) != wbits) { 337 + dev_err(aic31xx->dev, 338 + "%s: Failed! 0x%x was 0x%x expected 0x%x (%d, 0x%x, %d us)\n", 339 + __func__, reg, bits, wbits, ret, mask, 340 + (count - counter) * sleep); 341 + ret = -1; 342 + } 343 + return ret; 344 + } 345 + 346 + #define WIDGET_BIT(reg, shift) (((shift) << 8) | (reg)) 347 + 348 + static int aic31xx_dapm_power_event(struct snd_soc_dapm_widget *w, 349 + struct snd_kcontrol *kcontrol, int event) 350 + { 351 + struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(w->codec); 352 + unsigned int reg = AIC31XX_DACFLAG1; 353 + unsigned int mask; 354 + 355 + switch (WIDGET_BIT(w->reg, w->shift)) { 356 + case WIDGET_BIT(AIC31XX_DACSETUP, 7): 357 + mask = AIC31XX_LDACPWRSTATUS_MASK; 358 + break; 359 + case WIDGET_BIT(AIC31XX_DACSETUP, 6): 360 + mask = AIC31XX_RDACPWRSTATUS_MASK; 361 + break; 362 + case WIDGET_BIT(AIC31XX_HPDRIVER, 7): 363 + mask = AIC31XX_HPLDRVPWRSTATUS_MASK; 364 + break; 365 + case WIDGET_BIT(AIC31XX_HPDRIVER, 6): 366 + mask = AIC31XX_HPRDRVPWRSTATUS_MASK; 367 + break; 368 + case WIDGET_BIT(AIC31XX_SPKAMP, 7): 369 + mask = AIC31XX_SPLDRVPWRSTATUS_MASK; 370 + break; 371 + case WIDGET_BIT(AIC31XX_SPKAMP, 6): 372 + mask = AIC31XX_SPRDRVPWRSTATUS_MASK; 373 + break; 374 + case WIDGET_BIT(AIC31XX_ADCSETUP, 7): 375 + mask = AIC31XX_ADCPWRSTATUS_MASK; 376 + reg = AIC31XX_ADCFLAG; 377 + break; 378 + default: 379 + dev_err(w->codec->dev, "Unknown widget '%s' calling %s/n", 380 + w->name, __func__); 381 + return -EINVAL; 382 + } 383 + 384 + switch (event) { 385 + case SND_SOC_DAPM_POST_PMU: 386 + return aic31xx_wait_bits(aic31xx, reg, mask, mask, 5000, 100); 387 + case SND_SOC_DAPM_POST_PMD: 388 + return aic31xx_wait_bits(aic31xx, reg, mask, 0, 5000, 100); 389 + default: 390 + dev_dbg(w->codec->dev, 391 + "Unhandled dapm widget event %d from %s\n", 392 + event, w->name); 393 + } 394 + return 0; 395 + } 396 + 397 + static const struct snd_kcontrol_new left_output_switches[] = { 398 + SOC_DAPM_SINGLE("From Left DAC", AIC31XX_DACMIXERROUTE, 6, 1, 0), 399 + SOC_DAPM_SINGLE("From MIC1LP", AIC31XX_DACMIXERROUTE, 5, 1, 0), 400 + SOC_DAPM_SINGLE("From MIC1RP", AIC31XX_DACMIXERROUTE, 4, 1, 0), 401 + }; 402 + 403 + static const struct snd_kcontrol_new right_output_switches[] = { 404 + SOC_DAPM_SINGLE("From Right DAC", AIC31XX_DACMIXERROUTE, 2, 1, 0), 405 + SOC_DAPM_SINGLE("From MIC1RP", AIC31XX_DACMIXERROUTE, 1, 1, 0), 406 + }; 407 + 408 + static const struct snd_kcontrol_new p_term_mic1lp = 409 + SOC_DAPM_ENUM("MIC1LP P-Terminal", mic1lp_p_enum); 410 + 411 + static const struct snd_kcontrol_new p_term_mic1rp = 412 + SOC_DAPM_ENUM("MIC1RP P-Terminal", mic1rp_p_enum); 413 + 414 + static const struct snd_kcontrol_new p_term_mic1lm = 415 + SOC_DAPM_ENUM("MIC1LM P-Terminal", mic1lm_p_enum); 416 + 417 + static const struct snd_kcontrol_new m_term_mic1lm = 418 + SOC_DAPM_ENUM("MIC1LM M-Terminal", mic1lm_m_enum); 419 + 420 + static const struct snd_kcontrol_new aic31xx_dapm_hpl_switch = 421 + SOC_DAPM_SINGLE("Switch", AIC31XX_LANALOGHPL, 7, 1, 0); 422 + 423 + static const struct snd_kcontrol_new aic31xx_dapm_hpr_switch = 424 + SOC_DAPM_SINGLE("Switch", AIC31XX_RANALOGHPR, 7, 1, 0); 425 + 426 + static const struct snd_kcontrol_new aic31xx_dapm_spl_switch = 427 + SOC_DAPM_SINGLE("Switch", AIC31XX_LANALOGSPL, 7, 1, 0); 428 + 429 + static const struct snd_kcontrol_new aic31xx_dapm_spr_switch = 430 + SOC_DAPM_SINGLE("Switch", AIC31XX_RANALOGSPR, 7, 1, 0); 431 + 432 + static int mic_bias_event(struct snd_soc_dapm_widget *w, 433 + struct snd_kcontrol *kcontrol, int event) 434 + { 435 + struct snd_soc_codec *codec = w->codec; 436 + struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); 437 + switch (event) { 438 + case SND_SOC_DAPM_POST_PMU: 439 + /* change mic bias voltage to user defined */ 440 + snd_soc_update_bits(codec, AIC31XX_MICBIAS, 441 + AIC31XX_MICBIAS_MASK, 442 + aic31xx->pdata.micbias_vg << 443 + AIC31XX_MICBIAS_SHIFT); 444 + dev_dbg(codec->dev, "%s: turned on\n", __func__); 445 + break; 446 + case SND_SOC_DAPM_PRE_PMD: 447 + /* turn mic bias off */ 448 + snd_soc_update_bits(codec, AIC31XX_MICBIAS, 449 + AIC31XX_MICBIAS_MASK, 0); 450 + dev_dbg(codec->dev, "%s: turned off\n", __func__); 451 + break; 452 + } 453 + return 0; 454 + } 455 + 456 + static const struct snd_soc_dapm_widget aic31xx_dapm_widgets[] = { 457 + SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0), 458 + 459 + SND_SOC_DAPM_MUX("DAC Left Input", 460 + SND_SOC_NOPM, 0, 0, &ldac_in_control), 461 + SND_SOC_DAPM_MUX("DAC Right Input", 462 + SND_SOC_NOPM, 0, 0, &rdac_in_control), 463 + /* DACs */ 464 + SND_SOC_DAPM_DAC_E("DAC Left", "Left Playback", 465 + AIC31XX_DACSETUP, 7, 0, aic31xx_dapm_power_event, 466 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 467 + 468 + SND_SOC_DAPM_DAC_E("DAC Right", "Right Playback", 469 + AIC31XX_DACSETUP, 6, 0, aic31xx_dapm_power_event, 470 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 471 + 472 + /* Output Mixers */ 473 + SND_SOC_DAPM_MIXER("Output Left", SND_SOC_NOPM, 0, 0, 474 + left_output_switches, 475 + ARRAY_SIZE(left_output_switches)), 476 + SND_SOC_DAPM_MIXER("Output Right", SND_SOC_NOPM, 0, 0, 477 + right_output_switches, 478 + ARRAY_SIZE(right_output_switches)), 479 + 480 + SND_SOC_DAPM_SWITCH("HP Left", SND_SOC_NOPM, 0, 0, 481 + &aic31xx_dapm_hpl_switch), 482 + SND_SOC_DAPM_SWITCH("HP Right", SND_SOC_NOPM, 0, 0, 483 + &aic31xx_dapm_hpr_switch), 484 + 485 + /* Output drivers */ 486 + SND_SOC_DAPM_OUT_DRV_E("HPL Driver", AIC31XX_HPDRIVER, 7, 0, 487 + NULL, 0, aic31xx_dapm_power_event, 488 + SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), 489 + SND_SOC_DAPM_OUT_DRV_E("HPR Driver", AIC31XX_HPDRIVER, 6, 0, 490 + NULL, 0, aic31xx_dapm_power_event, 491 + SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU), 492 + 493 + /* ADC */ 494 + SND_SOC_DAPM_ADC_E("ADC", "Capture", AIC31XX_ADCSETUP, 7, 0, 495 + aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU | 496 + SND_SOC_DAPM_POST_PMD), 497 + 498 + /* Input Selection to MIC_PGA */ 499 + SND_SOC_DAPM_MUX("MIC1LP P-Terminal", SND_SOC_NOPM, 0, 0, 500 + &p_term_mic1lp), 501 + SND_SOC_DAPM_MUX("MIC1RP P-Terminal", SND_SOC_NOPM, 0, 0, 502 + &p_term_mic1rp), 503 + SND_SOC_DAPM_MUX("MIC1LM P-Terminal", SND_SOC_NOPM, 0, 0, 504 + &p_term_mic1lm), 505 + 506 + SND_SOC_DAPM_MUX("MIC1LM M-Terminal", SND_SOC_NOPM, 0, 0, 507 + &m_term_mic1lm), 508 + /* Enabling & Disabling MIC Gain Ctl */ 509 + SND_SOC_DAPM_PGA("MIC_GAIN_CTL", AIC31XX_MICPGA, 510 + 7, 1, NULL, 0), 511 + 512 + /* Mic Bias */ 513 + SND_SOC_DAPM_SUPPLY("MICBIAS", SND_SOC_NOPM, 0, 0, mic_bias_event, 514 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 515 + 516 + /* Outputs */ 517 + SND_SOC_DAPM_OUTPUT("HPL"), 518 + SND_SOC_DAPM_OUTPUT("HPR"), 519 + 520 + /* Inputs */ 521 + SND_SOC_DAPM_INPUT("MIC1LP"), 522 + SND_SOC_DAPM_INPUT("MIC1RP"), 523 + SND_SOC_DAPM_INPUT("MIC1LM"), 524 + }; 525 + 526 + static const struct snd_soc_dapm_widget aic311x_dapm_widgets[] = { 527 + /* AIC3111 and AIC3110 have stereo class-D amplifier */ 528 + SND_SOC_DAPM_OUT_DRV_E("SPL ClassD", AIC31XX_SPKAMP, 7, 0, NULL, 0, 529 + aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU | 530 + SND_SOC_DAPM_POST_PMD), 531 + SND_SOC_DAPM_OUT_DRV_E("SPR ClassD", AIC31XX_SPKAMP, 6, 0, NULL, 0, 532 + aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU | 533 + SND_SOC_DAPM_POST_PMD), 534 + SND_SOC_DAPM_SWITCH("Speaker Left", SND_SOC_NOPM, 0, 0, 535 + &aic31xx_dapm_spl_switch), 536 + SND_SOC_DAPM_SWITCH("Speaker Right", SND_SOC_NOPM, 0, 0, 537 + &aic31xx_dapm_spr_switch), 538 + SND_SOC_DAPM_OUTPUT("SPL"), 539 + SND_SOC_DAPM_OUTPUT("SPR"), 540 + }; 541 + 542 + /* AIC3100 and AIC3120 have only mono class-D amplifier */ 543 + static const struct snd_soc_dapm_widget aic310x_dapm_widgets[] = { 544 + SND_SOC_DAPM_OUT_DRV_E("SPK ClassD", AIC31XX_SPKAMP, 7, 0, NULL, 0, 545 + aic31xx_dapm_power_event, SND_SOC_DAPM_POST_PMU | 546 + SND_SOC_DAPM_POST_PMD), 547 + SND_SOC_DAPM_SWITCH("Speaker", SND_SOC_NOPM, 0, 0, 548 + &aic31xx_dapm_spl_switch), 549 + SND_SOC_DAPM_OUTPUT("SPK"), 550 + }; 551 + 552 + static const struct snd_soc_dapm_route 553 + aic31xx_audio_map[] = { 554 + /* DAC Input Routing */ 555 + {"DAC Left Input", "Left Data", "DAC IN"}, 556 + {"DAC Left Input", "Right Data", "DAC IN"}, 557 + {"DAC Left Input", "Mono", "DAC IN"}, 558 + {"DAC Right Input", "Left Data", "DAC IN"}, 559 + {"DAC Right Input", "Right Data", "DAC IN"}, 560 + {"DAC Right Input", "Mono", "DAC IN"}, 561 + {"DAC Left", NULL, "DAC Left Input"}, 562 + {"DAC Right", NULL, "DAC Right Input"}, 563 + 564 + /* Mic input */ 565 + {"MIC1LP P-Terminal", "FFR 10 Ohm", "MIC1LP"}, 566 + {"MIC1LP P-Terminal", "FFR 20 Ohm", "MIC1LP"}, 567 + {"MIC1LP P-Terminal", "FFR 40 Ohm", "MIC1LP"}, 568 + {"MIC1RP P-Terminal", "FFR 10 Ohm", "MIC1RP"}, 569 + {"MIC1RP P-Terminal", "FFR 20 Ohm", "MIC1RP"}, 570 + {"MIC1RP P-Terminal", "FFR 40 Ohm", "MIC1RP"}, 571 + {"MIC1LM P-Terminal", "FFR 10 Ohm", "MIC1LM"}, 572 + {"MIC1LM P-Terminal", "FFR 20 Ohm", "MIC1LM"}, 573 + {"MIC1LM P-Terminal", "FFR 40 Ohm", "MIC1LM"}, 574 + 575 + {"MIC1LM M-Terminal", "FFR 10 Ohm", "MIC1LM"}, 576 + {"MIC1LM M-Terminal", "FFR 20 Ohm", "MIC1LM"}, 577 + {"MIC1LM M-Terminal", "FFR 40 Ohm", "MIC1LM"}, 578 + 579 + {"MIC_GAIN_CTL", NULL, "MIC1LP P-Terminal"}, 580 + {"MIC_GAIN_CTL", NULL, "MIC1RP P-Terminal"}, 581 + {"MIC_GAIN_CTL", NULL, "MIC1LM P-Terminal"}, 582 + {"MIC_GAIN_CTL", NULL, "MIC1LM M-Terminal"}, 583 + 584 + {"ADC", NULL, "MIC_GAIN_CTL"}, 585 + 586 + /* Left Output */ 587 + {"Output Left", "From Left DAC", "DAC Left"}, 588 + {"Output Left", "From MIC1LP", "MIC1LP"}, 589 + {"Output Left", "From MIC1RP", "MIC1RP"}, 590 + 591 + /* Right Output */ 592 + {"Output Right", "From Right DAC", "DAC Right"}, 593 + {"Output Right", "From MIC1RP", "MIC1RP"}, 594 + 595 + /* HPL path */ 596 + {"HP Left", "Switch", "Output Left"}, 597 + {"HPL Driver", NULL, "HP Left"}, 598 + {"HPL", NULL, "HPL Driver"}, 599 + 600 + /* HPR path */ 601 + {"HP Right", "Switch", "Output Right"}, 602 + {"HPR Driver", NULL, "HP Right"}, 603 + {"HPR", NULL, "HPR Driver"}, 604 + }; 605 + 606 + static const struct snd_soc_dapm_route 607 + aic311x_audio_map[] = { 608 + /* SP L path */ 609 + {"Speaker Left", "Switch", "Output Left"}, 610 + {"SPL ClassD", NULL, "Speaker Left"}, 611 + {"SPL", NULL, "SPL ClassD"}, 612 + 613 + /* SP R path */ 614 + {"Speaker Right", "Switch", "Output Right"}, 615 + {"SPR ClassD", NULL, "Speaker Right"}, 616 + {"SPR", NULL, "SPR ClassD"}, 617 + }; 618 + 619 + static const struct snd_soc_dapm_route 620 + aic310x_audio_map[] = { 621 + /* SP L path */ 622 + {"Speaker", "Switch", "Output Left"}, 623 + {"SPK ClassD", NULL, "Speaker"}, 624 + {"SPK", NULL, "SPK ClassD"}, 625 + }; 626 + 627 + static int aic31xx_add_controls(struct snd_soc_codec *codec) 628 + { 629 + int ret = 0; 630 + struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); 631 + 632 + if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) 633 + ret = snd_soc_add_codec_controls( 634 + codec, aic311x_snd_controls, 635 + ARRAY_SIZE(aic311x_snd_controls)); 636 + else 637 + ret = snd_soc_add_codec_controls( 638 + codec, aic310x_snd_controls, 639 + ARRAY_SIZE(aic310x_snd_controls)); 640 + 641 + return ret; 642 + } 643 + 644 + static int aic31xx_add_widgets(struct snd_soc_codec *codec) 645 + { 646 + struct snd_soc_dapm_context *dapm = &codec->dapm; 647 + struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); 648 + int ret = 0; 649 + 650 + if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) { 651 + ret = snd_soc_dapm_new_controls( 652 + dapm, aic311x_dapm_widgets, 653 + ARRAY_SIZE(aic311x_dapm_widgets)); 654 + if (ret) 655 + return ret; 656 + 657 + ret = snd_soc_dapm_add_routes(dapm, aic311x_audio_map, 658 + ARRAY_SIZE(aic311x_audio_map)); 659 + if (ret) 660 + return ret; 661 + } else { 662 + ret = snd_soc_dapm_new_controls( 663 + dapm, aic310x_dapm_widgets, 664 + ARRAY_SIZE(aic310x_dapm_widgets)); 665 + if (ret) 666 + return ret; 667 + 668 + ret = snd_soc_dapm_add_routes(dapm, aic310x_audio_map, 669 + ARRAY_SIZE(aic310x_audio_map)); 670 + if (ret) 671 + return ret; 672 + } 673 + 674 + return 0; 675 + } 676 + 677 + static int aic31xx_setup_pll(struct snd_soc_codec *codec, 678 + struct snd_pcm_hw_params *params) 679 + { 680 + struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); 681 + int bclk_n = 0; 682 + int i; 683 + 684 + /* Use PLL as CODEC_CLKIN and DAC_CLK as BDIV_CLKIN */ 685 + snd_soc_update_bits(codec, AIC31XX_CLKMUX, 686 + AIC31XX_CODEC_CLKIN_MASK, AIC31XX_CODEC_CLKIN_PLL); 687 + snd_soc_update_bits(codec, AIC31XX_IFACE2, 688 + AIC31XX_BDIVCLK_MASK, AIC31XX_DAC2BCLK); 689 + 690 + for (i = 0; i < ARRAY_SIZE(aic31xx_divs); i++) { 691 + if (aic31xx_divs[i].rate == params_rate(params) && 692 + aic31xx_divs[i].mclk == aic31xx->sysclk) 693 + break; 694 + } 695 + 696 + if (i == ARRAY_SIZE(aic31xx_divs)) { 697 + dev_err(codec->dev, "%s: Sampling rate %u not supported\n", 698 + __func__, params_rate(params)); 699 + return -EINVAL; 700 + } 701 + 702 + /* PLL configuration */ 703 + snd_soc_update_bits(codec, AIC31XX_PLLPR, AIC31XX_PLL_MASK, 704 + (aic31xx_divs[i].p_val << 4) | 0x01); 705 + snd_soc_write(codec, AIC31XX_PLLJ, aic31xx_divs[i].pll_j); 706 + 707 + snd_soc_write(codec, AIC31XX_PLLDMSB, 708 + aic31xx_divs[i].pll_d >> 8); 709 + snd_soc_write(codec, AIC31XX_PLLDLSB, 710 + aic31xx_divs[i].pll_d & 0xff); 711 + 712 + /* DAC dividers configuration */ 713 + snd_soc_update_bits(codec, AIC31XX_NDAC, AIC31XX_PLL_MASK, 714 + aic31xx_divs[i].ndac); 715 + snd_soc_update_bits(codec, AIC31XX_MDAC, AIC31XX_PLL_MASK, 716 + aic31xx_divs[i].mdac); 717 + 718 + snd_soc_write(codec, AIC31XX_DOSRMSB, aic31xx_divs[i].dosr >> 8); 719 + snd_soc_write(codec, AIC31XX_DOSRLSB, aic31xx_divs[i].dosr & 0xff); 720 + 721 + /* ADC dividers configuration. Write reset value 1 if not used. */ 722 + snd_soc_update_bits(codec, AIC31XX_NADC, AIC31XX_PLL_MASK, 723 + aic31xx_divs[i].nadc ? aic31xx_divs[i].nadc : 1); 724 + snd_soc_update_bits(codec, AIC31XX_MADC, AIC31XX_PLL_MASK, 725 + aic31xx_divs[i].madc ? aic31xx_divs[i].madc : 1); 726 + 727 + snd_soc_write(codec, AIC31XX_AOSR, aic31xx_divs[i].aosr); 728 + 729 + /* Bit clock divider configuration. */ 730 + bclk_n = (aic31xx_divs[i].dosr * aic31xx_divs[i].mdac) 731 + / snd_soc_params_to_frame_size(params); 732 + if (bclk_n == 0) { 733 + dev_err(codec->dev, "%s: Not enough BLCK bandwidth\n", 734 + __func__); 735 + return -EINVAL; 736 + } 737 + 738 + snd_soc_update_bits(codec, AIC31XX_BCLKN, 739 + AIC31XX_PLL_MASK, bclk_n); 740 + 741 + aic31xx->rate_div_line = i; 742 + 743 + dev_dbg(codec->dev, 744 + "pll %d.%04d/%d dosr %d n %d m %d aosr %d n %d m %d bclk_n %d\n", 745 + aic31xx_divs[i].pll_j, aic31xx_divs[i].pll_d, 746 + aic31xx_divs[i].p_val, aic31xx_divs[i].dosr, 747 + aic31xx_divs[i].ndac, aic31xx_divs[i].mdac, 748 + aic31xx_divs[i].aosr, aic31xx_divs[i].nadc, 749 + aic31xx_divs[i].madc, bclk_n); 750 + 751 + return 0; 752 + } 753 + 754 + static int aic31xx_hw_params(struct snd_pcm_substream *substream, 755 + struct snd_pcm_hw_params *params, 756 + struct snd_soc_dai *tmp) 757 + { 758 + struct snd_soc_pcm_runtime *rtd = substream->private_data; 759 + struct snd_soc_codec *codec = rtd->codec; 760 + u8 data = 0; 761 + 762 + dev_dbg(codec->dev, "## %s: format %d width %d rate %d\n", 763 + __func__, params_format(params), params_width(params), 764 + params_rate(params)); 765 + 766 + switch (params_width(params)) { 767 + case 16: 768 + break; 769 + case 20: 770 + data = (AIC31XX_WORD_LEN_20BITS << 771 + AIC31XX_IFACE1_DATALEN_SHIFT); 772 + break; 773 + case 24: 774 + data = (AIC31XX_WORD_LEN_24BITS << 775 + AIC31XX_IFACE1_DATALEN_SHIFT); 776 + break; 777 + case 32: 778 + data = (AIC31XX_WORD_LEN_32BITS << 779 + AIC31XX_IFACE1_DATALEN_SHIFT); 780 + break; 781 + default: 782 + dev_err(codec->dev, "%s: Unsupported format %d\n", 783 + __func__, params_format(params)); 784 + return -EINVAL; 785 + } 786 + 787 + snd_soc_update_bits(codec, AIC31XX_IFACE1, 788 + AIC31XX_IFACE1_DATALEN_MASK, 789 + data); 790 + 791 + return aic31xx_setup_pll(codec, params); 792 + } 793 + 794 + static int aic31xx_dac_mute(struct snd_soc_dai *codec_dai, int mute) 795 + { 796 + struct snd_soc_codec *codec = codec_dai->codec; 797 + 798 + if (mute) { 799 + snd_soc_update_bits(codec, AIC31XX_DACMUTE, 800 + AIC31XX_DACMUTE_MASK, 801 + AIC31XX_DACMUTE_MASK); 802 + } else { 803 + snd_soc_update_bits(codec, AIC31XX_DACMUTE, 804 + AIC31XX_DACMUTE_MASK, 0x0); 805 + } 806 + 807 + return 0; 808 + } 809 + 810 + static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai, 811 + unsigned int fmt) 812 + { 813 + struct snd_soc_codec *codec = codec_dai->codec; 814 + u8 iface_reg1 = 0; 815 + u8 iface_reg3 = 0; 816 + u8 dsp_a_val = 0; 817 + 818 + dev_dbg(codec->dev, "## %s: fmt = 0x%x\n", __func__, fmt); 819 + 820 + /* set master/slave audio interface */ 821 + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 822 + case SND_SOC_DAIFMT_CBM_CFM: 823 + iface_reg1 |= AIC31XX_BCLK_MASTER | AIC31XX_WCLK_MASTER; 824 + break; 825 + default: 826 + dev_alert(codec->dev, "Invalid DAI master/slave interface\n"); 827 + return -EINVAL; 828 + } 829 + 830 + /* interface format */ 831 + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 832 + case SND_SOC_DAIFMT_I2S: 833 + break; 834 + case SND_SOC_DAIFMT_DSP_A: 835 + dsp_a_val = 0x1; 836 + case SND_SOC_DAIFMT_DSP_B: 837 + /* NOTE: BCLKINV bit value 1 equas NB and 0 equals IB */ 838 + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 839 + case SND_SOC_DAIFMT_NB_NF: 840 + iface_reg3 |= AIC31XX_BCLKINV_MASK; 841 + break; 842 + case SND_SOC_DAIFMT_IB_NF: 843 + break; 844 + default: 845 + return -EINVAL; 846 + } 847 + iface_reg1 |= (AIC31XX_DSP_MODE << 848 + AIC31XX_IFACE1_DATATYPE_SHIFT); 849 + break; 850 + case SND_SOC_DAIFMT_RIGHT_J: 851 + iface_reg1 |= (AIC31XX_RIGHT_JUSTIFIED_MODE << 852 + AIC31XX_IFACE1_DATATYPE_SHIFT); 853 + break; 854 + case SND_SOC_DAIFMT_LEFT_J: 855 + iface_reg1 |= (AIC31XX_LEFT_JUSTIFIED_MODE << 856 + AIC31XX_IFACE1_DATATYPE_SHIFT); 857 + break; 858 + default: 859 + dev_err(codec->dev, "Invalid DAI interface format\n"); 860 + return -EINVAL; 861 + } 862 + 863 + snd_soc_update_bits(codec, AIC31XX_IFACE1, 864 + AIC31XX_IFACE1_DATATYPE_MASK | 865 + AIC31XX_IFACE1_MASTER_MASK, 866 + iface_reg1); 867 + snd_soc_update_bits(codec, AIC31XX_DATA_OFFSET, 868 + AIC31XX_DATA_OFFSET_MASK, 869 + dsp_a_val); 870 + snd_soc_update_bits(codec, AIC31XX_IFACE2, 871 + AIC31XX_BCLKINV_MASK, 872 + iface_reg3); 873 + 874 + return 0; 875 + } 876 + 877 + static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai, 878 + int clk_id, unsigned int freq, int dir) 879 + { 880 + struct snd_soc_codec *codec = codec_dai->codec; 881 + struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); 882 + int i; 883 + 884 + dev_dbg(codec->dev, "## %s: clk_id = %d, freq = %d, dir = %d\n", 885 + __func__, clk_id, freq, dir); 886 + 887 + for (i = 0; aic31xx_divs[i].mclk != freq; i++) { 888 + if (i == ARRAY_SIZE(aic31xx_divs)) { 889 + dev_err(aic31xx->dev, "%s: Unsupported frequency %d\n", 890 + __func__, freq); 891 + return -EINVAL; 892 + } 893 + } 894 + 895 + /* set clock on MCLK, BCLK, or GPIO1 as PLL input */ 896 + snd_soc_update_bits(codec, AIC31XX_CLKMUX, AIC31XX_PLL_CLKIN_MASK, 897 + clk_id << AIC31XX_PLL_CLKIN_SHIFT); 898 + 899 + aic31xx->sysclk = freq; 900 + return 0; 901 + } 902 + 903 + static int aic31xx_regulator_event(struct notifier_block *nb, 904 + unsigned long event, void *data) 905 + { 906 + struct aic31xx_disable_nb *disable_nb = 907 + container_of(nb, struct aic31xx_disable_nb, nb); 908 + struct aic31xx_priv *aic31xx = disable_nb->aic31xx; 909 + 910 + if (event & REGULATOR_EVENT_DISABLE) { 911 + /* 912 + * Put codec to reset and as at least one of the 913 + * supplies was disabled. 914 + */ 915 + if (gpio_is_valid(aic31xx->pdata.gpio_reset)) 916 + gpio_set_value(aic31xx->pdata.gpio_reset, 0); 917 + 918 + regcache_mark_dirty(aic31xx->regmap); 919 + dev_dbg(aic31xx->dev, "## %s: DISABLE received\n", __func__); 920 + } 921 + 922 + return 0; 923 + } 924 + 925 + static void aic31xx_clk_on(struct snd_soc_codec *codec) 926 + { 927 + struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); 928 + u8 mask = AIC31XX_PM_MASK; 929 + u8 on = AIC31XX_PM_MASK; 930 + 931 + dev_dbg(codec->dev, "codec clock -> on (rate %d)\n", 932 + aic31xx_divs[aic31xx->rate_div_line].rate); 933 + snd_soc_update_bits(codec, AIC31XX_PLLPR, mask, on); 934 + mdelay(10); 935 + snd_soc_update_bits(codec, AIC31XX_NDAC, mask, on); 936 + snd_soc_update_bits(codec, AIC31XX_MDAC, mask, on); 937 + if (aic31xx_divs[aic31xx->rate_div_line].nadc) 938 + snd_soc_update_bits(codec, AIC31XX_NADC, mask, on); 939 + if (aic31xx_divs[aic31xx->rate_div_line].madc) 940 + snd_soc_update_bits(codec, AIC31XX_MADC, mask, on); 941 + snd_soc_update_bits(codec, AIC31XX_BCLKN, mask, on); 942 + } 943 + 944 + static void aic31xx_clk_off(struct snd_soc_codec *codec) 945 + { 946 + struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); 947 + u8 mask = AIC31XX_PM_MASK; 948 + u8 off = 0; 949 + 950 + dev_dbg(codec->dev, "codec clock -> off\n"); 951 + snd_soc_update_bits(codec, AIC31XX_BCLKN, mask, off); 952 + snd_soc_update_bits(codec, AIC31XX_MADC, mask, off); 953 + snd_soc_update_bits(codec, AIC31XX_NADC, mask, off); 954 + snd_soc_update_bits(codec, AIC31XX_MDAC, mask, off); 955 + snd_soc_update_bits(codec, AIC31XX_NDAC, mask, off); 956 + snd_soc_update_bits(codec, AIC31XX_PLLPR, mask, off); 957 + } 958 + 959 + static int aic31xx_power_on(struct snd_soc_codec *codec) 960 + { 961 + struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); 962 + int ret = 0; 963 + 964 + ret = regulator_bulk_enable(ARRAY_SIZE(aic31xx->supplies), 965 + aic31xx->supplies); 966 + if (ret) 967 + return ret; 968 + 969 + if (gpio_is_valid(aic31xx->pdata.gpio_reset)) { 970 + gpio_set_value(aic31xx->pdata.gpio_reset, 1); 971 + udelay(100); 972 + } 973 + regcache_cache_only(aic31xx->regmap, false); 974 + ret = regcache_sync(aic31xx->regmap); 975 + if (ret != 0) { 976 + dev_err(codec->dev, 977 + "Failed to restore cache: %d\n", ret); 978 + regcache_cache_only(aic31xx->regmap, true); 979 + regulator_bulk_disable(ARRAY_SIZE(aic31xx->supplies), 980 + aic31xx->supplies); 981 + return ret; 982 + } 983 + return 0; 984 + } 985 + 986 + static int aic31xx_power_off(struct snd_soc_codec *codec) 987 + { 988 + struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); 989 + int ret = 0; 990 + 991 + regcache_cache_only(aic31xx->regmap, true); 992 + ret = regulator_bulk_disable(ARRAY_SIZE(aic31xx->supplies), 993 + aic31xx->supplies); 994 + 995 + return ret; 996 + } 997 + 998 + static int aic31xx_set_bias_level(struct snd_soc_codec *codec, 999 + enum snd_soc_bias_level level) 1000 + { 1001 + dev_dbg(codec->dev, "## %s: %d -> %d\n", __func__, 1002 + codec->dapm.bias_level, level); 1003 + 1004 + switch (level) { 1005 + case SND_SOC_BIAS_ON: 1006 + break; 1007 + case SND_SOC_BIAS_PREPARE: 1008 + if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) 1009 + aic31xx_clk_on(codec); 1010 + break; 1011 + case SND_SOC_BIAS_STANDBY: 1012 + switch (codec->dapm.bias_level) { 1013 + case SND_SOC_BIAS_OFF: 1014 + aic31xx_power_on(codec); 1015 + break; 1016 + case SND_SOC_BIAS_PREPARE: 1017 + aic31xx_clk_off(codec); 1018 + break; 1019 + default: 1020 + BUG(); 1021 + } 1022 + break; 1023 + case SND_SOC_BIAS_OFF: 1024 + aic31xx_power_off(codec); 1025 + break; 1026 + } 1027 + codec->dapm.bias_level = level; 1028 + 1029 + return 0; 1030 + } 1031 + 1032 + static int aic31xx_suspend(struct snd_soc_codec *codec) 1033 + { 1034 + aic31xx_set_bias_level(codec, SND_SOC_BIAS_OFF); 1035 + return 0; 1036 + } 1037 + 1038 + static int aic31xx_resume(struct snd_soc_codec *codec) 1039 + { 1040 + aic31xx_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1041 + return 0; 1042 + } 1043 + 1044 + static int aic31xx_codec_probe(struct snd_soc_codec *codec) 1045 + { 1046 + int ret = 0; 1047 + struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); 1048 + int i; 1049 + 1050 + dev_dbg(aic31xx->dev, "## %s\n", __func__); 1051 + 1052 + aic31xx = snd_soc_codec_get_drvdata(codec); 1053 + codec->control_data = aic31xx->regmap; 1054 + 1055 + aic31xx->codec = codec; 1056 + 1057 + ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); 1058 + 1059 + if (ret != 0) { 1060 + dev_err(codec->dev, "snd_soc_codec_set_cache_io failed %d\n", 1061 + ret); 1062 + return ret; 1063 + } 1064 + 1065 + for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) { 1066 + aic31xx->disable_nb[i].nb.notifier_call = 1067 + aic31xx_regulator_event; 1068 + aic31xx->disable_nb[i].aic31xx = aic31xx; 1069 + ret = regulator_register_notifier(aic31xx->supplies[i].consumer, 1070 + &aic31xx->disable_nb[i].nb); 1071 + if (ret) { 1072 + dev_err(codec->dev, 1073 + "Failed to request regulator notifier: %d\n", 1074 + ret); 1075 + return ret; 1076 + } 1077 + } 1078 + 1079 + regcache_cache_only(aic31xx->regmap, true); 1080 + regcache_mark_dirty(aic31xx->regmap); 1081 + 1082 + ret = aic31xx_add_controls(codec); 1083 + if (ret) 1084 + return ret; 1085 + 1086 + ret = aic31xx_add_widgets(codec); 1087 + 1088 + return ret; 1089 + } 1090 + 1091 + static int aic31xx_codec_remove(struct snd_soc_codec *codec) 1092 + { 1093 + struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); 1094 + int i; 1095 + /* power down chip */ 1096 + aic31xx_set_bias_level(codec, SND_SOC_BIAS_OFF); 1097 + 1098 + for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) 1099 + regulator_unregister_notifier(aic31xx->supplies[i].consumer, 1100 + &aic31xx->disable_nb[i].nb); 1101 + 1102 + return 0; 1103 + } 1104 + 1105 + static struct snd_soc_codec_driver soc_codec_driver_aic31xx = { 1106 + .probe = aic31xx_codec_probe, 1107 + .remove = aic31xx_codec_remove, 1108 + .suspend = aic31xx_suspend, 1109 + .resume = aic31xx_resume, 1110 + .set_bias_level = aic31xx_set_bias_level, 1111 + .controls = aic31xx_snd_controls, 1112 + .num_controls = ARRAY_SIZE(aic31xx_snd_controls), 1113 + .dapm_widgets = aic31xx_dapm_widgets, 1114 + .num_dapm_widgets = ARRAY_SIZE(aic31xx_dapm_widgets), 1115 + .dapm_routes = aic31xx_audio_map, 1116 + .num_dapm_routes = ARRAY_SIZE(aic31xx_audio_map), 1117 + }; 1118 + 1119 + static struct snd_soc_dai_ops aic31xx_dai_ops = { 1120 + .hw_params = aic31xx_hw_params, 1121 + .set_sysclk = aic31xx_set_dai_sysclk, 1122 + .set_fmt = aic31xx_set_dai_fmt, 1123 + .digital_mute = aic31xx_dac_mute, 1124 + }; 1125 + 1126 + static struct snd_soc_dai_driver aic31xx_dai_driver[] = { 1127 + { 1128 + .name = "tlv320aic31xx-hifi", 1129 + .playback = { 1130 + .stream_name = "Playback", 1131 + .channels_min = 1, 1132 + .channels_max = 2, 1133 + .rates = AIC31XX_RATES, 1134 + .formats = AIC31XX_FORMATS, 1135 + }, 1136 + .capture = { 1137 + .stream_name = "Capture", 1138 + .channels_min = 1, 1139 + .channels_max = 2, 1140 + .rates = AIC31XX_RATES, 1141 + .formats = AIC31XX_FORMATS, 1142 + }, 1143 + .ops = &aic31xx_dai_ops, 1144 + .symmetric_rates = 1, 1145 + } 1146 + }; 1147 + 1148 + #if defined(CONFIG_OF) 1149 + static const struct of_device_id tlv320aic31xx_of_match[] = { 1150 + { .compatible = "ti,tlv320aic310x" }, 1151 + { .compatible = "ti,tlv320aic311x" }, 1152 + { .compatible = "ti,tlv320aic3100" }, 1153 + { .compatible = "ti,tlv320aic3110" }, 1154 + { .compatible = "ti,tlv320aic3120" }, 1155 + { .compatible = "ti,tlv320aic3111" }, 1156 + {}, 1157 + }; 1158 + MODULE_DEVICE_TABLE(of, tlv320aic31xx_of_match); 1159 + 1160 + static void aic31xx_pdata_from_of(struct aic31xx_priv *aic31xx) 1161 + { 1162 + struct device_node *np = aic31xx->dev->of_node; 1163 + unsigned int value = MICBIAS_2_0V; 1164 + int ret; 1165 + 1166 + of_property_read_u32(np, "ai31xx-micbias-vg", &value); 1167 + switch (value) { 1168 + case MICBIAS_2_0V: 1169 + case MICBIAS_2_5V: 1170 + case MICBIAS_AVDDV: 1171 + aic31xx->pdata.micbias_vg = value; 1172 + break; 1173 + default: 1174 + dev_err(aic31xx->dev, 1175 + "Bad ai31xx-micbias-vg value %d DT\n", 1176 + value); 1177 + aic31xx->pdata.micbias_vg = MICBIAS_2_0V; 1178 + } 1179 + 1180 + ret = of_get_named_gpio(np, "gpio-reset", 0); 1181 + if (ret > 0) 1182 + aic31xx->pdata.gpio_reset = ret; 1183 + } 1184 + #else /* CONFIG_OF */ 1185 + static void aic31xx_pdata_from_of(struct aic31xx_priv *aic31xx) 1186 + { 1187 + } 1188 + #endif /* CONFIG_OF */ 1189 + 1190 + void aic31xx_device_init(struct aic31xx_priv *aic31xx) 1191 + { 1192 + int ret, i; 1193 + 1194 + dev_set_drvdata(aic31xx->dev, aic31xx); 1195 + 1196 + if (dev_get_platdata(aic31xx->dev)) 1197 + memcpy(&aic31xx->pdata, dev_get_platdata(aic31xx->dev), 1198 + sizeof(aic31xx->pdata)); 1199 + else if (aic31xx->dev->of_node) 1200 + aic31xx_pdata_from_of(aic31xx); 1201 + 1202 + if (aic31xx->pdata.gpio_reset) { 1203 + ret = devm_gpio_request_one(aic31xx->dev, 1204 + aic31xx->pdata.gpio_reset, 1205 + GPIOF_OUT_INIT_HIGH, 1206 + "aic31xx-reset-pin"); 1207 + if (ret < 0) { 1208 + dev_err(aic31xx->dev, "not able to acquire gpio\n"); 1209 + return; 1210 + } 1211 + } 1212 + 1213 + for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) 1214 + aic31xx->supplies[i].supply = aic31xx_supply_names[i]; 1215 + 1216 + ret = devm_regulator_bulk_get(aic31xx->dev, 1217 + ARRAY_SIZE(aic31xx->supplies), 1218 + aic31xx->supplies); 1219 + if (ret != 0) 1220 + dev_err(aic31xx->dev, "Failed to request supplies: %d\n", ret); 1221 + 1222 + } 1223 + 1224 + static int aic31xx_i2c_probe(struct i2c_client *i2c, 1225 + const struct i2c_device_id *id) 1226 + { 1227 + struct aic31xx_priv *aic31xx; 1228 + int ret; 1229 + const struct regmap_config *regmap_config; 1230 + 1231 + dev_dbg(&i2c->dev, "## %s: %s codec_type = %d\n", __func__, 1232 + id->name, (int) id->driver_data); 1233 + 1234 + regmap_config = &aic31xx_i2c_regmap; 1235 + 1236 + aic31xx = devm_kzalloc(&i2c->dev, sizeof(*aic31xx), GFP_KERNEL); 1237 + if (aic31xx == NULL) 1238 + return -ENOMEM; 1239 + 1240 + aic31xx->regmap = devm_regmap_init_i2c(i2c, regmap_config); 1241 + 1242 + if (IS_ERR(aic31xx->regmap)) { 1243 + ret = PTR_ERR(aic31xx->regmap); 1244 + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", 1245 + ret); 1246 + return ret; 1247 + } 1248 + aic31xx->dev = &i2c->dev; 1249 + 1250 + aic31xx->pdata.codec_type = id->driver_data; 1251 + 1252 + aic31xx_device_init(aic31xx); 1253 + 1254 + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_driver_aic31xx, 1255 + aic31xx_dai_driver, 1256 + ARRAY_SIZE(aic31xx_dai_driver)); 1257 + 1258 + return ret; 1259 + } 1260 + 1261 + static int aic31xx_i2c_remove(struct i2c_client *i2c) 1262 + { 1263 + struct aic31xx_priv *aic31xx = dev_get_drvdata(&i2c->dev); 1264 + 1265 + kfree(aic31xx); 1266 + return 0; 1267 + } 1268 + 1269 + static const struct i2c_device_id aic31xx_i2c_id[] = { 1270 + { "tlv320aic310x", AIC3100 }, 1271 + { "tlv320aic311x", AIC3110 }, 1272 + { "tlv320aic3100", AIC3100 }, 1273 + { "tlv320aic3110", AIC3110 }, 1274 + { "tlv320aic3120", AIC3120 }, 1275 + { "tlv320aic3111", AIC3111 }, 1276 + { } 1277 + }; 1278 + MODULE_DEVICE_TABLE(i2c, aic31xx_i2c_id); 1279 + 1280 + static struct i2c_driver aic31xx_i2c_driver = { 1281 + .driver = { 1282 + .name = "tlv320aic31xx-codec", 1283 + .owner = THIS_MODULE, 1284 + .of_match_table = of_match_ptr(tlv320aic31xx_of_match), 1285 + }, 1286 + .probe = aic31xx_i2c_probe, 1287 + .remove = (aic31xx_i2c_remove), 1288 + .id_table = aic31xx_i2c_id, 1289 + }; 1290 + 1291 + module_i2c_driver(aic31xx_i2c_driver); 1292 + 1293 + MODULE_DESCRIPTION("ASoC TLV320AIC3111 codec driver"); 1294 + MODULE_AUTHOR("Jyri Sarha"); 1295 + MODULE_LICENSE("GPL");
+258
sound/soc/codecs/tlv320aic31xx.h
··· 1 + /* 2 + * ALSA SoC TLV320AIC31XX codec driver 3 + * 4 + * Copyright (C) 2013 Texas Instruments, Inc. 5 + * 6 + * This package is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + * 10 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 11 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 12 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 13 + * 14 + */ 15 + #ifndef _TLV320AIC31XX_H 16 + #define _TLV320AIC31XX_H 17 + 18 + #define AIC31XX_RATES SNDRV_PCM_RATE_8000_192000 19 + 20 + #define AIC31XX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \ 21 + | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) 22 + 23 + 24 + #define AIC31XX_STEREO_CLASS_D_BIT 0x1 25 + #define AIC31XX_MINIDSP_BIT 0x2 26 + 27 + enum aic31xx_type { 28 + AIC3100 = 0, 29 + AIC3110 = AIC31XX_STEREO_CLASS_D_BIT, 30 + AIC3120 = AIC31XX_MINIDSP_BIT, 31 + AIC3111 = (AIC31XX_STEREO_CLASS_D_BIT | AIC31XX_MINIDSP_BIT), 32 + }; 33 + 34 + struct aic31xx_pdata { 35 + enum aic31xx_type codec_type; 36 + unsigned int gpio_reset; 37 + int micbias_vg; 38 + }; 39 + 40 + /* Page Control Register */ 41 + #define AIC31XX_PAGECTL 0x00 42 + 43 + /* Page 0 Registers */ 44 + /* Software reset register */ 45 + #define AIC31XX_RESET 0x01 46 + /* OT FLAG register */ 47 + #define AIC31XX_OT_FLAG 0x03 48 + /* Clock clock Gen muxing, Multiplexers*/ 49 + #define AIC31XX_CLKMUX 0x04 50 + /* PLL P and R-VAL register */ 51 + #define AIC31XX_PLLPR 0x05 52 + /* PLL J-VAL register */ 53 + #define AIC31XX_PLLJ 0x06 54 + /* PLL D-VAL MSB register */ 55 + #define AIC31XX_PLLDMSB 0x07 56 + /* PLL D-VAL LSB register */ 57 + #define AIC31XX_PLLDLSB 0x08 58 + /* DAC NDAC_VAL register*/ 59 + #define AIC31XX_NDAC 0x0B 60 + /* DAC MDAC_VAL register */ 61 + #define AIC31XX_MDAC 0x0C 62 + /* DAC OSR setting register 1, MSB value */ 63 + #define AIC31XX_DOSRMSB 0x0D 64 + /* DAC OSR setting register 2, LSB value */ 65 + #define AIC31XX_DOSRLSB 0x0E 66 + #define AIC31XX_MINI_DSP_INPOL 0x10 67 + /* Clock setting register 8, PLL */ 68 + #define AIC31XX_NADC 0x12 69 + /* Clock setting register 9, PLL */ 70 + #define AIC31XX_MADC 0x13 71 + /* ADC Oversampling (AOSR) Register */ 72 + #define AIC31XX_AOSR 0x14 73 + /* Clock setting register 9, Multiplexers */ 74 + #define AIC31XX_CLKOUTMUX 0x19 75 + /* Clock setting register 10, CLOCKOUT M divider value */ 76 + #define AIC31XX_CLKOUTMVAL 0x1A 77 + /* Audio Interface Setting Register 1 */ 78 + #define AIC31XX_IFACE1 0x1B 79 + /* Audio Data Slot Offset Programming */ 80 + #define AIC31XX_DATA_OFFSET 0x1C 81 + /* Audio Interface Setting Register 2 */ 82 + #define AIC31XX_IFACE2 0x1D 83 + /* Clock setting register 11, BCLK N Divider */ 84 + #define AIC31XX_BCLKN 0x1E 85 + /* Audio Interface Setting Register 3, Secondary Audio Interface */ 86 + #define AIC31XX_IFACESEC1 0x1F 87 + /* Audio Interface Setting Register 4 */ 88 + #define AIC31XX_IFACESEC2 0x20 89 + /* Audio Interface Setting Register 5 */ 90 + #define AIC31XX_IFACESEC3 0x21 91 + /* I2C Bus Condition */ 92 + #define AIC31XX_I2C 0x22 93 + /* ADC FLAG */ 94 + #define AIC31XX_ADCFLAG 0x24 95 + /* DAC Flag Registers */ 96 + #define AIC31XX_DACFLAG1 0x25 97 + #define AIC31XX_DACFLAG2 0x26 98 + /* Sticky Interrupt flag (overflow) */ 99 + #define AIC31XX_OFFLAG 0x27 100 + /* Sticy DAC Interrupt flags */ 101 + #define AIC31XX_INTRDACFLAG 0x2C 102 + /* Sticy ADC Interrupt flags */ 103 + #define AIC31XX_INTRADCFLAG 0x2D 104 + /* DAC Interrupt flags 2 */ 105 + #define AIC31XX_INTRDACFLAG2 0x2E 106 + /* ADC Interrupt flags 2 */ 107 + #define AIC31XX_INTRADCFLAG2 0x2F 108 + /* INT1 interrupt control */ 109 + #define AIC31XX_INT1CTRL 0x30 110 + /* INT2 interrupt control */ 111 + #define AIC31XX_INT2CTRL 0x31 112 + /* GPIO1 control */ 113 + #define AIC31XX_GPIO1 0x33 114 + 115 + #define AIC31XX_DACPRB 0x3C 116 + /* ADC Instruction Set Register */ 117 + #define AIC31XX_ADCPRB 0x3D 118 + /* DAC channel setup register */ 119 + #define AIC31XX_DACSETUP 0x3F 120 + /* DAC Mute and volume control register */ 121 + #define AIC31XX_DACMUTE 0x40 122 + /* Left DAC channel digital volume control */ 123 + #define AIC31XX_LDACVOL 0x41 124 + /* Right DAC channel digital volume control */ 125 + #define AIC31XX_RDACVOL 0x42 126 + /* Headset detection */ 127 + #define AIC31XX_HSDETECT 0x43 128 + /* ADC Digital Mic */ 129 + #define AIC31XX_ADCSETUP 0x51 130 + /* ADC Digital Volume Control Fine Adjust */ 131 + #define AIC31XX_ADCFGA 0x52 132 + /* ADC Digital Volume Control Coarse Adjust */ 133 + #define AIC31XX_ADCVOL 0x53 134 + 135 + 136 + /* Page 1 Registers */ 137 + /* Headphone drivers */ 138 + #define AIC31XX_HPDRIVER 0x9F 139 + /* Class-D Speakear Amplifier */ 140 + #define AIC31XX_SPKAMP 0xA0 141 + /* HP Output Drivers POP Removal Settings */ 142 + #define AIC31XX_HPPOP 0xA1 143 + /* Output Driver PGA Ramp-Down Period Control */ 144 + #define AIC31XX_SPPGARAMP 0xA2 145 + /* DAC_L and DAC_R Output Mixer Routing */ 146 + #define AIC31XX_DACMIXERROUTE 0xA3 147 + /* Left Analog Vol to HPL */ 148 + #define AIC31XX_LANALOGHPL 0xA4 149 + /* Right Analog Vol to HPR */ 150 + #define AIC31XX_RANALOGHPR 0xA5 151 + /* Left Analog Vol to SPL */ 152 + #define AIC31XX_LANALOGSPL 0xA6 153 + /* Right Analog Vol to SPR */ 154 + #define AIC31XX_RANALOGSPR 0xA7 155 + /* HPL Driver */ 156 + #define AIC31XX_HPLGAIN 0xA8 157 + /* HPR Driver */ 158 + #define AIC31XX_HPRGAIN 0xA9 159 + /* SPL Driver */ 160 + #define AIC31XX_SPLGAIN 0xAA 161 + /* SPR Driver */ 162 + #define AIC31XX_SPRGAIN 0xAB 163 + /* HP Driver Control */ 164 + #define AIC31XX_HPCONTROL 0xAC 165 + /* MIC Bias Control */ 166 + #define AIC31XX_MICBIAS 0xAE 167 + /* MIC PGA*/ 168 + #define AIC31XX_MICPGA 0xAF 169 + /* Delta-Sigma Mono ADC Channel Fine-Gain Input Selection for P-Terminal */ 170 + #define AIC31XX_MICPGAPI 0xB0 171 + /* ADC Input Selection for M-Terminal */ 172 + #define AIC31XX_MICPGAMI 0xB1 173 + /* Input CM Settings */ 174 + #define AIC31XX_MICPGACM 0xB2 175 + 176 + /* Bits, masks and shifts */ 177 + 178 + /* AIC31XX_CLKMUX */ 179 + #define AIC31XX_PLL_CLKIN_MASK 0x0c 180 + #define AIC31XX_PLL_CLKIN_SHIFT 2 181 + #define AIC31XX_PLL_CLKIN_MCLK 0 182 + #define AIC31XX_CODEC_CLKIN_MASK 0x03 183 + #define AIC31XX_CODEC_CLKIN_SHIFT 0 184 + #define AIC31XX_CODEC_CLKIN_PLL 3 185 + #define AIC31XX_CODEC_CLKIN_BCLK 1 186 + 187 + /* AIC31XX_PLLPR, AIC31XX_NDAC, AIC31XX_MDAC, AIC31XX_NADC, AIC31XX_MADC, 188 + AIC31XX_BCLKN */ 189 + #define AIC31XX_PLL_MASK 0x7f 190 + #define AIC31XX_PM_MASK 0x80 191 + 192 + /* AIC31XX_IFACE1 */ 193 + #define AIC31XX_WORD_LEN_16BITS 0x00 194 + #define AIC31XX_WORD_LEN_20BITS 0x01 195 + #define AIC31XX_WORD_LEN_24BITS 0x02 196 + #define AIC31XX_WORD_LEN_32BITS 0x03 197 + #define AIC31XX_IFACE1_DATALEN_MASK 0x30 198 + #define AIC31XX_IFACE1_DATALEN_SHIFT (4) 199 + #define AIC31XX_IFACE1_DATATYPE_MASK 0xC0 200 + #define AIC31XX_IFACE1_DATATYPE_SHIFT (6) 201 + #define AIC31XX_I2S_MODE 0x00 202 + #define AIC31XX_DSP_MODE 0x01 203 + #define AIC31XX_RIGHT_JUSTIFIED_MODE 0x02 204 + #define AIC31XX_LEFT_JUSTIFIED_MODE 0x03 205 + #define AIC31XX_IFACE1_MASTER_MASK 0x0C 206 + #define AIC31XX_BCLK_MASTER 0x08 207 + #define AIC31XX_WCLK_MASTER 0x04 208 + 209 + /* AIC31XX_DATA_OFFSET */ 210 + #define AIC31XX_DATA_OFFSET_MASK 0xFF 211 + 212 + /* AIC31XX_IFACE2 */ 213 + #define AIC31XX_BCLKINV_MASK 0x08 214 + #define AIC31XX_BDIVCLK_MASK 0x03 215 + #define AIC31XX_DAC2BCLK 0x00 216 + #define AIC31XX_DACMOD2BCLK 0x01 217 + #define AIC31XX_ADC2BCLK 0x02 218 + #define AIC31XX_ADCMOD2BCLK 0x03 219 + 220 + /* AIC31XX_ADCFLAG */ 221 + #define AIC31XX_ADCPWRSTATUS_MASK 0x40 222 + 223 + /* AIC31XX_DACFLAG1 */ 224 + #define AIC31XX_LDACPWRSTATUS_MASK 0x80 225 + #define AIC31XX_RDACPWRSTATUS_MASK 0x08 226 + #define AIC31XX_HPLDRVPWRSTATUS_MASK 0x20 227 + #define AIC31XX_HPRDRVPWRSTATUS_MASK 0x02 228 + #define AIC31XX_SPLDRVPWRSTATUS_MASK 0x10 229 + #define AIC31XX_SPRDRVPWRSTATUS_MASK 0x01 230 + 231 + /* AIC31XX_INTRDACFLAG */ 232 + #define AIC31XX_HPSCDETECT_MASK 0x80 233 + #define AIC31XX_BUTTONPRESS_MASK 0x20 234 + #define AIC31XX_HSPLUG_MASK 0x10 235 + #define AIC31XX_LDRCTHRES_MASK 0x08 236 + #define AIC31XX_RDRCTHRES_MASK 0x04 237 + #define AIC31XX_DACSINT_MASK 0x02 238 + #define AIC31XX_DACAINT_MASK 0x01 239 + 240 + /* AIC31XX_INT1CTRL */ 241 + #define AIC31XX_HSPLUGDET_MASK 0x80 242 + #define AIC31XX_BUTTONPRESSDET_MASK 0x40 243 + #define AIC31XX_DRCTHRES_MASK 0x20 244 + #define AIC31XX_AGCNOISE_MASK 0x10 245 + #define AIC31XX_OC_MASK 0x08 246 + #define AIC31XX_ENGINE_MASK 0x04 247 + 248 + /* AIC31XX_DACSETUP */ 249 + #define AIC31XX_SOFTSTEP_MASK 0x03 250 + 251 + /* AIC31XX_DACMUTE */ 252 + #define AIC31XX_DACMUTE_MASK 0x0C 253 + 254 + /* AIC31XX_MICBIAS */ 255 + #define AIC31XX_MICBIAS_MASK 0x03 256 + #define AIC31XX_MICBIAS_SHIFT 0 257 + 258 + #endif /* _TLV320AIC31XX_H */