brintos

brintos / linux-shallow public Read only

0
0
Text · 36.8 KiB · fd4a96a Raw
1222 lines · c
1// SPDX-License-Identifier: GPL-2.02//3// nau8822.c  --  NAU8822 ALSA Soc Audio driver4//5// Copyright 2017 Nuvoton Technology Crop.6//7// Author: David Lin <ctlin0@nuvoton.com>8// Co-author: John Hsu <kchsu0@nuvoton.com>9// Co-author: Seven Li <wtli@nuvoton.com>10//11// Based on WM8974.c12 13#include <linux/module.h>14#include <linux/moduleparam.h>15#include <linux/kernel.h>16#include <linux/init.h>17#include <linux/clk.h>18#include <linux/delay.h>19#include <linux/pm.h>20#include <linux/i2c.h>21#include <linux/regmap.h>22#include <linux/slab.h>23#include <sound/core.h>24#include <sound/pcm.h>25#include <sound/pcm_params.h>26#include <sound/soc.h>27#include <sound/initval.h>28#include <sound/tlv.h>29#include <asm/div64.h>30#include "nau8822.h"31 32#define NAU_PLL_FREQ_MAX 10000000033#define NAU_PLL_FREQ_MIN 9000000034#define NAU_PLL_REF_MAX 3300000035#define NAU_PLL_REF_MIN 800000036#define NAU_PLL_OPTOP_MIN 637 38static const int nau8822_mclk_scaler[] = { 10, 15, 20, 30, 40, 60, 80, 120 };39 40static const struct reg_default nau8822_reg_defaults[] = {41	{ NAU8822_REG_POWER_MANAGEMENT_1, 0x0000 },42	{ NAU8822_REG_POWER_MANAGEMENT_2, 0x0000 },43	{ NAU8822_REG_POWER_MANAGEMENT_3, 0x0000 },44	{ NAU8822_REG_AUDIO_INTERFACE, 0x0050 },45	{ NAU8822_REG_COMPANDING_CONTROL, 0x0000 },46	{ NAU8822_REG_CLOCKING, 0x0140 },47	{ NAU8822_REG_ADDITIONAL_CONTROL, 0x0000 },48	{ NAU8822_REG_GPIO_CONTROL, 0x0000 },49	{ NAU8822_REG_JACK_DETECT_CONTROL_1, 0x0000 },50	{ NAU8822_REG_DAC_CONTROL, 0x0000 },51	{ NAU8822_REG_LEFT_DAC_DIGITAL_VOLUME, 0x00ff },52	{ NAU8822_REG_RIGHT_DAC_DIGITAL_VOLUME, 0x00ff },53	{ NAU8822_REG_JACK_DETECT_CONTROL_2, 0x0000 },54	{ NAU8822_REG_ADC_CONTROL, 0x0100 },55	{ NAU8822_REG_LEFT_ADC_DIGITAL_VOLUME, 0x00ff },56	{ NAU8822_REG_RIGHT_ADC_DIGITAL_VOLUME, 0x00ff },57	{ NAU8822_REG_EQ1, 0x012c },58	{ NAU8822_REG_EQ2, 0x002c },59	{ NAU8822_REG_EQ3, 0x002c },60	{ NAU8822_REG_EQ4, 0x002c },61	{ NAU8822_REG_EQ5, 0x002c },62	{ NAU8822_REG_DAC_LIMITER_1, 0x0032 },63	{ NAU8822_REG_DAC_LIMITER_2, 0x0000 },64	{ NAU8822_REG_NOTCH_FILTER_1, 0x0000 },65	{ NAU8822_REG_NOTCH_FILTER_2, 0x0000 },66	{ NAU8822_REG_NOTCH_FILTER_3, 0x0000 },67	{ NAU8822_REG_NOTCH_FILTER_4, 0x0000 },68	{ NAU8822_REG_ALC_CONTROL_1, 0x0038 },69	{ NAU8822_REG_ALC_CONTROL_2, 0x000b },70	{ NAU8822_REG_ALC_CONTROL_3, 0x0032 },71	{ NAU8822_REG_NOISE_GATE, 0x0010 },72	{ NAU8822_REG_PLL_N, 0x0008 },73	{ NAU8822_REG_PLL_K1, 0x000c },74	{ NAU8822_REG_PLL_K2, 0x0093 },75	{ NAU8822_REG_PLL_K3, 0x00e9 },76	{ NAU8822_REG_3D_CONTROL, 0x0000 },77	{ NAU8822_REG_RIGHT_SPEAKER_CONTROL, 0x0000 },78	{ NAU8822_REG_INPUT_CONTROL, 0x0033 },79	{ NAU8822_REG_LEFT_INP_PGA_CONTROL, 0x0010 },80	{ NAU8822_REG_RIGHT_INP_PGA_CONTROL, 0x0010 },81	{ NAU8822_REG_LEFT_ADC_BOOST_CONTROL, 0x0100 },82	{ NAU8822_REG_RIGHT_ADC_BOOST_CONTROL, 0x0100 },83	{ NAU8822_REG_OUTPUT_CONTROL, 0x0002 },84	{ NAU8822_REG_LEFT_MIXER_CONTROL, 0x0001 },85	{ NAU8822_REG_RIGHT_MIXER_CONTROL, 0x0001 },86	{ NAU8822_REG_LHP_VOLUME, 0x0039 },87	{ NAU8822_REG_RHP_VOLUME, 0x0039 },88	{ NAU8822_REG_LSPKOUT_VOLUME, 0x0039 },89	{ NAU8822_REG_RSPKOUT_VOLUME, 0x0039 },90	{ NAU8822_REG_AUX2_MIXER, 0x0001 },91	{ NAU8822_REG_AUX1_MIXER, 0x0001 },92	{ NAU8822_REG_POWER_MANAGEMENT_4, 0x0000 },93	{ NAU8822_REG_LEFT_TIME_SLOT, 0x0000 },94	{ NAU8822_REG_MISC, 0x0020 },95	{ NAU8822_REG_RIGHT_TIME_SLOT, 0x0000 },96	{ NAU8822_REG_DEVICE_REVISION, 0x007f },97	{ NAU8822_REG_DEVICE_ID, 0x001a },98	{ NAU8822_REG_DAC_DITHER, 0x0114 },99	{ NAU8822_REG_ALC_ENHANCE_1, 0x0000 },100	{ NAU8822_REG_ALC_ENHANCE_2, 0x0000 },101	{ NAU8822_REG_192KHZ_SAMPLING, 0x0008 },102	{ NAU8822_REG_MISC_CONTROL, 0x0000 },103	{ NAU8822_REG_INPUT_TIEOFF, 0x0000 },104	{ NAU8822_REG_POWER_REDUCTION, 0x0000 },105	{ NAU8822_REG_AGC_PEAK2PEAK, 0x0000 },106	{ NAU8822_REG_AGC_PEAK_DETECT, 0x0000 },107	{ NAU8822_REG_AUTOMUTE_CONTROL, 0x0000 },108	{ NAU8822_REG_OUTPUT_TIEOFF, 0x0000 },109};110 111static bool nau8822_readable_reg(struct device *dev, unsigned int reg)112{113	switch (reg) {114	case NAU8822_REG_RESET ... NAU8822_REG_JACK_DETECT_CONTROL_1:115	case NAU8822_REG_DAC_CONTROL ... NAU8822_REG_LEFT_ADC_DIGITAL_VOLUME:116	case NAU8822_REG_RIGHT_ADC_DIGITAL_VOLUME:117	case NAU8822_REG_EQ1 ... NAU8822_REG_EQ5:118	case NAU8822_REG_DAC_LIMITER_1 ... NAU8822_REG_DAC_LIMITER_2:119	case NAU8822_REG_NOTCH_FILTER_1 ... NAU8822_REG_NOTCH_FILTER_4:120	case NAU8822_REG_ALC_CONTROL_1 ...NAU8822_REG_PLL_K3:121	case NAU8822_REG_3D_CONTROL:122	case NAU8822_REG_RIGHT_SPEAKER_CONTROL:123	case NAU8822_REG_INPUT_CONTROL ... NAU8822_REG_LEFT_ADC_BOOST_CONTROL:124	case NAU8822_REG_RIGHT_ADC_BOOST_CONTROL ... NAU8822_REG_AUX1_MIXER:125	case NAU8822_REG_POWER_MANAGEMENT_4 ... NAU8822_REG_DEVICE_ID:126	case NAU8822_REG_DAC_DITHER:127	case NAU8822_REG_ALC_ENHANCE_1 ... NAU8822_REG_MISC_CONTROL:128	case NAU8822_REG_INPUT_TIEOFF ... NAU8822_REG_OUTPUT_TIEOFF:129		return true;130	default:131		return false;132	}133}134 135static bool nau8822_writeable_reg(struct device *dev, unsigned int reg)136{137	switch (reg) {138	case NAU8822_REG_RESET ... NAU8822_REG_JACK_DETECT_CONTROL_1:139	case NAU8822_REG_DAC_CONTROL ... NAU8822_REG_LEFT_ADC_DIGITAL_VOLUME:140	case NAU8822_REG_RIGHT_ADC_DIGITAL_VOLUME:141	case NAU8822_REG_EQ1 ... NAU8822_REG_EQ5:142	case NAU8822_REG_DAC_LIMITER_1 ... NAU8822_REG_DAC_LIMITER_2:143	case NAU8822_REG_NOTCH_FILTER_1 ... NAU8822_REG_NOTCH_FILTER_4:144	case NAU8822_REG_ALC_CONTROL_1 ...NAU8822_REG_PLL_K3:145	case NAU8822_REG_3D_CONTROL:146	case NAU8822_REG_RIGHT_SPEAKER_CONTROL:147	case NAU8822_REG_INPUT_CONTROL ... NAU8822_REG_LEFT_ADC_BOOST_CONTROL:148	case NAU8822_REG_RIGHT_ADC_BOOST_CONTROL ... NAU8822_REG_AUX1_MIXER:149	case NAU8822_REG_POWER_MANAGEMENT_4 ... NAU8822_REG_DEVICE_ID:150	case NAU8822_REG_DAC_DITHER:151	case NAU8822_REG_ALC_ENHANCE_1 ... NAU8822_REG_MISC_CONTROL:152	case NAU8822_REG_INPUT_TIEOFF ... NAU8822_REG_OUTPUT_TIEOFF:153		return true;154	default:155		return false;156	}157}158 159static bool nau8822_volatile(struct device *dev, unsigned int reg)160{161	switch (reg) {162	case NAU8822_REG_RESET:163	case NAU8822_REG_DEVICE_REVISION:164	case NAU8822_REG_DEVICE_ID:165	case NAU8822_REG_AGC_PEAK2PEAK:166	case NAU8822_REG_AGC_PEAK_DETECT:167	case NAU8822_REG_AUTOMUTE_CONTROL:168		return true;169	default:170		return false;171	}172}173 174/* The EQ parameters get function is to get the 5 band equalizer control.175 * The regmap raw read can't work here because regmap doesn't provide176 * value format for value width of 9 bits. Therefore, the driver reads data177 * from cache and makes value format according to the endianness of178 * bytes type control element.179 */180static int nau8822_eq_get(struct snd_kcontrol *kcontrol,181	struct snd_ctl_elem_value *ucontrol)182{183	struct snd_soc_component *component =184			snd_soc_kcontrol_component(kcontrol);185	struct soc_bytes_ext *params = (void *)kcontrol->private_value;186	int i, reg;187	u16 reg_val, *val;188	__be16 tmp;189 190	val = (u16 *)ucontrol->value.bytes.data;191	reg = NAU8822_REG_EQ1;192	for (i = 0; i < params->max / sizeof(u16); i++) {193		reg_val = snd_soc_component_read(component, reg + i);194		/* conversion of 16-bit integers between native CPU format195		 * and big endian format196		 */197		tmp = cpu_to_be16(reg_val);198		memcpy(val + i, &tmp, sizeof(tmp));199	}200 201	return 0;202}203 204/* The EQ parameters put function is to make configuration of 5 band equalizer205 * control. These configuration includes central frequency, equalizer gain,206 * cut-off frequency, bandwidth control, and equalizer path.207 * The regmap raw write can't work here because regmap doesn't provide208 * register and value format for register with address 7 bits and value 9 bits.209 * Therefore, the driver makes value format according to the endianness of210 * bytes type control element and writes data to codec.211 */212static int nau8822_eq_put(struct snd_kcontrol *kcontrol,213	struct snd_ctl_elem_value *ucontrol)214{215	struct snd_soc_component *component =216			snd_soc_kcontrol_component(kcontrol);217	struct soc_bytes_ext *params = (void *)kcontrol->private_value;218	void *data;219	u16 *val, value;220	int i, reg, ret;221	__be16 *tmp;222 223	data = kmemdup(ucontrol->value.bytes.data,224		params->max, GFP_KERNEL | GFP_DMA);225	if (!data)226		return -ENOMEM;227 228	val = (u16 *)data;229	reg = NAU8822_REG_EQ1;230	for (i = 0; i < params->max / sizeof(u16); i++) {231		/* conversion of 16-bit integers between native CPU format232		 * and big endian format233		 */234		tmp = (__be16 *)(val + i);235		value = be16_to_cpup(tmp);236		ret = snd_soc_component_write(component, reg + i, value);237		if (ret) {238			dev_err(component->dev,239			    "EQ configuration fail, register: %x ret: %d\n",240			    reg + i, ret);241			kfree(data);242			return ret;243		}244	}245	kfree(data);246 247	return 0;248}249 250static const char * const nau8822_companding[] = {251	"Off", "NC", "u-law", "A-law"};252 253static const struct soc_enum nau8822_companding_adc_enum =254	SOC_ENUM_SINGLE(NAU8822_REG_COMPANDING_CONTROL, NAU8822_ADCCM_SFT,255		ARRAY_SIZE(nau8822_companding), nau8822_companding);256 257static const struct soc_enum nau8822_companding_dac_enum =258	SOC_ENUM_SINGLE(NAU8822_REG_COMPANDING_CONTROL, NAU8822_DACCM_SFT,259		ARRAY_SIZE(nau8822_companding), nau8822_companding);260 261static const char * const nau8822_eqmode[] = {"Capture", "Playback"};262 263static const struct soc_enum nau8822_eqmode_enum =264	SOC_ENUM_SINGLE(NAU8822_REG_EQ1, NAU8822_EQM_SFT,265		ARRAY_SIZE(nau8822_eqmode), nau8822_eqmode);266 267static const char * const nau8822_alc1[] = {"Off", "Right", "Left", "Both"};268static const char * const nau8822_alc3[] = {"Normal", "Limiter"};269 270static const struct soc_enum nau8822_alc_enable_enum =271	SOC_ENUM_SINGLE(NAU8822_REG_ALC_CONTROL_1, NAU8822_ALCEN_SFT,272		ARRAY_SIZE(nau8822_alc1), nau8822_alc1);273 274static const struct soc_enum nau8822_alc_mode_enum =275	SOC_ENUM_SINGLE(NAU8822_REG_ALC_CONTROL_3, NAU8822_ALCM_SFT,276		ARRAY_SIZE(nau8822_alc3), nau8822_alc3);277 278static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);279static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0);280static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0);281static const DECLARE_TLV_DB_SCALE(pga_boost_tlv, 0, 2000, 0);282static const DECLARE_TLV_DB_SCALE(boost_tlv, -1500, 300, 1);283static const DECLARE_TLV_DB_SCALE(limiter_tlv, 0, 100, 0);284 285static const struct snd_kcontrol_new nau8822_snd_controls[] = {286	SOC_ENUM("ADC Companding", nau8822_companding_adc_enum),287	SOC_ENUM("DAC Companding", nau8822_companding_dac_enum),288 289	SOC_ENUM("EQ Function", nau8822_eqmode_enum),290	SND_SOC_BYTES_EXT("EQ Parameters", 10,291		  nau8822_eq_get, nau8822_eq_put),292 293	SOC_DOUBLE("DAC Inversion Switch",294		NAU8822_REG_DAC_CONTROL, 0, 1, 1, 0),295	SOC_DOUBLE_R_TLV("PCM Volume",296		NAU8822_REG_LEFT_DAC_DIGITAL_VOLUME,297		NAU8822_REG_RIGHT_DAC_DIGITAL_VOLUME, 0, 255, 0, digital_tlv),298 299	SOC_SINGLE("High Pass Filter Switch",300		NAU8822_REG_ADC_CONTROL, 8, 1, 0),301	SOC_SINGLE("High Pass Cut Off",302		NAU8822_REG_ADC_CONTROL, 4, 7, 0),303 304	SOC_DOUBLE("ADC Inversion Switch",305		NAU8822_REG_ADC_CONTROL, 0, 1, 1, 0),306	SOC_DOUBLE_R_TLV("ADC Volume",307		NAU8822_REG_LEFT_ADC_DIGITAL_VOLUME,308		NAU8822_REG_RIGHT_ADC_DIGITAL_VOLUME, 0, 255, 0, digital_tlv),309 310	SOC_SINGLE("DAC Limiter Switch",311		NAU8822_REG_DAC_LIMITER_1, 8, 1, 0),312	SOC_SINGLE("DAC Limiter Decay",313		NAU8822_REG_DAC_LIMITER_1, 4, 15, 0),314	SOC_SINGLE("DAC Limiter Attack",315		NAU8822_REG_DAC_LIMITER_1, 0, 15, 0),316	SOC_SINGLE("DAC Limiter Threshold",317		NAU8822_REG_DAC_LIMITER_2, 4, 7, 0),318	SOC_SINGLE_TLV("DAC Limiter Volume",319		NAU8822_REG_DAC_LIMITER_2, 0, 12, 0, limiter_tlv),320 321	SOC_ENUM("ALC Mode", nau8822_alc_mode_enum),322	SOC_ENUM("ALC Enable Switch", nau8822_alc_enable_enum),323	SOC_SINGLE("ALC Min Gain",324		NAU8822_REG_ALC_CONTROL_1, 0, 7, 0),325	SOC_SINGLE("ALC Max Gain",326		NAU8822_REG_ALC_CONTROL_1, 3, 7, 0),327	SOC_SINGLE("ALC Hold",328		NAU8822_REG_ALC_CONTROL_2, 4, 10, 0),329	SOC_SINGLE("ALC Target",330		NAU8822_REG_ALC_CONTROL_2, 0, 15, 0),331	SOC_SINGLE("ALC Decay",332		NAU8822_REG_ALC_CONTROL_3, 4, 10, 0),333	SOC_SINGLE("ALC Attack",334		NAU8822_REG_ALC_CONTROL_3, 0, 10, 0),335	SOC_SINGLE("ALC Noise Gate Switch",336		NAU8822_REG_NOISE_GATE, 3, 1, 0),337	SOC_SINGLE("ALC Noise Gate Threshold",338		NAU8822_REG_NOISE_GATE, 0, 7, 0),339 340	SOC_DOUBLE_R("PGA ZC Switch",341		NAU8822_REG_LEFT_INP_PGA_CONTROL,342		NAU8822_REG_RIGHT_INP_PGA_CONTROL,343		7, 1, 0),344	SOC_DOUBLE_R_TLV("PGA Volume",345		NAU8822_REG_LEFT_INP_PGA_CONTROL,346		NAU8822_REG_RIGHT_INP_PGA_CONTROL, 0, 63, 0, inpga_tlv),347 348	SOC_DOUBLE_R("Headphone ZC Switch",349		NAU8822_REG_LHP_VOLUME,350		NAU8822_REG_RHP_VOLUME, 7, 1, 0),351	SOC_DOUBLE_R("Headphone Playback Switch",352		NAU8822_REG_LHP_VOLUME,353		NAU8822_REG_RHP_VOLUME, 6, 1, 1),354	SOC_DOUBLE_R_TLV("Headphone Volume",355		NAU8822_REG_LHP_VOLUME,356		NAU8822_REG_RHP_VOLUME,	0, 63, 0, spk_tlv),357 358	SOC_DOUBLE_R("Speaker ZC Switch",359		NAU8822_REG_LSPKOUT_VOLUME,360		NAU8822_REG_RSPKOUT_VOLUME, 7, 1, 0),361	SOC_DOUBLE_R("Speaker Playback Switch",362		NAU8822_REG_LSPKOUT_VOLUME,363		NAU8822_REG_RSPKOUT_VOLUME, 6, 1, 1),364	SOC_DOUBLE_R_TLV("Speaker Volume",365		NAU8822_REG_LSPKOUT_VOLUME,366		NAU8822_REG_RSPKOUT_VOLUME, 0, 63, 0, spk_tlv),367 368	SOC_DOUBLE_R("AUXOUT Playback Switch",369		NAU8822_REG_AUX2_MIXER,370		NAU8822_REG_AUX1_MIXER, 6, 1, 1),371 372	SOC_DOUBLE_R_TLV("PGA Boost Volume",373		NAU8822_REG_LEFT_ADC_BOOST_CONTROL,374		NAU8822_REG_RIGHT_ADC_BOOST_CONTROL, 8, 1, 0, pga_boost_tlv),375	SOC_DOUBLE_R_TLV("L2/R2 Boost Volume",376		NAU8822_REG_LEFT_ADC_BOOST_CONTROL,377		NAU8822_REG_RIGHT_ADC_BOOST_CONTROL, 4, 7, 0, boost_tlv),378	SOC_DOUBLE_R_TLV("Aux Boost Volume",379		NAU8822_REG_LEFT_ADC_BOOST_CONTROL,380		NAU8822_REG_RIGHT_ADC_BOOST_CONTROL, 0, 7, 0, boost_tlv),381 382	SOC_SINGLE("DAC 128x Oversampling Switch",383		NAU8822_REG_DAC_CONTROL, 5, 1, 0),384	SOC_SINGLE("ADC 128x Oversampling Switch",385		NAU8822_REG_ADC_CONTROL, 5, 1, 0),386};387 388/* LMAIN and RMAIN Mixer */389static const struct snd_kcontrol_new nau8822_left_out_mixer[] = {390	SOC_DAPM_SINGLE("LINMIX Switch",391		NAU8822_REG_LEFT_MIXER_CONTROL, 1, 1, 0),392	SOC_DAPM_SINGLE("LAUX Switch",393		NAU8822_REG_LEFT_MIXER_CONTROL, 5, 1, 0),394	SOC_DAPM_SINGLE("LDAC Switch",395		NAU8822_REG_LEFT_MIXER_CONTROL, 0, 1, 0),396	SOC_DAPM_SINGLE("RDAC Switch",397		NAU8822_REG_OUTPUT_CONTROL, 5, 1, 0),398};399 400static const struct snd_kcontrol_new nau8822_right_out_mixer[] = {401	SOC_DAPM_SINGLE("RINMIX Switch",402		NAU8822_REG_RIGHT_MIXER_CONTROL, 1, 1, 0),403	SOC_DAPM_SINGLE("RAUX Switch",404		NAU8822_REG_RIGHT_MIXER_CONTROL, 5, 1, 0),405	SOC_DAPM_SINGLE("RDAC Switch",406		NAU8822_REG_RIGHT_MIXER_CONTROL, 0, 1, 0),407	SOC_DAPM_SINGLE("LDAC Switch",408		NAU8822_REG_OUTPUT_CONTROL, 6, 1, 0),409};410 411/* AUX1 and AUX2 Mixer */412static const struct snd_kcontrol_new nau8822_auxout1_mixer[] = {413	SOC_DAPM_SINGLE("RDAC Switch", NAU8822_REG_AUX1_MIXER, 0, 1, 0),414	SOC_DAPM_SINGLE("RMIX Switch", NAU8822_REG_AUX1_MIXER, 1, 1, 0),415	SOC_DAPM_SINGLE("RINMIX Switch", NAU8822_REG_AUX1_MIXER, 2, 1, 0),416	SOC_DAPM_SINGLE("LDAC Switch", NAU8822_REG_AUX1_MIXER, 3, 1, 0),417	SOC_DAPM_SINGLE("LMIX Switch", NAU8822_REG_AUX1_MIXER, 4, 1, 0),418};419 420static const struct snd_kcontrol_new nau8822_auxout2_mixer[] = {421	SOC_DAPM_SINGLE("LDAC Switch", NAU8822_REG_AUX2_MIXER, 0, 1, 0),422	SOC_DAPM_SINGLE("LMIX Switch", NAU8822_REG_AUX2_MIXER, 1, 1, 0),423	SOC_DAPM_SINGLE("LINMIX Switch", NAU8822_REG_AUX2_MIXER, 2, 1, 0),424	SOC_DAPM_SINGLE("AUX1MIX Output Switch",425		NAU8822_REG_AUX2_MIXER, 3, 1, 0),426};427 428/* Input PGA */429static const struct snd_kcontrol_new nau8822_left_input_mixer[] = {430	SOC_DAPM_SINGLE("L2 Switch", NAU8822_REG_INPUT_CONTROL, 2, 1, 0),431	SOC_DAPM_SINGLE("MicN Switch", NAU8822_REG_INPUT_CONTROL, 1, 1, 0),432	SOC_DAPM_SINGLE("MicP Switch", NAU8822_REG_INPUT_CONTROL, 0, 1, 0),433};434static const struct snd_kcontrol_new nau8822_right_input_mixer[] = {435	SOC_DAPM_SINGLE("R2 Switch", NAU8822_REG_INPUT_CONTROL, 6, 1, 0),436	SOC_DAPM_SINGLE("MicN Switch", NAU8822_REG_INPUT_CONTROL, 5, 1, 0),437	SOC_DAPM_SINGLE("MicP Switch", NAU8822_REG_INPUT_CONTROL, 4, 1, 0),438};439 440/* Loopback Switch */441static const struct snd_kcontrol_new nau8822_loopback =442	SOC_DAPM_SINGLE("Switch", NAU8822_REG_COMPANDING_CONTROL,443		NAU8822_ADDAP_SFT, 1, 0);444 445static int check_mclk_select_pll(struct snd_soc_dapm_widget *source,446			 struct snd_soc_dapm_widget *sink)447{448	struct snd_soc_component *component =449		snd_soc_dapm_to_component(source->dapm);450	unsigned int value;451 452	value = snd_soc_component_read(component, NAU8822_REG_CLOCKING);453 454	return (value & NAU8822_CLKM_MASK);455}456 457static const struct snd_soc_dapm_widget nau8822_dapm_widgets[] = {458	SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback",459		NAU8822_REG_POWER_MANAGEMENT_3, 0, 0),460	SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback",461		NAU8822_REG_POWER_MANAGEMENT_3, 1, 0),462	SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture",463		NAU8822_REG_POWER_MANAGEMENT_2, 0, 0),464	SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture",465		NAU8822_REG_POWER_MANAGEMENT_2, 1, 0),466 467	SOC_MIXER_ARRAY("Left Output Mixer",468		NAU8822_REG_POWER_MANAGEMENT_3, 2, 0, nau8822_left_out_mixer),469	SOC_MIXER_ARRAY("Right Output Mixer",470		NAU8822_REG_POWER_MANAGEMENT_3,	3, 0, nau8822_right_out_mixer),471	SOC_MIXER_ARRAY("AUX1 Output Mixer",472		NAU8822_REG_POWER_MANAGEMENT_1, 7, 0, nau8822_auxout1_mixer),473	SOC_MIXER_ARRAY("AUX2 Output Mixer",474		NAU8822_REG_POWER_MANAGEMENT_1,	6, 0, nau8822_auxout2_mixer),475 476	SOC_MIXER_ARRAY("Left Input Mixer",477		NAU8822_REG_POWER_MANAGEMENT_2,478		2, 0, nau8822_left_input_mixer),479	SOC_MIXER_ARRAY("Right Input Mixer",480		NAU8822_REG_POWER_MANAGEMENT_2,481		3, 0, nau8822_right_input_mixer),482 483	SND_SOC_DAPM_PGA("Left Boost Mixer",484		NAU8822_REG_POWER_MANAGEMENT_2, 4, 0, NULL, 0),485	SND_SOC_DAPM_PGA("Right Boost Mixer",486		NAU8822_REG_POWER_MANAGEMENT_2, 5, 0, NULL, 0),487 488	SND_SOC_DAPM_PGA("Left Capture PGA",489		NAU8822_REG_LEFT_INP_PGA_CONTROL, 6, 1, NULL, 0),490	SND_SOC_DAPM_PGA("Right Capture PGA",491		NAU8822_REG_RIGHT_INP_PGA_CONTROL, 6, 1, NULL, 0),492 493	SND_SOC_DAPM_PGA("Left Headphone Out",494		NAU8822_REG_POWER_MANAGEMENT_2, 7, 0, NULL, 0),495	SND_SOC_DAPM_PGA("Right Headphone Out",496		NAU8822_REG_POWER_MANAGEMENT_2, 8, 0, NULL, 0),497 498	SND_SOC_DAPM_PGA("Left Speaker Out",499		 NAU8822_REG_POWER_MANAGEMENT_3, 6, 0, NULL, 0),500	SND_SOC_DAPM_PGA("Right Speaker Out",501		NAU8822_REG_POWER_MANAGEMENT_3,	5, 0, NULL, 0),502 503	SND_SOC_DAPM_PGA("AUX1 Out",504		NAU8822_REG_POWER_MANAGEMENT_3,	8, 0, NULL, 0),505	SND_SOC_DAPM_PGA("AUX2 Out",506		NAU8822_REG_POWER_MANAGEMENT_3,	7, 0, NULL, 0),507 508	SND_SOC_DAPM_SUPPLY("Mic Bias",509		NAU8822_REG_POWER_MANAGEMENT_1,	4, 0, NULL, 0),510	SND_SOC_DAPM_SUPPLY("PLL",511		NAU8822_REG_POWER_MANAGEMENT_1,	5, 0, NULL, 0),512 513	SND_SOC_DAPM_SWITCH("Digital Loopback", SND_SOC_NOPM, 0, 0,514		&nau8822_loopback),515 516	SND_SOC_DAPM_INPUT("LMICN"),517	SND_SOC_DAPM_INPUT("LMICP"),518	SND_SOC_DAPM_INPUT("RMICN"),519	SND_SOC_DAPM_INPUT("RMICP"),520	SND_SOC_DAPM_INPUT("LAUX"),521	SND_SOC_DAPM_INPUT("RAUX"),522	SND_SOC_DAPM_INPUT("L2"),523	SND_SOC_DAPM_INPUT("R2"),524	SND_SOC_DAPM_OUTPUT("LHP"),525	SND_SOC_DAPM_OUTPUT("RHP"),526	SND_SOC_DAPM_OUTPUT("LSPK"),527	SND_SOC_DAPM_OUTPUT("RSPK"),528	SND_SOC_DAPM_OUTPUT("AUXOUT1"),529	SND_SOC_DAPM_OUTPUT("AUXOUT2"),530};531 532static const struct snd_soc_dapm_route nau8822_dapm_routes[] = {533	{"Right DAC", NULL, "PLL", check_mclk_select_pll},534	{"Left DAC", NULL, "PLL", check_mclk_select_pll},535 536	/* LMAIN and RMAIN Mixer */537	{"Right Output Mixer", "LDAC Switch", "Left DAC"},538	{"Right Output Mixer", "RDAC Switch", "Right DAC"},539	{"Right Output Mixer", "RAUX Switch", "RAUX"},540	{"Right Output Mixer", "RINMIX Switch", "Right Boost Mixer"},541 542	{"Left Output Mixer", "LDAC Switch", "Left DAC"},543	{"Left Output Mixer", "RDAC Switch", "Right DAC"},544	{"Left Output Mixer", "LAUX Switch", "LAUX"},545	{"Left Output Mixer", "LINMIX Switch", "Left Boost Mixer"},546 547	/* AUX1 and AUX2 Mixer */548	{"AUX1 Output Mixer", "RDAC Switch", "Right DAC"},549	{"AUX1 Output Mixer", "RMIX Switch", "Right Output Mixer"},550	{"AUX1 Output Mixer", "RINMIX Switch", "Right Boost Mixer"},551	{"AUX1 Output Mixer", "LDAC Switch", "Left DAC"},552	{"AUX1 Output Mixer", "LMIX Switch", "Left Output Mixer"},553 554	{"AUX2 Output Mixer", "LDAC Switch", "Left DAC"},555	{"AUX2 Output Mixer", "LMIX Switch", "Left Output Mixer"},556	{"AUX2 Output Mixer", "LINMIX Switch", "Left Boost Mixer"},557	{"AUX2 Output Mixer", "AUX1MIX Output Switch", "AUX1 Output Mixer"},558 559	/* Outputs */560	{"Right Headphone Out", NULL, "Right Output Mixer"},561	{"RHP", NULL, "Right Headphone Out"},562 563	{"Left Headphone Out", NULL, "Left Output Mixer"},564	{"LHP", NULL, "Left Headphone Out"},565 566	{"Right Speaker Out", NULL, "Right Output Mixer"},567	{"RSPK", NULL, "Right Speaker Out"},568 569	{"Left Speaker Out", NULL, "Left Output Mixer"},570	{"LSPK", NULL, "Left Speaker Out"},571 572	{"AUX1 Out", NULL, "AUX1 Output Mixer"},573	{"AUX2 Out", NULL, "AUX2 Output Mixer"},574	{"AUXOUT1", NULL, "AUX1 Out"},575	{"AUXOUT2", NULL, "AUX2 Out"},576 577	/* Boost Mixer */578	{"Right ADC", NULL, "PLL", check_mclk_select_pll},579	{"Left ADC", NULL, "PLL", check_mclk_select_pll},580 581	{"Right ADC", NULL, "Right Boost Mixer"},582 583	{"Right Boost Mixer", NULL, "RAUX"},584	{"Right Boost Mixer", NULL, "Right Capture PGA"},585	{"Right Boost Mixer", NULL, "R2"},586 587	{"Left ADC", NULL, "Left Boost Mixer"},588 589	{"Left Boost Mixer", NULL, "LAUX"},590	{"Left Boost Mixer", NULL, "Left Capture PGA"},591	{"Left Boost Mixer", NULL, "L2"},592 593	/* Input PGA */594	{"Right Capture PGA", NULL, "Right Input Mixer"},595	{"Left Capture PGA", NULL, "Left Input Mixer"},596 597	/* Enable Microphone Power */598	{"Right Capture PGA", NULL, "Mic Bias"},599	{"Left Capture PGA", NULL, "Mic Bias"},600 601	{"Right Input Mixer", "R2 Switch", "R2"},602	{"Right Input Mixer", "MicN Switch", "RMICN"},603	{"Right Input Mixer", "MicP Switch", "RMICP"},604 605	{"Left Input Mixer", "L2 Switch", "L2"},606	{"Left Input Mixer", "MicN Switch", "LMICN"},607	{"Left Input Mixer", "MicP Switch", "LMICP"},608 609	/* Digital Loopback */610	{"Digital Loopback", "Switch", "Left ADC"},611	{"Digital Loopback", "Switch", "Right ADC"},612	{"Left DAC", NULL, "Digital Loopback"},613	{"Right DAC", NULL, "Digital Loopback"},614};615 616static int nau8822_calc_pll(unsigned int pll_in, unsigned int fs,617				struct nau8822_pll *pll_param)618{619	u64 f2, f2_max, pll_ratio;620	int i, scal_sel;621 622	if (pll_in > NAU_PLL_REF_MAX || pll_in < NAU_PLL_REF_MIN)623		return -EINVAL;624	f2_max = 0;625	scal_sel = ARRAY_SIZE(nau8822_mclk_scaler);626 627	for (i = 0; i < scal_sel; i++) {628		f2 = 256 * fs * 4 * nau8822_mclk_scaler[i] / 10;629		if (f2 > NAU_PLL_FREQ_MIN && f2 < NAU_PLL_FREQ_MAX &&630			f2_max < f2) {631			f2_max = f2;632			scal_sel = i;633		}634	}635 636	if (ARRAY_SIZE(nau8822_mclk_scaler) == scal_sel)637		return -EINVAL;638	pll_param->mclk_scaler = scal_sel;639	f2 = f2_max;640 641	/* Calculate the PLL 4-bit integer input and the PLL 24-bit fractional642	 * input; round up the 24+4bit.643	 */644	pll_ratio = div_u64(f2 << 28, pll_in);645	pll_param->pre_factor = 0;646	if (((pll_ratio >> 28) & 0xF) < NAU_PLL_OPTOP_MIN) {647		pll_ratio <<= 1;648		pll_param->pre_factor = 1;649	}650	pll_param->pll_int = (pll_ratio >> 28) & 0xF;651	pll_param->pll_frac = ((pll_ratio & 0xFFFFFFF) >> 4);652 653	return 0;654}655 656static int nau8822_config_clkdiv(struct snd_soc_dai *dai, int div, int rate)657{658	struct snd_soc_component *component = dai->component;659	struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component);660	struct nau8822_pll *pll = &nau8822->pll;661	int i, sclk, imclk;662 663	switch (nau8822->div_id) {664	case NAU8822_CLK_MCLK:665		/* Configure the master clock prescaler div to make system666		 * clock to approximate the internal master clock (IMCLK);667		 * and large or equal to IMCLK.668		 */669		div = 0;670		imclk = rate * 256;671		for (i = 1; i < ARRAY_SIZE(nau8822_mclk_scaler); i++) {672			sclk = (nau8822->sysclk * 10) /	nau8822_mclk_scaler[i];673			if (sclk < imclk)674				break;675			div = i;676		}677		dev_dbg(component->dev, "master clock prescaler %x for fs %d\n",678			div, rate);679 680		/* master clock from MCLK and disable PLL */681		snd_soc_component_update_bits(component,682			NAU8822_REG_CLOCKING, NAU8822_MCLKSEL_MASK,683			(div << NAU8822_MCLKSEL_SFT));684		snd_soc_component_update_bits(component,685			NAU8822_REG_CLOCKING, NAU8822_CLKM_MASK,686			NAU8822_CLKM_MCLK);687		break;688 689	case NAU8822_CLK_PLL:690		/* master clock from PLL and enable PLL */691		if (pll->mclk_scaler != div) {692			dev_err(component->dev,693			"master clock prescaler not meet PLL parameters\n");694			return -EINVAL;695		}696		snd_soc_component_update_bits(component,697			NAU8822_REG_CLOCKING, NAU8822_MCLKSEL_MASK,698			(div << NAU8822_MCLKSEL_SFT));699		snd_soc_component_update_bits(component,700			NAU8822_REG_CLOCKING, NAU8822_CLKM_MASK,701			NAU8822_CLKM_PLL);702		break;703 704	default:705		return -EINVAL;706	}707 708	return 0;709}710 711static int nau8822_set_pll(struct snd_soc_dai *dai, int pll_id, int source,712				unsigned int freq_in, unsigned int freq_out)713{714	struct snd_soc_component *component = dai->component;715	struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component);716	struct nau8822_pll *pll_param = &nau8822->pll;717	int ret, fs;718 719	if (freq_in == pll_param->freq_in &&720	    freq_out == pll_param->freq_out)721		return 0;722 723	if (freq_out == 0) {724		dev_dbg(component->dev, "PLL disabled\n");725		snd_soc_component_update_bits(component,726			NAU8822_REG_POWER_MANAGEMENT_1, NAU8822_PLL_EN_MASK, NAU8822_PLL_OFF);727		return 0;728	}729 730	fs = freq_out / 256;731 732	ret = nau8822_calc_pll(freq_in, fs, pll_param);733	if (ret < 0) {734		dev_err(component->dev, "Unsupported input clock %d\n",735			freq_in);736		return ret;737	}738 739	dev_dbg(component->dev,740		"pll_int=%x pll_frac=%x mclk_scaler=%x pre_factor=%x\n",741		pll_param->pll_int, pll_param->pll_frac,742		pll_param->mclk_scaler, pll_param->pre_factor);743 744	snd_soc_component_update_bits(component,745		NAU8822_REG_POWER_MANAGEMENT_1, NAU8822_PLL_EN_MASK, NAU8822_PLL_OFF);746	snd_soc_component_update_bits(component,747		NAU8822_REG_PLL_N, NAU8822_PLLMCLK_DIV2 | NAU8822_PLLN_MASK,748		(pll_param->pre_factor ? NAU8822_PLLMCLK_DIV2 : 0) |749		pll_param->pll_int);750	snd_soc_component_write(component,751		NAU8822_REG_PLL_K1, (pll_param->pll_frac >> NAU8822_PLLK1_SFT) &752		NAU8822_PLLK1_MASK);753	snd_soc_component_write(component,754		NAU8822_REG_PLL_K2, (pll_param->pll_frac >> NAU8822_PLLK2_SFT) &755		NAU8822_PLLK2_MASK);756	snd_soc_component_write(component,757		NAU8822_REG_PLL_K3, pll_param->pll_frac & NAU8822_PLLK3_MASK);758	snd_soc_component_update_bits(component,759		NAU8822_REG_CLOCKING, NAU8822_MCLKSEL_MASK,760		pll_param->mclk_scaler << NAU8822_MCLKSEL_SFT);761	snd_soc_component_update_bits(component,762		NAU8822_REG_CLOCKING, NAU8822_CLKM_MASK, NAU8822_CLKM_PLL);763	snd_soc_component_update_bits(component,764		NAU8822_REG_POWER_MANAGEMENT_1, NAU8822_PLL_EN_MASK, NAU8822_PLL_ON);765 766	pll_param->freq_in = freq_in;767	pll_param->freq_out = freq_out;768 769	return 0;770}771 772static int nau8822_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,773				 unsigned int freq, int dir)774{775	struct snd_soc_component *component = dai->component;776	struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component);777	unsigned long mclk_freq;778 779	nau8822->div_id = clk_id;780	nau8822->sysclk = freq;781 782	if (nau8822->mclk) {783		mclk_freq = clk_get_rate(nau8822->mclk);784		if (mclk_freq != freq) {785			int ret = nau8822_set_pll(dai, NAU8822_CLK_MCLK,786				NAU8822_CLK_MCLK, mclk_freq, freq);787			if (ret) {788				dev_err(component->dev, "Failed to set PLL\n");789				return ret;790			}791			nau8822->div_id = NAU8822_CLK_PLL;792		}793	}794 795	dev_dbg(component->dev, "master sysclk %dHz, source %s\n", freq,796		nau8822->div_id == NAU8822_CLK_PLL ? "PLL" : "MCLK");797 798	return 0;799}800 801static int nau8822_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)802{803	struct snd_soc_component *component = dai->component;804	u16 ctrl1_val = 0, ctrl2_val = 0;805 806	dev_dbg(component->dev, "%s\n", __func__);807 808	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {809	case SND_SOC_DAIFMT_CBM_CFM:810		ctrl2_val |= 1;811		break;812	case SND_SOC_DAIFMT_CBS_CFS:813		ctrl2_val &= ~1;814		break;815	default:816		return -EINVAL;817	}818 819	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {820	case SND_SOC_DAIFMT_I2S:821		ctrl1_val |= 0x10;822		break;823	case SND_SOC_DAIFMT_RIGHT_J:824		break;825	case SND_SOC_DAIFMT_LEFT_J:826		ctrl1_val |= 0x8;827		break;828	case SND_SOC_DAIFMT_DSP_A:829		ctrl1_val |= 0x18;830		break;831	default:832		return -EINVAL;833	}834 835	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {836	case SND_SOC_DAIFMT_NB_NF:837		break;838	case SND_SOC_DAIFMT_IB_IF:839		ctrl1_val |= 0x180;840		break;841	case SND_SOC_DAIFMT_IB_NF:842		ctrl1_val |= 0x100;843		break;844	case SND_SOC_DAIFMT_NB_IF:845		ctrl1_val |= 0x80;846		break;847	default:848		return -EINVAL;849	}850 851	snd_soc_component_update_bits(component,852		NAU8822_REG_AUDIO_INTERFACE,853		NAU8822_AIFMT_MASK | NAU8822_LRP_MASK | NAU8822_BCLKP_MASK,854		ctrl1_val);855	snd_soc_component_update_bits(component,856		NAU8822_REG_CLOCKING, NAU8822_CLKIOEN_MASK, ctrl2_val);857 858	return 0;859}860 861static int nau8822_hw_params(struct snd_pcm_substream *substream,862			    struct snd_pcm_hw_params *params,863			    struct snd_soc_dai *dai)864{865	struct snd_soc_component *component = dai->component;866	struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component);867	int div = 0, val_len = 0, val_rate = 0;868	unsigned int ctrl_val, bclk_fs, bclk_div;869 870	/* make BCLK and LRC divide configuration if the codec as master. */871	ctrl_val = snd_soc_component_read(component, NAU8822_REG_CLOCKING);872	if (ctrl_val & NAU8822_CLK_MASTER) {873		/* get the bclk and fs ratio */874		bclk_fs = snd_soc_params_to_bclk(params) / params_rate(params);875		if (bclk_fs <= 32)876			bclk_div = NAU8822_BCLKDIV_8;877		else if (bclk_fs <= 64)878			bclk_div = NAU8822_BCLKDIV_4;879		else if (bclk_fs <= 128)880			bclk_div = NAU8822_BCLKDIV_2;881		else882			return -EINVAL;883		snd_soc_component_update_bits(component, NAU8822_REG_CLOCKING,884				NAU8822_BCLKSEL_MASK, bclk_div);885	}886 887	switch (params_format(params)) {888	case SNDRV_PCM_FORMAT_S16_LE:889		break;890	case SNDRV_PCM_FORMAT_S20_3LE:891		val_len |= NAU8822_WLEN_20;892		break;893	case SNDRV_PCM_FORMAT_S24_LE:894		val_len |= NAU8822_WLEN_24;895		break;896	case SNDRV_PCM_FORMAT_S32_LE:897		val_len |= NAU8822_WLEN_32;898		break;899	default:900		return -EINVAL;901	}902 903	switch (params_rate(params)) {904	case 8000:905		val_rate |= NAU8822_SMPLR_8K;906		break;907	case 11025:908		val_rate |= NAU8822_SMPLR_12K;909		break;910	case 16000:911		val_rate |= NAU8822_SMPLR_16K;912		break;913	case 22050:914		val_rate |= NAU8822_SMPLR_24K;915		break;916	case 32000:917		val_rate |= NAU8822_SMPLR_32K;918		break;919	case 44100:920	case 48000:921		break;922	default:923		return -EINVAL;924	}925 926	snd_soc_component_update_bits(component,927		NAU8822_REG_AUDIO_INTERFACE, NAU8822_WLEN_MASK, val_len);928	snd_soc_component_update_bits(component,929		NAU8822_REG_ADDITIONAL_CONTROL, NAU8822_SMPLR_MASK, val_rate);930 931	/* If the master clock is from MCLK, provide the runtime FS for driver932	 * to get the master clock prescaler configuration.933	 */934	if (nau8822->div_id != NAU8822_CLK_MCLK)935		div = nau8822->pll.mclk_scaler;936 937	nau8822_config_clkdiv(dai, div, params_rate(params));938 939	return 0;940}941 942static int nau8822_mute(struct snd_soc_dai *dai, int mute, int direction)943{944	struct snd_soc_component *component = dai->component;945 946	dev_dbg(component->dev, "%s: %d\n", __func__, mute);947 948	if (mute)949		snd_soc_component_update_bits(component,950			NAU8822_REG_DAC_CONTROL, 0x40, 0x40);951	else952		snd_soc_component_update_bits(component,953			NAU8822_REG_DAC_CONTROL, 0x40, 0);954 955	return 0;956}957 958static int nau8822_set_bias_level(struct snd_soc_component *component,959				 enum snd_soc_bias_level level)960{961	struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component);962 963	switch (level) {964	case SND_SOC_BIAS_ON:965		break;966 967	case SND_SOC_BIAS_PREPARE:968		if (nau8822->mclk &&969			snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_ON) {970			int ret = clk_prepare_enable(nau8822->mclk);971 972			if (ret) {973				dev_err(component->dev,974					"Failed to enable MCLK: %d\n", ret);975				return ret;976			}977		}978 979		snd_soc_component_update_bits(component,980			NAU8822_REG_POWER_MANAGEMENT_1,981			NAU8822_REFIMP_MASK, NAU8822_REFIMP_80K);982		break;983 984	case SND_SOC_BIAS_STANDBY:985		if (nau8822->mclk &&986			snd_soc_component_get_bias_level(component) != SND_SOC_BIAS_OFF)987			clk_disable_unprepare(nau8822->mclk);988 989		snd_soc_component_update_bits(component,990			NAU8822_REG_POWER_MANAGEMENT_1,991			NAU8822_IOBUF_EN | NAU8822_ABIAS_EN,992			NAU8822_IOBUF_EN | NAU8822_ABIAS_EN);993 994		if (snd_soc_component_get_bias_level(component) ==995			SND_SOC_BIAS_OFF) {996			snd_soc_component_update_bits(component,997				NAU8822_REG_POWER_MANAGEMENT_1,998				NAU8822_REFIMP_MASK, NAU8822_REFIMP_3K);999			mdelay(100);1000		}1001		snd_soc_component_update_bits(component,1002			NAU8822_REG_POWER_MANAGEMENT_1,1003			NAU8822_REFIMP_MASK, NAU8822_REFIMP_300K);1004		break;1005 1006	case SND_SOC_BIAS_OFF:1007		snd_soc_component_write(component,1008			NAU8822_REG_POWER_MANAGEMENT_1, 0);1009		snd_soc_component_write(component,1010			NAU8822_REG_POWER_MANAGEMENT_2, 0);1011		snd_soc_component_write(component,1012			NAU8822_REG_POWER_MANAGEMENT_3, 0);1013		break;1014	}1015 1016	dev_dbg(component->dev, "%s: %d\n", __func__, level);1017 1018	return 0;1019}1020 1021#define NAU8822_RATES (SNDRV_PCM_RATE_8000_48000)1022 1023#define NAU8822_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \1024	SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)1025 1026static const struct snd_soc_dai_ops nau8822_dai_ops = {1027	.hw_params	= nau8822_hw_params,1028	.mute_stream	= nau8822_mute,1029	.set_fmt	= nau8822_set_dai_fmt,1030	.set_sysclk	= nau8822_set_dai_sysclk,1031	.set_pll	= nau8822_set_pll,1032	.no_capture_mute = 1,1033};1034 1035static struct snd_soc_dai_driver nau8822_dai = {1036	.name = "nau8822-hifi",1037	.playback = {1038		.stream_name = "Playback",1039		.channels_min = 1,1040		.channels_max = 2,1041		.rates = NAU8822_RATES,1042		.formats = NAU8822_FORMATS,1043	},1044	.capture = {1045		.stream_name = "Capture",1046		.channels_min = 1,1047		.channels_max = 2,1048		.rates = NAU8822_RATES,1049		.formats = NAU8822_FORMATS,1050	},1051	.ops = &nau8822_dai_ops,1052	.symmetric_rate = 1,1053};1054 1055static int nau8822_suspend(struct snd_soc_component *component)1056{1057	struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component);1058 1059	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);1060 1061	regcache_mark_dirty(nau8822->regmap);1062 1063	return 0;1064}1065 1066static int nau8822_resume(struct snd_soc_component *component)1067{1068	struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component);1069 1070	regcache_sync(nau8822->regmap);1071 1072	snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY);1073 1074	return 0;1075}1076 1077/*1078 * These registers contain an "update" bit - bit 8. This means, for example,1079 * that one can write new DAC digital volume for both channels, but only when1080 * the update bit is set, will also the volume be updated - simultaneously for1081 * both channels.1082 */1083static const int update_reg[] = {1084	NAU8822_REG_LEFT_DAC_DIGITAL_VOLUME,1085	NAU8822_REG_RIGHT_DAC_DIGITAL_VOLUME,1086	NAU8822_REG_LEFT_ADC_DIGITAL_VOLUME,1087	NAU8822_REG_RIGHT_ADC_DIGITAL_VOLUME,1088	NAU8822_REG_LEFT_INP_PGA_CONTROL,1089	NAU8822_REG_RIGHT_INP_PGA_CONTROL,1090	NAU8822_REG_LHP_VOLUME,1091	NAU8822_REG_RHP_VOLUME,1092	NAU8822_REG_LSPKOUT_VOLUME,1093	NAU8822_REG_RSPKOUT_VOLUME,1094};1095 1096static int nau8822_probe(struct snd_soc_component *component)1097{1098	int i;1099	struct device_node *of_node = component->dev->of_node;1100 1101	/*1102	 * Set the update bit in all registers, that have one. This way all1103	 * writes to those registers will also cause the update bit to be1104	 * written.1105	 */1106	for (i = 0; i < ARRAY_SIZE(update_reg); i++)1107		snd_soc_component_update_bits(component,1108			update_reg[i], 0x100, 0x100);1109 1110	/* Check property to configure the two loudspeaker outputs as1111	 * a single Bridge Tied Load output1112	 */1113	if (of_property_read_bool(of_node, "nuvoton,spk-btl"))1114		snd_soc_component_update_bits(component,1115					      NAU8822_REG_RIGHT_SPEAKER_CONTROL,1116					      NAU8822_RSUBBYP, NAU8822_RSUBBYP);1117 1118	return 0;1119}1120 1121static const struct snd_soc_component_driver soc_component_dev_nau8822 = {1122	.probe				= nau8822_probe,1123	.suspend			= nau8822_suspend,1124	.resume				= nau8822_resume,1125	.set_bias_level			= nau8822_set_bias_level,1126	.controls			= nau8822_snd_controls,1127	.num_controls			= ARRAY_SIZE(nau8822_snd_controls),1128	.dapm_widgets			= nau8822_dapm_widgets,1129	.num_dapm_widgets		= ARRAY_SIZE(nau8822_dapm_widgets),1130	.dapm_routes			= nau8822_dapm_routes,1131	.num_dapm_routes		= ARRAY_SIZE(nau8822_dapm_routes),1132	.idle_bias_on			= 1,1133	.use_pmdown_time		= 1,1134	.endianness			= 1,1135};1136 1137static const struct regmap_config nau8822_regmap_config = {1138	.reg_bits = 7,1139	.val_bits = 9,1140 1141	.max_register = NAU8822_REG_MAX_REGISTER,1142	.volatile_reg = nau8822_volatile,1143 1144	.readable_reg = nau8822_readable_reg,1145	.writeable_reg = nau8822_writeable_reg,1146 1147	.cache_type = REGCACHE_RBTREE,1148	.reg_defaults = nau8822_reg_defaults,1149	.num_reg_defaults = ARRAY_SIZE(nau8822_reg_defaults),1150};1151 1152static int nau8822_i2c_probe(struct i2c_client *i2c)1153{1154	struct device *dev = &i2c->dev;1155	struct nau8822 *nau8822 = dev_get_platdata(dev);1156	int ret;1157 1158	if (!nau8822) {1159		nau8822 = devm_kzalloc(dev, sizeof(*nau8822), GFP_KERNEL);1160		if (nau8822 == NULL)1161			return -ENOMEM;1162	}1163	i2c_set_clientdata(i2c, nau8822);1164 1165	nau8822->mclk = devm_clk_get_optional(&i2c->dev, "mclk");1166	if (IS_ERR(nau8822->mclk))1167		return dev_err_probe(&i2c->dev, PTR_ERR(nau8822->mclk),1168			"Error getting mclk\n");1169 1170	nau8822->regmap = devm_regmap_init_i2c(i2c, &nau8822_regmap_config);1171	if (IS_ERR(nau8822->regmap)) {1172		ret = PTR_ERR(nau8822->regmap);1173		dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);1174		return ret;1175	}1176	nau8822->dev = dev;1177 1178	/* Reset the codec */1179	ret = regmap_write(nau8822->regmap, NAU8822_REG_RESET, 0x00);1180	if (ret != 0) {1181		dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret);1182		return ret;1183	}1184 1185	ret = devm_snd_soc_register_component(dev, &soc_component_dev_nau8822,1186						&nau8822_dai, 1);1187	if (ret != 0) {1188		dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);1189		return ret;1190	}1191 1192	return 0;1193}1194 1195static const struct i2c_device_id nau8822_i2c_id[] = {1196	{ "nau8822" },1197	{ }1198};1199MODULE_DEVICE_TABLE(i2c, nau8822_i2c_id);1200 1201#ifdef CONFIG_OF1202static const struct of_device_id nau8822_of_match[] = {1203	{ .compatible = "nuvoton,nau8822", },1204	{ }1205};1206MODULE_DEVICE_TABLE(of, nau8822_of_match);1207#endif1208 1209static struct i2c_driver nau8822_i2c_driver = {1210	.driver = {1211		.name = "nau8822",1212		.of_match_table = of_match_ptr(nau8822_of_match),1213	},1214	.probe = nau8822_i2c_probe,1215	.id_table = nau8822_i2c_id,1216};1217module_i2c_driver(nau8822_i2c_driver);1218 1219MODULE_DESCRIPTION("ASoC NAU8822 codec driver");1220MODULE_AUTHOR("David Lin <ctlin0@nuvoton.com>");1221MODULE_LICENSE("GPL v2");1222