brintos

brintos / linux-shallow public Read only

0
0
Text · 30.1 KiB · 7e59448 Raw
994 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * NAU85L40 ALSA SoC audio driver4 *5 * Copyright 2016 Nuvoton Technology Corp.6 * Author: John Hsu <KCHSU0@nuvoton.com>7 */8 9#include <linux/module.h>10#include <linux/moduleparam.h>11#include <linux/init.h>12#include <linux/delay.h>13#include <linux/pm.h>14#include <linux/i2c.h>15#include <linux/regmap.h>16#include <linux/regulator/consumer.h>17#include <linux/spi/spi.h>18#include <linux/slab.h>19#include <linux/of.h>20#include <sound/core.h>21#include <sound/pcm.h>22#include <sound/pcm_params.h>23#include <sound/soc.h>24#include <sound/soc-dapm.h>25#include <sound/initval.h>26#include <sound/tlv.h>27#include "nau8540.h"28 29#define NAU_FREF_MAX 1350000030#define NAU_FVCO_MAX 10000000031#define NAU_FVCO_MIN 9000000032 33/* the maximum frequency of CLK_ADC */34#define CLK_ADC_MAX 614400035 36/* scaling for mclk from sysclk_src output */37static const struct nau8540_fll_attr mclk_src_scaling[] = {38	{ 1, 0x0 },39	{ 2, 0x2 },40	{ 4, 0x3 },41	{ 8, 0x4 },42	{ 16, 0x5 },43	{ 32, 0x6 },44	{ 3, 0x7 },45	{ 6, 0xa },46	{ 12, 0xb },47	{ 24, 0xc },48};49 50/* ratio for input clk freq */51static const struct nau8540_fll_attr fll_ratio[] = {52	{ 512000, 0x01 },53	{ 256000, 0x02 },54	{ 128000, 0x04 },55	{ 64000, 0x08 },56	{ 32000, 0x10 },57	{ 8000, 0x20 },58	{ 4000, 0x40 },59};60 61static const struct nau8540_fll_attr fll_pre_scalar[] = {62	{ 1, 0x0 },63	{ 2, 0x1 },64	{ 4, 0x2 },65	{ 8, 0x3 },66};67 68/* over sampling rate */69static const struct nau8540_osr_attr osr_adc_sel[] = {70	{ 32, 3 },	/* OSR 32, SRC 1/8 */71	{ 64, 2 },	/* OSR 64, SRC 1/4 */72	{ 128, 1 },	/* OSR 128, SRC 1/2 */73	{ 256, 0 },	/* OSR 256, SRC 1 */74};75 76static const struct reg_default nau8540_reg_defaults[] = {77	{NAU8540_REG_POWER_MANAGEMENT, 0x0000},78	{NAU8540_REG_CLOCK_CTRL, 0x0000},79	{NAU8540_REG_CLOCK_SRC, 0x0000},80	{NAU8540_REG_FLL1, 0x0001},81	{NAU8540_REG_FLL2, 0x3126},82	{NAU8540_REG_FLL3, 0x0008},83	{NAU8540_REG_FLL4, 0x0010},84	{NAU8540_REG_FLL5, 0xC000},85	{NAU8540_REG_FLL6, 0x6000},86	{NAU8540_REG_FLL_VCO_RSV, 0xF13C},87	{NAU8540_REG_PCM_CTRL0, 0x000B},88	{NAU8540_REG_PCM_CTRL1, 0x3010},89	{NAU8540_REG_PCM_CTRL2, 0x0800},90	{NAU8540_REG_PCM_CTRL3, 0x0000},91	{NAU8540_REG_PCM_CTRL4, 0x000F},92	{NAU8540_REG_ALC_CONTROL_1, 0x0000},93	{NAU8540_REG_ALC_CONTROL_2, 0x700B},94	{NAU8540_REG_ALC_CONTROL_3, 0x0022},95	{NAU8540_REG_ALC_CONTROL_4, 0x1010},96	{NAU8540_REG_ALC_CONTROL_5, 0x1010},97	{NAU8540_REG_NOTCH_FIL1_CH1, 0x0000},98	{NAU8540_REG_NOTCH_FIL2_CH1, 0x0000},99	{NAU8540_REG_NOTCH_FIL1_CH2, 0x0000},100	{NAU8540_REG_NOTCH_FIL2_CH2, 0x0000},101	{NAU8540_REG_NOTCH_FIL1_CH3, 0x0000},102	{NAU8540_REG_NOTCH_FIL2_CH3, 0x0000},103	{NAU8540_REG_NOTCH_FIL1_CH4, 0x0000},104	{NAU8540_REG_NOTCH_FIL2_CH4, 0x0000},105	{NAU8540_REG_HPF_FILTER_CH12, 0x0000},106	{NAU8540_REG_HPF_FILTER_CH34, 0x0000},107	{NAU8540_REG_ADC_SAMPLE_RATE, 0x0002},108	{NAU8540_REG_DIGITAL_GAIN_CH1, 0x0400},109	{NAU8540_REG_DIGITAL_GAIN_CH2, 0x0400},110	{NAU8540_REG_DIGITAL_GAIN_CH3, 0x0400},111	{NAU8540_REG_DIGITAL_GAIN_CH4, 0x0400},112	{NAU8540_REG_DIGITAL_MUX, 0x00E4},113	{NAU8540_REG_GPIO_CTRL, 0x0000},114	{NAU8540_REG_MISC_CTRL, 0x0000},115	{NAU8540_REG_I2C_CTRL, 0xEFFF},116	{NAU8540_REG_VMID_CTRL, 0x0000},117	{NAU8540_REG_MUTE, 0x0000},118	{NAU8540_REG_ANALOG_ADC1, 0x0011},119	{NAU8540_REG_ANALOG_ADC2, 0x0020},120	{NAU8540_REG_ANALOG_PWR, 0x0000},121	{NAU8540_REG_MIC_BIAS, 0x0004},122	{NAU8540_REG_REFERENCE, 0x0000},123	{NAU8540_REG_FEPGA1, 0x0000},124	{NAU8540_REG_FEPGA2, 0x0000},125	{NAU8540_REG_FEPGA3, 0x0101},126	{NAU8540_REG_FEPGA4, 0x0101},127	{NAU8540_REG_PWR, 0x0000},128};129 130static bool nau8540_readable_reg(struct device *dev, unsigned int reg)131{132	switch (reg) {133	case NAU8540_REG_POWER_MANAGEMENT ... NAU8540_REG_FLL_VCO_RSV:134	case NAU8540_REG_PCM_CTRL0 ... NAU8540_REG_PCM_CTRL4:135	case NAU8540_REG_ALC_CONTROL_1 ... NAU8540_REG_ALC_CONTROL_5:136	case NAU8540_REG_ALC_GAIN_CH12 ... NAU8540_REG_ADC_SAMPLE_RATE:137	case NAU8540_REG_DIGITAL_GAIN_CH1 ... NAU8540_REG_DIGITAL_MUX:138	case NAU8540_REG_P2P_CH1 ... NAU8540_REG_I2C_CTRL:139	case NAU8540_REG_I2C_DEVICE_ID:140	case NAU8540_REG_VMID_CTRL ... NAU8540_REG_MUTE:141	case NAU8540_REG_ANALOG_ADC1 ... NAU8540_REG_PWR:142		return true;143	default:144		return false;145	}146 147}148 149static bool nau8540_writeable_reg(struct device *dev, unsigned int reg)150{151	switch (reg) {152	case NAU8540_REG_SW_RESET ... NAU8540_REG_FLL_VCO_RSV:153	case NAU8540_REG_PCM_CTRL0 ... NAU8540_REG_PCM_CTRL4:154	case NAU8540_REG_ALC_CONTROL_1 ... NAU8540_REG_ALC_CONTROL_5:155	case NAU8540_REG_NOTCH_FIL1_CH1 ... NAU8540_REG_ADC_SAMPLE_RATE:156	case NAU8540_REG_DIGITAL_GAIN_CH1 ... NAU8540_REG_DIGITAL_MUX:157	case NAU8540_REG_GPIO_CTRL ... NAU8540_REG_I2C_CTRL:158	case NAU8540_REG_RST:159	case NAU8540_REG_VMID_CTRL ... NAU8540_REG_MUTE:160	case NAU8540_REG_ANALOG_ADC1 ... NAU8540_REG_PWR:161		return true;162	default:163		return false;164	}165}166 167static bool nau8540_volatile_reg(struct device *dev, unsigned int reg)168{169	switch (reg) {170	case NAU8540_REG_SW_RESET:171	case NAU8540_REG_ALC_GAIN_CH12 ... NAU8540_REG_ALC_STATUS:172	case NAU8540_REG_P2P_CH1 ... NAU8540_REG_PEAK_CH4:173	case NAU8540_REG_I2C_DEVICE_ID:174	case NAU8540_REG_RST:175		return true;176	default:177		return false;178	}179}180 181 182static const DECLARE_TLV_DB_MINMAX(adc_vol_tlv, -12800, 3600);183static const DECLARE_TLV_DB_MINMAX(fepga_gain_tlv, -100, 3600);184 185static const struct snd_kcontrol_new nau8540_snd_controls[] = {186	SOC_SINGLE_TLV("Mic1 Volume", NAU8540_REG_DIGITAL_GAIN_CH1,187		0, 0x520, 0, adc_vol_tlv),188	SOC_SINGLE_TLV("Mic2 Volume", NAU8540_REG_DIGITAL_GAIN_CH2,189		0, 0x520, 0, adc_vol_tlv),190	SOC_SINGLE_TLV("Mic3 Volume", NAU8540_REG_DIGITAL_GAIN_CH3,191		0, 0x520, 0, adc_vol_tlv),192	SOC_SINGLE_TLV("Mic4 Volume", NAU8540_REG_DIGITAL_GAIN_CH4,193		0, 0x520, 0, adc_vol_tlv),194 195	SOC_SINGLE_TLV("Frontend PGA1 Volume", NAU8540_REG_FEPGA3,196		0, 0x25, 0, fepga_gain_tlv),197	SOC_SINGLE_TLV("Frontend PGA2 Volume", NAU8540_REG_FEPGA3,198		8, 0x25, 0, fepga_gain_tlv),199	SOC_SINGLE_TLV("Frontend PGA3 Volume", NAU8540_REG_FEPGA4,200		0, 0x25, 0, fepga_gain_tlv),201	SOC_SINGLE_TLV("Frontend PGA4 Volume", NAU8540_REG_FEPGA4,202		8, 0x25, 0, fepga_gain_tlv),203};204 205static const char * const adc_channel[] = {206	"ADC channel 1", "ADC channel 2", "ADC channel 3", "ADC channel 4"207};208static SOC_ENUM_SINGLE_DECL(209	digital_ch4_enum, NAU8540_REG_DIGITAL_MUX, 6, adc_channel);210 211static const struct snd_kcontrol_new digital_ch4_mux =212	SOC_DAPM_ENUM("Digital CH4 Select", digital_ch4_enum);213 214static SOC_ENUM_SINGLE_DECL(215	digital_ch3_enum, NAU8540_REG_DIGITAL_MUX, 4, adc_channel);216 217static const struct snd_kcontrol_new digital_ch3_mux =218	SOC_DAPM_ENUM("Digital CH3 Select", digital_ch3_enum);219 220static SOC_ENUM_SINGLE_DECL(221	digital_ch2_enum, NAU8540_REG_DIGITAL_MUX, 2, adc_channel);222 223static const struct snd_kcontrol_new digital_ch2_mux =224	SOC_DAPM_ENUM("Digital CH2 Select", digital_ch2_enum);225 226static SOC_ENUM_SINGLE_DECL(227	digital_ch1_enum, NAU8540_REG_DIGITAL_MUX, 0, adc_channel);228 229static const struct snd_kcontrol_new digital_ch1_mux =230	SOC_DAPM_ENUM("Digital CH1 Select", digital_ch1_enum);231 232static int nau8540_fepga_event(struct snd_soc_dapm_widget *w,233			       struct snd_kcontrol *k, int event)234{235	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);236	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);237 238	switch (event) {239	case SND_SOC_DAPM_POST_PMU:240		regmap_update_bits(nau8540->regmap, NAU8540_REG_FEPGA2,241				   NAU8540_ACDC_CTL_MASK, NAU8540_ACDC_CTL_MIC1P_VREF |242				   NAU8540_ACDC_CTL_MIC1N_VREF | NAU8540_ACDC_CTL_MIC2P_VREF |243				   NAU8540_ACDC_CTL_MIC2N_VREF | NAU8540_ACDC_CTL_MIC3P_VREF |244				   NAU8540_ACDC_CTL_MIC3N_VREF | NAU8540_ACDC_CTL_MIC4P_VREF |245				   NAU8540_ACDC_CTL_MIC4N_VREF);246		break;247	default:248		break;249	}250	return 0;251}252 253static int nau8540_precharge_event(struct snd_soc_dapm_widget *w,254				   struct snd_kcontrol *k, int event)255{256	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);257	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);258 259	switch (event) {260	case SND_SOC_DAPM_POST_PMU:261		regmap_update_bits(nau8540->regmap, NAU8540_REG_REFERENCE,262				   NAU8540_DISCHRG_EN, NAU8540_DISCHRG_EN);263		msleep(40);264		regmap_update_bits(nau8540->regmap, NAU8540_REG_REFERENCE,265				   NAU8540_DISCHRG_EN, 0);266		regmap_update_bits(nau8540->regmap, NAU8540_REG_FEPGA2,267				   NAU8540_ACDC_CTL_MASK, 0);268		break;269	default:270		break;271	}272	return 0;273}274 275static int adc_power_control(struct snd_soc_dapm_widget *w,276		struct snd_kcontrol *k, int  event)277{278	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);279	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);280 281	if (SND_SOC_DAPM_EVENT_ON(event)) {282		msleep(160);283		/* DO12 and DO34 pad output enable */284		regmap_update_bits(nau8540->regmap, NAU8540_REG_POWER_MANAGEMENT,285				   NAU8540_ADC_ALL_EN, NAU8540_ADC_ALL_EN);286		regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL1,287			NAU8540_I2S_DO12_TRI, 0);288		regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL2,289			NAU8540_I2S_DO34_TRI, 0);290	} else if (SND_SOC_DAPM_EVENT_OFF(event)) {291		regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL1,292			NAU8540_I2S_DO12_TRI, NAU8540_I2S_DO12_TRI);293		regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL2,294			NAU8540_I2S_DO34_TRI, NAU8540_I2S_DO34_TRI);295		regmap_update_bits(nau8540->regmap, NAU8540_REG_POWER_MANAGEMENT,296				   NAU8540_ADC_ALL_EN, 0);297	}298	return 0;299}300 301static int aiftx_power_control(struct snd_soc_dapm_widget *w,302		struct snd_kcontrol *k, int  event)303{304	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);305	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);306 307	if (SND_SOC_DAPM_EVENT_OFF(event)) {308		regmap_write(nau8540->regmap, NAU8540_REG_RST, 0x0001);309		regmap_write(nau8540->regmap, NAU8540_REG_RST, 0x0000);310	}311	return 0;312}313 314static const struct snd_soc_dapm_widget nau8540_dapm_widgets[] = {315	SND_SOC_DAPM_SUPPLY("MICBIAS2", NAU8540_REG_MIC_BIAS, 11, 0, NULL, 0),316	SND_SOC_DAPM_SUPPLY("MICBIAS1", NAU8540_REG_MIC_BIAS, 10, 0, NULL, 0),317 318	SND_SOC_DAPM_INPUT("MIC1"),319	SND_SOC_DAPM_INPUT("MIC2"),320	SND_SOC_DAPM_INPUT("MIC3"),321	SND_SOC_DAPM_INPUT("MIC4"),322 323	SND_SOC_DAPM_PGA_S("Frontend PGA1", 0, NAU8540_REG_PWR, 12, 0,324			   nau8540_fepga_event, SND_SOC_DAPM_POST_PMU),325	SND_SOC_DAPM_PGA_S("Frontend PGA2", 0, NAU8540_REG_PWR, 13, 0,326			   nau8540_fepga_event, SND_SOC_DAPM_POST_PMU),327	SND_SOC_DAPM_PGA_S("Frontend PGA3", 0, NAU8540_REG_PWR, 14, 0,328			   nau8540_fepga_event, SND_SOC_DAPM_POST_PMU),329	SND_SOC_DAPM_PGA_S("Frontend PGA4", 0, NAU8540_REG_PWR, 15, 0,330			   nau8540_fepga_event, SND_SOC_DAPM_POST_PMU),331 332	SND_SOC_DAPM_PGA_S("Precharge", 1, SND_SOC_NOPM, 0, 0,333			   nau8540_precharge_event, SND_SOC_DAPM_POST_PMU),334 335	SND_SOC_DAPM_PGA_S("ADC CH1", 2, NAU8540_REG_ANALOG_PWR, 0, 0,336			   adc_power_control, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),337	SND_SOC_DAPM_PGA_S("ADC CH2", 2, NAU8540_REG_ANALOG_PWR, 1, 0,338			   adc_power_control, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),339	SND_SOC_DAPM_PGA_S("ADC CH3", 2, NAU8540_REG_ANALOG_PWR, 2, 0,340			   adc_power_control, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),341	SND_SOC_DAPM_PGA_S("ADC CH4", 2, NAU8540_REG_ANALOG_PWR, 3, 0,342			   adc_power_control, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),343 344	SND_SOC_DAPM_MUX("Digital CH4 Mux",345		SND_SOC_NOPM, 0, 0, &digital_ch4_mux),346	SND_SOC_DAPM_MUX("Digital CH3 Mux",347		SND_SOC_NOPM, 0, 0, &digital_ch3_mux),348	SND_SOC_DAPM_MUX("Digital CH2 Mux",349		SND_SOC_NOPM, 0, 0, &digital_ch2_mux),350	SND_SOC_DAPM_MUX("Digital CH1 Mux",351		SND_SOC_NOPM, 0, 0, &digital_ch1_mux),352 353	SND_SOC_DAPM_AIF_OUT_E("AIFTX", "Capture", 0, SND_SOC_NOPM, 0, 0,354		aiftx_power_control, SND_SOC_DAPM_POST_PMD),355};356 357static const struct snd_soc_dapm_route nau8540_dapm_routes[] = {358	{"Frontend PGA1", NULL, "MIC1"},359	{"Frontend PGA2", NULL, "MIC2"},360	{"Frontend PGA3", NULL, "MIC3"},361	{"Frontend PGA4", NULL, "MIC4"},362 363	{"Precharge", NULL, "Frontend PGA1"},364	{"Precharge", NULL, "Frontend PGA2"},365	{"Precharge", NULL, "Frontend PGA3"},366	{"Precharge", NULL, "Frontend PGA4"},367 368	{"ADC CH1", NULL, "Precharge"},369	{"ADC CH2", NULL, "Precharge"},370	{"ADC CH3", NULL, "Precharge"},371	{"ADC CH4", NULL, "Precharge"},372 373	{"ADC CH1", NULL, "MICBIAS1"},374	{"ADC CH2", NULL, "MICBIAS1"},375	{"ADC CH3", NULL, "MICBIAS2"},376	{"ADC CH4", NULL, "MICBIAS2"},377 378	{"Digital CH1 Mux", "ADC channel 1", "ADC CH1"},379	{"Digital CH1 Mux", "ADC channel 2", "ADC CH2"},380	{"Digital CH1 Mux", "ADC channel 3", "ADC CH3"},381	{"Digital CH1 Mux", "ADC channel 4", "ADC CH4"},382 383	{"Digital CH2 Mux", "ADC channel 1", "ADC CH1"},384	{"Digital CH2 Mux", "ADC channel 2", "ADC CH2"},385	{"Digital CH2 Mux", "ADC channel 3", "ADC CH3"},386	{"Digital CH2 Mux", "ADC channel 4", "ADC CH4"},387 388	{"Digital CH3 Mux", "ADC channel 1", "ADC CH1"},389	{"Digital CH3 Mux", "ADC channel 2", "ADC CH2"},390	{"Digital CH3 Mux", "ADC channel 3", "ADC CH3"},391	{"Digital CH3 Mux", "ADC channel 4", "ADC CH4"},392 393	{"Digital CH4 Mux", "ADC channel 1", "ADC CH1"},394	{"Digital CH4 Mux", "ADC channel 2", "ADC CH2"},395	{"Digital CH4 Mux", "ADC channel 3", "ADC CH3"},396	{"Digital CH4 Mux", "ADC channel 4", "ADC CH4"},397 398	{"AIFTX", NULL, "Digital CH1 Mux"},399	{"AIFTX", NULL, "Digital CH2 Mux"},400	{"AIFTX", NULL, "Digital CH3 Mux"},401	{"AIFTX", NULL, "Digital CH4 Mux"},402};403 404static const struct nau8540_osr_attr *405nau8540_get_osr(struct nau8540 *nau8540)406{407	unsigned int osr;408 409	regmap_read(nau8540->regmap, NAU8540_REG_ADC_SAMPLE_RATE, &osr);410	osr &= NAU8540_ADC_OSR_MASK;411	if (osr >= ARRAY_SIZE(osr_adc_sel))412		return NULL;413	return &osr_adc_sel[osr];414}415 416static int nau8540_dai_startup(struct snd_pcm_substream *substream,417			       struct snd_soc_dai *dai)418{419	struct snd_soc_component *component = dai->component;420	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);421	const struct nau8540_osr_attr *osr;422 423	osr = nau8540_get_osr(nau8540);424	if (!osr || !osr->osr)425		return -EINVAL;426 427	return snd_pcm_hw_constraint_minmax(substream->runtime,428					    SNDRV_PCM_HW_PARAM_RATE,429					    0, CLK_ADC_MAX / osr->osr);430}431 432static int nau8540_hw_params(struct snd_pcm_substream *substream,433	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)434{435	struct snd_soc_component *component = dai->component;436	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);437	unsigned int val_len = 0;438	const struct nau8540_osr_attr *osr;439 440	/* CLK_ADC = OSR * FS441	 * ADC clock frequency is defined as Over Sampling Rate (OSR)442	 * multiplied by the audio sample rate (Fs). Note that the OSR and Fs443	 * values must be selected such that the maximum frequency is less444	 * than 6.144 MHz.445	 */446	osr = nau8540_get_osr(nau8540);447	if (!osr || !osr->osr)448		return -EINVAL;449	if (params_rate(params) * osr->osr > CLK_ADC_MAX)450		return -EINVAL;451	regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC,452		NAU8540_CLK_ADC_SRC_MASK,453		osr->clk_src << NAU8540_CLK_ADC_SRC_SFT);454 455	switch (params_width(params)) {456	case 16:457		val_len |= NAU8540_I2S_DL_16;458		break;459	case 20:460		val_len |= NAU8540_I2S_DL_20;461		break;462	case 24:463		val_len |= NAU8540_I2S_DL_24;464		break;465	case 32:466		val_len |= NAU8540_I2S_DL_32;467		break;468	default:469		return -EINVAL;470	}471 472	regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL0,473		NAU8540_I2S_DL_MASK, val_len);474 475	return 0;476}477 478static int nau8540_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)479{480	struct snd_soc_component *component = dai->component;481	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);482	unsigned int ctrl1_val = 0, ctrl2_val = 0;483 484	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {485	case SND_SOC_DAIFMT_CBM_CFM:486		ctrl2_val |= NAU8540_I2S_MS_MASTER;487		break;488	case SND_SOC_DAIFMT_CBS_CFS:489		break;490	default:491		return -EINVAL;492	}493 494	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {495	case SND_SOC_DAIFMT_NB_NF:496		break;497	case SND_SOC_DAIFMT_IB_NF:498		ctrl1_val |= NAU8540_I2S_BP_INV;499		break;500	default:501		return -EINVAL;502	}503 504	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {505	case SND_SOC_DAIFMT_I2S:506		ctrl1_val |= NAU8540_I2S_DF_I2S;507		break;508	case SND_SOC_DAIFMT_LEFT_J:509		ctrl1_val |= NAU8540_I2S_DF_LEFT;510		break;511	case SND_SOC_DAIFMT_RIGHT_J:512		ctrl1_val |= NAU8540_I2S_DF_RIGTH;513		break;514	case SND_SOC_DAIFMT_DSP_A:515		ctrl1_val |= NAU8540_I2S_DF_PCM_AB;516		break;517	case SND_SOC_DAIFMT_DSP_B:518		ctrl1_val |= NAU8540_I2S_DF_PCM_AB;519		ctrl1_val |= NAU8540_I2S_PCMB_EN;520		break;521	default:522		return -EINVAL;523	}524 525	regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL0,526		NAU8540_I2S_DL_MASK | NAU8540_I2S_DF_MASK |527		NAU8540_I2S_BP_INV | NAU8540_I2S_PCMB_EN, ctrl1_val);528	regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL1,529		NAU8540_I2S_MS_MASK | NAU8540_I2S_DO12_OE, ctrl2_val);530	regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL2,531		NAU8540_I2S_DO34_OE, 0);532 533	return 0;534}535 536/**537 * nau8540_set_tdm_slot - configure DAI TX TDM.538 * @dai: DAI539 * @tx_mask: bitmask representing active TX slots. Ex.540 *                 0xf for normal 4 channel TDM.541 *                 0xf0 for shifted 4 channel TDM542 * @rx_mask: no used.543 * @slots: Number of slots in use.544 * @slot_width: Width in bits for each slot.545 *546 * Configures a DAI for TDM operation. Only support 4 slots TDM.547 */548static int nau8540_set_tdm_slot(struct snd_soc_dai *dai,549	unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)550{551	struct snd_soc_component *component = dai->component;552	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);553	unsigned int ctrl2_val = 0, ctrl4_val = 0;554 555	if (slots > 4 || ((tx_mask & 0xf0) && (tx_mask & 0xf)))556		return -EINVAL;557 558	ctrl4_val |= (NAU8540_TDM_MODE | NAU8540_TDM_OFFSET_EN);559	if (tx_mask & 0xf0) {560		ctrl2_val = 4 * slot_width;561		ctrl4_val |= (tx_mask >> 4);562	} else {563		ctrl4_val |= tx_mask;564	}565	regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL4,566		NAU8540_TDM_MODE | NAU8540_TDM_OFFSET_EN |567		NAU8540_TDM_TX_MASK, ctrl4_val);568	regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL1,569		NAU8540_I2S_DO12_OE, NAU8540_I2S_DO12_OE);570	regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL2,571		NAU8540_I2S_DO34_OE | NAU8540_I2S_TSLOT_L_MASK,572		NAU8540_I2S_DO34_OE | ctrl2_val);573 574	return 0;575}576 577static int nau8540_dai_trigger(struct snd_pcm_substream *substream,578			       int cmd, struct snd_soc_dai *dai)579{580	struct snd_soc_component *component = dai->component;581	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);582	struct regmap *regmap = nau8540->regmap;583	unsigned int val;584	int ret = 0;585 586	/* Reading the peak data to detect abnormal data in the ADC channel.587	 * If abnormal data happens, the driver takes recovery actions to588	 * refresh the ADC channel.589	 */590	switch (cmd) {591	case SNDRV_PCM_TRIGGER_START:592		regmap_update_bits(regmap, NAU8540_REG_CLOCK_CTRL,593				   NAU8540_CLK_AGC_EN, NAU8540_CLK_AGC_EN);594		regmap_update_bits(regmap, NAU8540_REG_ALC_CONTROL_3,595				   NAU8540_ALC_CH_ALL_EN, NAU8540_ALC_CH_ALL_EN);596 597		regmap_read(regmap, NAU8540_REG_PEAK_CH1, &val);598		dev_dbg(nau8540->dev, "1.ADC CH1 peak data %x", val);599		if (!val) {600			regmap_update_bits(regmap, NAU8540_REG_MUTE,601					   NAU8540_PGA_CH_ALL_MUTE, NAU8540_PGA_CH_ALL_MUTE);602			regmap_update_bits(regmap, NAU8540_REG_MUTE,603					   NAU8540_PGA_CH_ALL_MUTE, 0);604			regmap_write(regmap, NAU8540_REG_RST, 0x1);605			regmap_write(regmap, NAU8540_REG_RST, 0);606			regmap_read(regmap, NAU8540_REG_PEAK_CH1, &val);607			dev_dbg(nau8540->dev, "2.ADC CH1 peak data %x", val);608			if (!val) {609				dev_err(nau8540->dev, "Channel recovery failed!!");610				ret = -EIO;611			}612		}613		regmap_update_bits(regmap, NAU8540_REG_CLOCK_CTRL,614				   NAU8540_CLK_AGC_EN, 0);615		regmap_update_bits(regmap, NAU8540_REG_ALC_CONTROL_3,616				   NAU8540_ALC_CH_ALL_EN, 0);617		break;618 619	default:620		break;621	}622 623	return ret;624}625 626static const struct snd_soc_dai_ops nau8540_dai_ops = {627	.startup = nau8540_dai_startup,628	.hw_params = nau8540_hw_params,629	.set_fmt = nau8540_set_fmt,630	.set_tdm_slot = nau8540_set_tdm_slot,631	.trigger = nau8540_dai_trigger,632};633 634#define NAU8540_RATES SNDRV_PCM_RATE_8000_48000635#define NAU8540_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \636	 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)637 638static struct snd_soc_dai_driver nau8540_dai = {639	.name = "nau8540-hifi",640	.capture = {641		.stream_name = "Capture",642		.channels_min = 1,643		.channels_max = 4,644		.rates = NAU8540_RATES,645		.formats = NAU8540_FORMATS,646	},647	.ops = &nau8540_dai_ops,648};649 650/**651 * nau8540_calc_fll_param - Calculate FLL parameters.652 * @fll_in: external clock provided to codec.653 * @fs: sampling rate.654 * @fll_param: Pointer to structure of FLL parameters.655 *656 * Calculate FLL parameters to configure codec.657 *658 * Returns 0 for success or negative error code.659 */660static int nau8540_calc_fll_param(unsigned int fll_in,661	unsigned int fs, struct nau8540_fll *fll_param)662{663	u64 fvco, fvco_max;664	unsigned int fref, i, fvco_sel;665 666	/* Ensure the reference clock frequency (FREF) is <= 13.5MHz by dividing667	 * freq_in by 1, 2, 4, or 8 using FLL pre-scalar.668	 * FREF = freq_in / NAU8540_FLL_REF_DIV_MASK669	 */670	for (i = 0; i < ARRAY_SIZE(fll_pre_scalar); i++) {671		fref = fll_in / fll_pre_scalar[i].param;672		if (fref <= NAU_FREF_MAX)673			break;674	}675	if (i == ARRAY_SIZE(fll_pre_scalar))676		return -EINVAL;677	fll_param->clk_ref_div = fll_pre_scalar[i].val;678 679	/* Choose the FLL ratio based on FREF */680	for (i = 0; i < ARRAY_SIZE(fll_ratio); i++) {681		if (fref >= fll_ratio[i].param)682			break;683	}684	if (i == ARRAY_SIZE(fll_ratio))685		return -EINVAL;686	fll_param->ratio = fll_ratio[i].val;687 688	/* Calculate the frequency of DCO (FDCO) given freq_out = 256 * Fs.689	 * FDCO must be within the 90MHz - 124MHz or the FFL cannot be690	 * guaranteed across the full range of operation.691	 * FDCO = freq_out * 2 * mclk_src_scaling692	 */693	fvco_max = 0;694	fvco_sel = ARRAY_SIZE(mclk_src_scaling);695	for (i = 0; i < ARRAY_SIZE(mclk_src_scaling); i++) {696		fvco = 256ULL * fs * 2 * mclk_src_scaling[i].param;697		if (fvco > NAU_FVCO_MIN && fvco < NAU_FVCO_MAX &&698			fvco_max < fvco) {699			fvco_max = fvco;700			fvco_sel = i;701		}702	}703	if (ARRAY_SIZE(mclk_src_scaling) == fvco_sel)704		return -EINVAL;705	fll_param->mclk_src = mclk_src_scaling[fvco_sel].val;706 707	/* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional708	 * input based on FDCO, FREF and FLL ratio.709	 */710	fvco = div_u64(fvco_max << 16, fref * fll_param->ratio);711	fll_param->fll_int = (fvco >> 16) & 0x3FF;712	fll_param->fll_frac = fvco & 0xFFFF;713	return 0;714}715 716static void nau8540_fll_apply(struct regmap *regmap,717	struct nau8540_fll *fll_param)718{719	regmap_update_bits(regmap, NAU8540_REG_CLOCK_SRC,720		NAU8540_CLK_SRC_MASK | NAU8540_CLK_MCLK_SRC_MASK,721		NAU8540_CLK_SRC_MCLK | fll_param->mclk_src);722	regmap_update_bits(regmap, NAU8540_REG_FLL1,723		NAU8540_FLL_RATIO_MASK | NAU8540_ICTRL_LATCH_MASK,724		fll_param->ratio | (0x6 << NAU8540_ICTRL_LATCH_SFT));725	/* FLL 16-bit fractional input */726	regmap_write(regmap, NAU8540_REG_FLL2, fll_param->fll_frac);727	/* FLL 10-bit integer input */728	regmap_update_bits(regmap, NAU8540_REG_FLL3,729		NAU8540_FLL_INTEGER_MASK, fll_param->fll_int);730	/* FLL pre-scaler */731	regmap_update_bits(regmap, NAU8540_REG_FLL4,732		NAU8540_FLL_REF_DIV_MASK,733		fll_param->clk_ref_div << NAU8540_FLL_REF_DIV_SFT);734	regmap_update_bits(regmap, NAU8540_REG_FLL5,735		NAU8540_FLL_CLK_SW_MASK, NAU8540_FLL_CLK_SW_REF);736	regmap_update_bits(regmap,737		NAU8540_REG_FLL6, NAU8540_DCO_EN, 0);738	if (fll_param->fll_frac) {739		regmap_update_bits(regmap, NAU8540_REG_FLL5,740			NAU8540_FLL_PDB_DAC_EN | NAU8540_FLL_LOOP_FTR_EN |741			NAU8540_FLL_FTR_SW_MASK,742			NAU8540_FLL_PDB_DAC_EN | NAU8540_FLL_LOOP_FTR_EN |743			NAU8540_FLL_FTR_SW_FILTER);744		regmap_update_bits(regmap, NAU8540_REG_FLL6,745			NAU8540_SDM_EN | NAU8540_CUTOFF500,746			NAU8540_SDM_EN | NAU8540_CUTOFF500);747	} else {748		regmap_update_bits(regmap, NAU8540_REG_FLL5,749			NAU8540_FLL_PDB_DAC_EN | NAU8540_FLL_LOOP_FTR_EN |750			NAU8540_FLL_FTR_SW_MASK, NAU8540_FLL_FTR_SW_ACCU);751		regmap_update_bits(regmap, NAU8540_REG_FLL6,752			NAU8540_SDM_EN | NAU8540_CUTOFF500, 0);753	}754}755 756/* freq_out must be 256*Fs in order to achieve the best performance */757static int nau8540_set_pll(struct snd_soc_component *component, int pll_id, int source,758		unsigned int freq_in, unsigned int freq_out)759{760	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);761	struct nau8540_fll fll_param;762	int ret, fs;763 764	switch (pll_id) {765	case NAU8540_CLK_FLL_MCLK:766		regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3,767			NAU8540_FLL_CLK_SRC_MASK | NAU8540_GAIN_ERR_MASK,768			NAU8540_FLL_CLK_SRC_MCLK | 0);769		break;770 771	case NAU8540_CLK_FLL_BLK:772		regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3,773			NAU8540_FLL_CLK_SRC_MASK | NAU8540_GAIN_ERR_MASK,774			NAU8540_FLL_CLK_SRC_BLK |775			(0xf << NAU8540_GAIN_ERR_SFT));776		break;777 778	case NAU8540_CLK_FLL_FS:779		regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3,780			NAU8540_FLL_CLK_SRC_MASK | NAU8540_GAIN_ERR_MASK,781			NAU8540_FLL_CLK_SRC_FS |782			(0xf << NAU8540_GAIN_ERR_SFT));783		break;784 785	default:786		dev_err(nau8540->dev, "Invalid clock id (%d)\n", pll_id);787		return -EINVAL;788	}789	dev_dbg(nau8540->dev, "Sysclk is %dHz and clock id is %d\n",790		freq_out, pll_id);791 792	fs = freq_out / 256;793	ret = nau8540_calc_fll_param(freq_in, fs, &fll_param);794	if (ret < 0) {795		dev_err(nau8540->dev, "Unsupported input clock %d\n", freq_in);796		return ret;797	}798	dev_dbg(nau8540->dev, "mclk_src=%x ratio=%x fll_frac=%x fll_int=%x clk_ref_div=%x\n",799		fll_param.mclk_src, fll_param.ratio, fll_param.fll_frac,800		fll_param.fll_int, fll_param.clk_ref_div);801 802	nau8540_fll_apply(nau8540->regmap, &fll_param);803	mdelay(2);804	regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC,805		NAU8540_CLK_SRC_MASK, NAU8540_CLK_SRC_VCO);806 807	return 0;808}809 810static int nau8540_set_sysclk(struct snd_soc_component *component,811	int clk_id, int source, unsigned int freq, int dir)812{813	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);814 815	switch (clk_id) {816	case NAU8540_CLK_DIS:817	case NAU8540_CLK_MCLK:818		regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC,819			NAU8540_CLK_SRC_MASK, NAU8540_CLK_SRC_MCLK);820		regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL6,821			NAU8540_DCO_EN, 0);822		break;823 824	case NAU8540_CLK_INTERNAL:825		regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL6,826			NAU8540_DCO_EN, NAU8540_DCO_EN);827		regmap_update_bits(nau8540->regmap, NAU8540_REG_CLOCK_SRC,828			NAU8540_CLK_SRC_MASK, NAU8540_CLK_SRC_VCO);829		break;830 831	default:832		dev_err(nau8540->dev, "Invalid clock id (%d)\n", clk_id);833		return -EINVAL;834	}835 836	dev_dbg(nau8540->dev, "Sysclk is %dHz and clock id is %d\n",837		freq, clk_id);838 839	return 0;840}841 842static void nau8540_reset_chip(struct regmap *regmap)843{844	regmap_write(regmap, NAU8540_REG_SW_RESET, 0x00);845	regmap_write(regmap, NAU8540_REG_SW_RESET, 0x00);846}847 848static void nau8540_init_regs(struct nau8540 *nau8540)849{850	struct regmap *regmap = nau8540->regmap;851 852	/* Enable Bias/VMID/VMID Tieoff */853	regmap_update_bits(regmap, NAU8540_REG_VMID_CTRL,854		NAU8540_VMID_EN | NAU8540_VMID_SEL_MASK,855		NAU8540_VMID_EN | (0x2 << NAU8540_VMID_SEL_SFT));856	regmap_update_bits(regmap, NAU8540_REG_REFERENCE,857		NAU8540_PRECHARGE_DIS | NAU8540_GLOBAL_BIAS_EN,858		NAU8540_PRECHARGE_DIS | NAU8540_GLOBAL_BIAS_EN);859	mdelay(2);860	regmap_update_bits(regmap, NAU8540_REG_MIC_BIAS,861		NAU8540_PU_PRE, NAU8540_PU_PRE);862	regmap_update_bits(regmap, NAU8540_REG_CLOCK_CTRL,863		NAU8540_CLK_ADC_EN | NAU8540_CLK_I2S_EN,864		NAU8540_CLK_ADC_EN | NAU8540_CLK_I2S_EN);865	/* ADC OSR selection, CLK_ADC = Fs * OSR;866	 * Channel time alignment enable.867	 */868	regmap_update_bits(regmap, NAU8540_REG_ADC_SAMPLE_RATE,869		NAU8540_CH_SYNC | NAU8540_ADC_OSR_MASK,870		NAU8540_CH_SYNC | NAU8540_ADC_OSR_64);871	/* PGA input mode selection */872	regmap_update_bits(regmap, NAU8540_REG_FEPGA1,873		NAU8540_FEPGA1_MODCH2_SHT | NAU8540_FEPGA1_MODCH1_SHT,874		NAU8540_FEPGA1_MODCH2_SHT | NAU8540_FEPGA1_MODCH1_SHT);875	regmap_update_bits(regmap, NAU8540_REG_FEPGA2,876		NAU8540_FEPGA2_MODCH4_SHT | NAU8540_FEPGA2_MODCH3_SHT,877		NAU8540_FEPGA2_MODCH4_SHT | NAU8540_FEPGA2_MODCH3_SHT);878	/* DO12 and DO34 pad output disable */879	regmap_update_bits(regmap, NAU8540_REG_PCM_CTRL1,880		NAU8540_I2S_DO12_TRI, NAU8540_I2S_DO12_TRI);881	regmap_update_bits(regmap, NAU8540_REG_PCM_CTRL2,882		NAU8540_I2S_DO34_TRI, NAU8540_I2S_DO34_TRI);883}884 885static int __maybe_unused nau8540_suspend(struct snd_soc_component *component)886{887	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);888 889	regcache_cache_only(nau8540->regmap, true);890	regcache_mark_dirty(nau8540->regmap);891 892	return 0;893}894 895static int __maybe_unused nau8540_resume(struct snd_soc_component *component)896{897	struct nau8540 *nau8540 = snd_soc_component_get_drvdata(component);898 899	regcache_cache_only(nau8540->regmap, false);900	regcache_sync(nau8540->regmap);901 902	return 0;903}904 905static const struct snd_soc_component_driver nau8540_component_driver = {906	.set_sysclk		= nau8540_set_sysclk,907	.set_pll		= nau8540_set_pll,908	.suspend		= nau8540_suspend,909	.resume			= nau8540_resume,910	.controls		= nau8540_snd_controls,911	.num_controls		= ARRAY_SIZE(nau8540_snd_controls),912	.dapm_widgets		= nau8540_dapm_widgets,913	.num_dapm_widgets	= ARRAY_SIZE(nau8540_dapm_widgets),914	.dapm_routes		= nau8540_dapm_routes,915	.num_dapm_routes	= ARRAY_SIZE(nau8540_dapm_routes),916	.suspend_bias_off	= 1,917	.idle_bias_on		= 1,918	.use_pmdown_time	= 1,919	.endianness		= 1,920};921 922static const struct regmap_config nau8540_regmap_config = {923	.val_bits = 16,924	.reg_bits = 16,925 926	.max_register = NAU8540_REG_MAX,927	.readable_reg = nau8540_readable_reg,928	.writeable_reg = nau8540_writeable_reg,929	.volatile_reg = nau8540_volatile_reg,930 931	.cache_type = REGCACHE_RBTREE,932	.reg_defaults = nau8540_reg_defaults,933	.num_reg_defaults = ARRAY_SIZE(nau8540_reg_defaults),934};935 936static int nau8540_i2c_probe(struct i2c_client *i2c)937{938	struct device *dev = &i2c->dev;939	struct nau8540 *nau8540 = dev_get_platdata(dev);940	int ret, value;941 942	if (!nau8540) {943		nau8540 = devm_kzalloc(dev, sizeof(*nau8540), GFP_KERNEL);944		if (!nau8540)945			return -ENOMEM;946	}947	i2c_set_clientdata(i2c, nau8540);948 949	nau8540->regmap = devm_regmap_init_i2c(i2c, &nau8540_regmap_config);950	if (IS_ERR(nau8540->regmap))951		return PTR_ERR(nau8540->regmap);952	ret = regmap_read(nau8540->regmap, NAU8540_REG_I2C_DEVICE_ID, &value);953	if (ret < 0) {954		dev_err(dev, "Failed to read device id from the NAU85L40: %d\n",955			ret);956		return ret;957	}958 959	nau8540->dev = dev;960	nau8540_reset_chip(nau8540->regmap);961	nau8540_init_regs(nau8540);962 963	return devm_snd_soc_register_component(dev,964		&nau8540_component_driver, &nau8540_dai, 1);965}966 967static const struct i2c_device_id nau8540_i2c_ids[] = {968	{ "nau8540" },969	{ }970};971MODULE_DEVICE_TABLE(i2c, nau8540_i2c_ids);972 973#ifdef CONFIG_OF974static const struct of_device_id nau8540_of_ids[] = {975	{ .compatible = "nuvoton,nau8540", },976	{}977};978MODULE_DEVICE_TABLE(of, nau8540_of_ids);979#endif980 981static struct i2c_driver nau8540_i2c_driver = {982	.driver = {983		.name = "nau8540",984		.of_match_table = of_match_ptr(nau8540_of_ids),985	},986	.probe = nau8540_i2c_probe,987	.id_table = nau8540_i2c_ids,988};989module_i2c_driver(nau8540_i2c_driver);990 991MODULE_DESCRIPTION("ASoC NAU85L40 driver");992MODULE_AUTHOR("John Hsu <KCHSU0@nuvoton.com>");993MODULE_LICENSE("GPL v2");994