brintos

brintos / linux-shallow public Read only

0
0
Text · 23.3 KiB · 8f24424 Raw
913 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * ak4619.c -- Asahi Kasei ALSA SoC Audio driver4 *5 * Copyright (C) 2023 Renesas Electronics Corporation6 * Khanh Le <khanh.le.xr@renesas.com>7 *8 * Based on ak4613.c by Kuninori Morimoto9 * Based on da7213.c by Adam Thomson10 * Based on ak4641.c by Harald Welte11 */12 13#include <linux/clk.h>14#include <linux/gpio/consumer.h>15#include <linux/i2c.h>16#include <linux/slab.h>17#include <linux/of_device.h>18#include <linux/module.h>19#include <linux/regmap.h>20#include <sound/soc.h>21#include <sound/pcm.h>22#include <sound/pcm_params.h>23#include <sound/tlv.h>24 25/*26 * Registers27 */28 29#define PWR_MGMT	0x00	/* Power Management */30#define AU_IFF1		0x01	/* Audio I/F Format */31#define AU_IFF2		0x02	/* Audio I/F Format (Extended) */32#define SYS_CLK		0x03	/* System Clock Setting */33#define MIC_AMP1	0x04	/* MIC AMP Gain 1 */34#define MIC_AMP2	0x05	/* MIC AMP Gain 2 */35#define LADC1		0x06	/* ADC1 Lch Digital Volume */36#define RADC1		0x07	/* ADC1 Rch Digital Volume */37#define LADC2		0x08	/* ADC2 Lch Digital Volume */38#define RADC2		0x09	/* ADC2 Rch Digital Volume */39#define ADC_DF		0x0a	/* ADC Digital Filter Setting */40#define ADC_AI		0x0b	/* ADC Analog Input Setting */41#define ADC_MHPF	0x0D	/* ADC Mute & HPF Control */42#define LDAC1		0x0E	/* DAC1 Lch Digital Volume */43#define RDAC1		0x0F	/* DAC1 Rch Digital Volume */44#define LDAC2		0x10	/* DAC2 Lch Digital Volume */45#define RDAC2		0x11	/* DAC2 Rch Digital Volume */46#define DAC_IS		0x12	/* DAC Input Select Setting */47#define DAC_DEMP	0x13	/* DAC De-Emphasis Setting */48#define DAC_MF		0x14	/* DAC Mute & Filter Setting */49 50/*51 * Bit fields52 */53 54/* Power Management */55#define PMAD2		BIT(5)56#define PMAD1		BIT(4)57#define PMDA2		BIT(2)58#define PMDA1		BIT(1)59#define RSTN		BIT(0)60 61/* Audio_I/F Format */62#define DCF_STEREO_I2S	(0x0 << 4)63#define DCF_STEREO_MSB	(0x5 << 4)64#define DCF_PCM_SF	(0x6 << 4)65#define DCF_PCM_LF	(0x7 << 4)66#define DSL_32		(0x3 << 2)67#define DCF_MASK	(0x7 << 4)68#define DSL_MASK	(0x3 << 2)69#define BCKP		BIT(1)70 71/* Audio_I/F Format (Extended) */72#define DIDL_24		(0x0 << 2)73#define DIDL_20		(0x1 << 2)74#define DIDL_16		(0x2 << 2)75#define DIDL_32		(0x3 << 2)76#define DODL_24		(0x0 << 0)77#define DODL_20		(0x1 << 0)78#define DODL_16		(0x2 << 0)79#define DIDL_MASK	(0x3 << 2)80#define DODL_MASK	(0x3 << 0)81#define SLOT            BIT(4)82 83/* System Clock Setting */84#define FS_MASK		0x785 86/* MIC AMP Gain */87#define MGNL_SHIFT	488#define MGNR_SHIFT	089#define MGN_MAX		0xB90 91/* ADC Digital Volume */92#define VOLAD_SHIFT	093#define VOLAD_MAX	0xFF94 95/* ADC Digital Filter Setting */96#define AD1SL_SHIFT	097#define AD2SL_SHIFT	498 99/* Analog Input Select */100#define AD1LSEL_SHIFT	6101#define AD1RSEL_SHIFT	4102#define AD2LSEL_SHIFT	2103#define AD2RSEL_SHIFT	0104 105/* ADC Mute & HPF Control */106#define ATSPAD_SHIFT	7107#define AD1MUTE_SHIFT	5108#define AD2MUTE_SHIFT	6109#define AD1MUTE_MAX	1110#define AD2MUTE_MAX	1111#define AD1MUTE_EN	BIT(5)112#define AD2MUTE_EN	BIT(6)113#define AD1HPFN_SHIFT	1114#define AD1HPFN_MAX	1115#define AD2HPFN_SHIFT	2116#define AD2HPFN_MAX	1117 118/* DAC Digital Volume */119#define VOLDA_SHIFT	0120#define VOLDA_MAX	0xFF121 122/* DAC Input Select Setting */123#define DAC1SEL_SHIFT	0124#define DAC2SEL_SHIFT	2125 126/* DAC De-Emphasis Setting */127#define DEM1_32000	(0x3 << 0)128#define DEM1_44100	(0x0 << 0)129#define DEM1_48000	(0x2 << 0)130#define DEM1_OFF	(0x1 << 0)131#define DEM2_32000	(0x3 << 2)132#define DEM2_44100	(0x0 << 2)133#define DEM2_48000	(0x2 << 2)134#define DEM2_OFF	(0x1 << 2)135#define DEM1_MASK	(0x3 << 0)136#define DEM2_MASK	(0x3 << 2)137#define DEM1_SHIFT	0138#define DEM2_SHIFT	2139 140/* DAC Mute & Filter Setting */141#define DA1MUTE_SHIFT	4142#define DA1MUTE_MAX	1143#define DA2MUTE_SHIFT	5144#define DA2MUTE_MAX	1145#define DA1MUTE_EN	BIT(4)146#define DA2MUTE_EN	BIT(5)147#define ATSPDA_SHIFT	7148#define DA1SL_SHIFT	0149#define DA2SL_SHIFT	2150 151/* Codec private data */152struct ak4619_priv {153	struct regmap *regmap;154	struct snd_pcm_hw_constraint_list constraint;155	int deemph_en;156	unsigned int playback_rate;157	unsigned int sysclk;158};159 160/*161 * DAC Volume162 *163 * max : 0x00 : +12.0 dB164 *	( 0.5 dB step )165 * min : 0xFE : -115.0 dB166 * mute: 0xFF167 */168static const DECLARE_TLV_DB_SCALE(dac_tlv, -11550, 50, 1);169 170/*171 * MIC Volume172 *173 * max : 0x0B : +27.0 dB174 *	( 3 dB step )175 * min: 0x00 : -6.0 dB176 */177static const DECLARE_TLV_DB_SCALE(mic_tlv, -600, 300, 0);178 179/*180 * ADC Volume181 *182 * max : 0x00 : +24.0 dB183 *	( 0.5 dB step )184 * min : 0xFE : -103.0 dB185 * mute: 0xFF186 */187static const DECLARE_TLV_DB_SCALE(adc_tlv, -10350, 50, 1);188 189/* ADC & DAC Volume Level Transition Time select */190static const char * const ak4619_vol_trans_txt[] = {191	"4/fs", "16/fs"192};193 194static SOC_ENUM_SINGLE_DECL(ak4619_adc_vol_trans, ADC_MHPF, ATSPAD_SHIFT, ak4619_vol_trans_txt);195static SOC_ENUM_SINGLE_DECL(ak4619_dac_vol_trans, DAC_MF,   ATSPDA_SHIFT, ak4619_vol_trans_txt);196 197/* ADC Digital Filter select */198static const char * const ak4619_adc_digi_fil_txt[] = {199	"Sharp Roll-Off Filter",200	"Slow Roll-Off Filter",201	"Short Delay Sharp Roll-Off Filter",202	"Short Delay Slow Roll-Off Filter",203	"Voice Filter"204};205 206static SOC_ENUM_SINGLE_DECL(ak4619_adc_1_digi_fil, ADC_DF, AD1SL_SHIFT, ak4619_adc_digi_fil_txt);207static SOC_ENUM_SINGLE_DECL(ak4619_adc_2_digi_fil, ADC_DF, AD2SL_SHIFT, ak4619_adc_digi_fil_txt);208 209/* DAC De-Emphasis Filter select */210static const char * const ak4619_dac_de_emp_txt[] = {211	"44.1kHz", "OFF", "48kHz", "32kHz"212};213 214static SOC_ENUM_SINGLE_DECL(ak4619_dac_1_de_emp, DAC_DEMP, DEM1_SHIFT, ak4619_dac_de_emp_txt);215static SOC_ENUM_SINGLE_DECL(ak4619_dac_2_de_emp, DAC_DEMP, DEM2_SHIFT, ak4619_dac_de_emp_txt);216 217/* DAC Digital Filter select */218static const char * const ak4619_dac_digi_fil_txt[] = {219	"Sharp Roll-Off Filter",220	"Slow Roll-Off Filter",221	"Short Delay Sharp Roll-Off Filter",222	"Short Delay Slow Roll-Off Filter"223};224 225static SOC_ENUM_SINGLE_DECL(ak4619_dac_1_digi_fil, DAC_MF, DA1SL_SHIFT, ak4619_dac_digi_fil_txt);226static SOC_ENUM_SINGLE_DECL(ak4619_dac_2_digi_fil, DAC_MF, DA2SL_SHIFT, ak4619_dac_digi_fil_txt);227 228/*229 * Control functions230 */231 232static void ak4619_set_deemph(struct snd_soc_component *component)233{234	struct ak4619_priv *ak4619 = snd_soc_component_get_drvdata(component);235	u8 dem = 0;236 237	if (!ak4619->deemph_en)238		return;239 240	switch (ak4619->playback_rate) {241	case 32000:242		dem |= DEM1_32000 | DEM2_32000;243		break;244	case 44100:245		dem |= DEM1_44100 | DEM2_44100;246		break;247	case 48000:248		dem |= DEM1_48000 | DEM2_48000;249		break;250	default:251		dem |= DEM1_OFF | DEM2_OFF;252		break;253	}254	snd_soc_component_update_bits(component, DAC_DEMP, DEM1_MASK | DEM2_MASK, dem);255}256 257static int ak4619_put_deemph(struct snd_kcontrol *kcontrol,258				struct snd_ctl_elem_value *ucontrol)259{260	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);261	struct ak4619_priv *ak4619 = snd_soc_component_get_drvdata(component);262	int deemph_en = ucontrol->value.integer.value[0];263	int ret = 0;264 265	switch (deemph_en) {266	case 0:267	case 1:268		break;269	default:270		return -EINVAL;271	}272 273	if (ak4619->deemph_en != deemph_en)274		ret = 1; /* The value changed */275 276	ak4619->deemph_en = deemph_en;277	ak4619_set_deemph(component);278 279	return ret;280}281 282static int ak4619_get_deemph(struct snd_kcontrol *kcontrol,283				struct snd_ctl_elem_value *ucontrol)284{285	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);286	struct ak4619_priv *ak4619 = snd_soc_component_get_drvdata(component);287 288	ucontrol->value.integer.value[0] = ak4619->deemph_en;289 290	return 0;291};292 293/*294 * KControls295 */296static const struct snd_kcontrol_new ak4619_snd_controls[] = {297 298	/* Volume controls */299	SOC_DOUBLE_R_TLV("DAC 1 Volume", LDAC1, RDAC1, VOLDA_SHIFT, VOLDA_MAX, 1, dac_tlv),300	SOC_DOUBLE_R_TLV("DAC 2 Volume", LDAC2, RDAC2, VOLDA_SHIFT, VOLDA_MAX, 1, dac_tlv),301	SOC_DOUBLE_R_TLV("ADC 1 Volume", LADC1, RADC1, VOLAD_SHIFT, VOLAD_MAX, 1, adc_tlv),302	SOC_DOUBLE_R_TLV("ADC 2 Volume", LADC2, RADC2, VOLAD_SHIFT, VOLAD_MAX, 1, adc_tlv),303 304	SOC_DOUBLE_TLV("Mic 1 Volume", MIC_AMP1, MGNL_SHIFT, MGNR_SHIFT, MGN_MAX, 0, mic_tlv),305	SOC_DOUBLE_TLV("Mic 2 Volume", MIC_AMP2, MGNL_SHIFT, MGNR_SHIFT, MGN_MAX, 0, mic_tlv),306 307	/* Volume Level Transition Time controls */308	SOC_ENUM("ADC Volume Level Transition Time", ak4619_adc_vol_trans),309	SOC_ENUM("DAC Volume Level Transition Time", ak4619_dac_vol_trans),310 311	/* Mute controls */312	SOC_SINGLE("DAC 1 Switch", DAC_MF, DA1MUTE_SHIFT, DA1MUTE_MAX, 1),313	SOC_SINGLE("DAC 2 Switch", DAC_MF, DA2MUTE_SHIFT, DA2MUTE_MAX, 1),314 315	SOC_SINGLE("ADC 1 Switch", ADC_MHPF, AD1MUTE_SHIFT, AD1MUTE_MAX, 1),316	SOC_SINGLE("ADC 2 Switch", ADC_MHPF, AD2MUTE_SHIFT, AD2MUTE_MAX, 1),317 318	/* Filter controls */319	SOC_ENUM("ADC 1 Digital Filter", ak4619_adc_1_digi_fil),320	SOC_ENUM("ADC 2 Digital Filter", ak4619_adc_2_digi_fil),321 322	SOC_SINGLE("ADC 1 HPF", ADC_MHPF, AD1HPFN_SHIFT, AD1HPFN_MAX, 1),323	SOC_SINGLE("ADC 2 HPF", ADC_MHPF, AD2HPFN_SHIFT, AD2HPFN_MAX, 1),324 325	SOC_ENUM("DAC 1 De-Emphasis Filter", ak4619_dac_1_de_emp),326	SOC_ENUM("DAC 2 De-Emphasis Filter", ak4619_dac_2_de_emp),327 328	SOC_ENUM("DAC 1 Digital Filter", ak4619_dac_1_digi_fil),329	SOC_ENUM("DAC 2 Digital Filter", ak4619_dac_2_digi_fil),330 331	SOC_SINGLE_BOOL_EXT("Playback De-Emphasis Switch", 0, ak4619_get_deemph, ak4619_put_deemph),332};333 334/*335 * DAPM336 */337 338/* Analog input mode */339static const char * const ak4619_analog_in_txt[] = {340	"Differential", "Single-Ended1", "Single-Ended2", "Pseudo Differential"341};342 343static SOC_ENUM_SINGLE_DECL(ak4619_ad_1_left_in,  ADC_AI, AD1LSEL_SHIFT, ak4619_analog_in_txt);344static SOC_ENUM_SINGLE_DECL(ak4619_ad_1_right_in, ADC_AI, AD1RSEL_SHIFT, ak4619_analog_in_txt);345static SOC_ENUM_SINGLE_DECL(ak4619_ad_2_left_in,  ADC_AI, AD2LSEL_SHIFT, ak4619_analog_in_txt);346static SOC_ENUM_SINGLE_DECL(ak4619_ad_2_right_in, ADC_AI, AD2RSEL_SHIFT, ak4619_analog_in_txt);347 348static const struct snd_kcontrol_new ak4619_ad_1_left_in_mux =349	SOC_DAPM_ENUM("Analog Input 1 Left MUX",  ak4619_ad_1_left_in);350static const struct snd_kcontrol_new ak4619_ad_1_right_in_mux =351	SOC_DAPM_ENUM("Analog Input 1 Right MUX", ak4619_ad_1_right_in);352static const struct snd_kcontrol_new ak4619_ad_2_left_in_mux =353	SOC_DAPM_ENUM("Analog Input 2 Left MUX",  ak4619_ad_2_left_in);354static const struct snd_kcontrol_new ak4619_ad_2_right_in_mux =355	SOC_DAPM_ENUM("Analog Input 2 Right MUX", ak4619_ad_2_right_in);356 357/* DAC source mux */358static const char * const ak4619_dac_in_txt[] = {359	"SDIN1", "SDIN2", "SDOUT1", "SDOUT2"360};361 362static SOC_ENUM_SINGLE_DECL(ak4619_dac_1_in, DAC_IS, DAC1SEL_SHIFT, ak4619_dac_in_txt);363static SOC_ENUM_SINGLE_DECL(ak4619_dac_2_in, DAC_IS, DAC2SEL_SHIFT, ak4619_dac_in_txt);364 365static const struct snd_kcontrol_new ak4619_dac_1_in_mux =366	SOC_DAPM_ENUM("DAC 1 Source MUX", ak4619_dac_1_in);367static const struct snd_kcontrol_new ak4619_dac_2_in_mux =368	SOC_DAPM_ENUM("DAC 2 Source MUX", ak4619_dac_2_in);369 370static const struct snd_soc_dapm_widget ak4619_dapm_widgets[] = {371 372	/* DACs */373	SND_SOC_DAPM_DAC("DAC1", NULL, PWR_MGMT, 1, 0),374	SND_SOC_DAPM_DAC("DAC2", NULL, PWR_MGMT, 2, 0),375 376	/* ADCs */377	SND_SOC_DAPM_ADC("ADC1", NULL, PWR_MGMT, 4, 0),378	SND_SOC_DAPM_ADC("ADC2", NULL, PWR_MGMT, 5, 0),379 380	/* Outputs */381	SND_SOC_DAPM_OUTPUT("AOUT1L"),382	SND_SOC_DAPM_OUTPUT("AOUT2L"),383 384	SND_SOC_DAPM_OUTPUT("AOUT1R"),385	SND_SOC_DAPM_OUTPUT("AOUT2R"),386 387	/* Inputs */388	SND_SOC_DAPM_INPUT("AIN1L"),389	SND_SOC_DAPM_INPUT("AIN2L"),390	SND_SOC_DAPM_INPUT("AIN4L"),391	SND_SOC_DAPM_INPUT("AIN5L"),392 393	SND_SOC_DAPM_INPUT("AIN1R"),394	SND_SOC_DAPM_INPUT("AIN2R"),395	SND_SOC_DAPM_INPUT("AIN4R"),396	SND_SOC_DAPM_INPUT("AIN5R"),397 398	SND_SOC_DAPM_INPUT("MIC1L"),399	SND_SOC_DAPM_INPUT("MIC1R"),400	SND_SOC_DAPM_INPUT("MIC2L"),401	SND_SOC_DAPM_INPUT("MIC2R"),402 403	/* DAI */404	SND_SOC_DAPM_AIF_IN("SDIN1",  "Playback", 0, SND_SOC_NOPM, 0, 0),405	SND_SOC_DAPM_AIF_IN("SDIN2",  "Playback", 0, SND_SOC_NOPM, 0, 0),406	SND_SOC_DAPM_AIF_OUT("SDOUT1", "Capture", 0, SND_SOC_NOPM, 0, 0),407	SND_SOC_DAPM_AIF_OUT("SDOUT2", "Capture", 0, SND_SOC_NOPM, 0, 0),408 409	/* MUXs for Mic PGA source selection */410	SND_SOC_DAPM_MUX("Analog Input 1 Left MUX",  SND_SOC_NOPM, 0, 0, &ak4619_ad_1_left_in_mux),411	SND_SOC_DAPM_MUX("Analog Input 1 Right MUX", SND_SOC_NOPM, 0, 0, &ak4619_ad_1_right_in_mux),412	SND_SOC_DAPM_MUX("Analog Input 2 Left MUX",  SND_SOC_NOPM, 0, 0, &ak4619_ad_2_left_in_mux),413	SND_SOC_DAPM_MUX("Analog Input 2 Right MUX", SND_SOC_NOPM, 0, 0, &ak4619_ad_2_right_in_mux),414 415	/* MUXs for DAC source selection */416	SND_SOC_DAPM_MUX("DAC 1 Source MUX", SND_SOC_NOPM, 0, 0, &ak4619_dac_1_in_mux),417	SND_SOC_DAPM_MUX("DAC 2 Source MUX", SND_SOC_NOPM, 0, 0, &ak4619_dac_2_in_mux),418};419 420static const struct snd_soc_dapm_route ak4619_intercon[] = {421	/* Dest       Connecting Widget    Source */422 423	/* Output path */424	{"AOUT1L", NULL, "DAC1"},425	{"AOUT2L", NULL, "DAC2"},426 427	{"AOUT1R", NULL, "DAC1"},428	{"AOUT2R", NULL, "DAC2"},429 430	{"DAC1", NULL, "DAC 1 Source MUX"},431	{"DAC2", NULL, "DAC 2 Source MUX"},432 433	{"DAC 1 Source MUX", "SDIN1",  "SDIN1"},434	{"DAC 1 Source MUX", "SDIN2",  "SDIN2"},435	{"DAC 1 Source MUX", "SDOUT1", "SDOUT1"},436	{"DAC 1 Source MUX", "SDOUT2", "SDOUT2"},437 438	{"DAC 2 Source MUX", "SDIN1",  "SDIN1"},439	{"DAC 2 Source MUX", "SDIN2",  "SDIN2"},440	{"DAC 2 Source MUX", "SDOUT1", "SDOUT1"},441	{"DAC 2 Source MUX", "SDOUT2", "SDOUT2"},442 443	/* Input path */444	{"SDOUT1", NULL, "ADC1"},445	{"SDOUT2", NULL, "ADC2"},446 447	{"ADC1", NULL, "Analog Input 1 Left MUX"},448	{"ADC1", NULL, "Analog Input 1 Right MUX"},449 450	{"ADC2", NULL, "Analog Input 2 Left MUX"},451	{"ADC2", NULL, "Analog Input 2 Right MUX"},452 453	{"Analog Input 1 Left MUX", "Differential",		"MIC1L"},454	{"Analog Input 1 Left MUX", "Single-Ended1",		"MIC1L"},455	{"Analog Input 1 Left MUX", "Single-Ended2",		"MIC1L"},456	{"Analog Input 1 Left MUX", "Pseudo Differential",	"MIC1L"},457 458	{"Analog Input 1 Right MUX", "Differential",		"MIC1R"},459	{"Analog Input 1 Right MUX", "Single-Ended1",		"MIC1R"},460	{"Analog Input 1 Right MUX", "Single-Ended2",		"MIC1R"},461	{"Analog Input 1 Right MUX", "Pseudo Differential",	"MIC1R"},462 463	{"Analog Input 2 Left MUX", "Differential",		"MIC2L"},464	{"Analog Input 2 Left MUX", "Single-Ended1",		"MIC2L"},465	{"Analog Input 2 Left MUX", "Single-Ended2",		"MIC2L"},466	{"Analog Input 2 Left MUX", "Pseudo Differential",	"MIC2L"},467 468	{"Analog Input 2 Right MUX", "Differential",		"MIC2R"},469	{"Analog Input 2 Right MUX", "Single-Ended1",		"MIC2R"},470	{"Analog Input 2 Right MUX", "Single-Ended2",		"MIC2R"},471	{"Analog Input 2 Right MUX", "Pseudo Differential",	"MIC2R"},472 473	{"MIC1L", NULL, "AIN1L"},474	{"MIC1L", NULL, "AIN2L"},475 476	{"MIC1R", NULL, "AIN1R"},477	{"MIC1R", NULL, "AIN2R"},478 479	{"MIC2L", NULL, "AIN4L"},480	{"MIC2L", NULL, "AIN5L"},481 482	{"MIC2R", NULL, "AIN4R"},483	{"MIC2R", NULL, "AIN5R"},484};485 486static const struct reg_default ak4619_reg_defaults[] = {487	{ PWR_MGMT,	0x00 },488	{ AU_IFF1,	0x0C },489	{ AU_IFF2,	0x0C },490	{ SYS_CLK,	0x00 },491	{ MIC_AMP1,	0x22 },492	{ MIC_AMP2,	0x22 },493	{ LADC1,	0x30 },494	{ RADC1,	0x30 },495	{ LADC2,	0x30 },496	{ RADC2,	0x30 },497	{ ADC_DF,	0x00 },498	{ ADC_AI,	0x00 },499	{ ADC_MHPF,	0x00 },500	{ LDAC1,	0x18 },501	{ RDAC1,	0x18 },502	{ LDAC2,	0x18 },503	{ RDAC2,	0x18 },504	{ DAC_IS,	0x04 },505	{ DAC_DEMP,	0x05 },506	{ DAC_MF,	0x0A },507};508 509static int ak4619_set_bias_level(struct snd_soc_component *component,510				 enum snd_soc_bias_level level)511{512	u8 pwr_ctrl = 0;513 514	switch (level) {515	case SND_SOC_BIAS_ON:516		pwr_ctrl |= RSTN;517		fallthrough;518	case SND_SOC_BIAS_PREPARE:519		pwr_ctrl |= PMAD1 | PMAD2 | PMDA1 | PMDA2;520		fallthrough;521	case SND_SOC_BIAS_STANDBY:522	case SND_SOC_BIAS_OFF:523	default:524		break;525	}526 527	snd_soc_component_write(component, PWR_MGMT, pwr_ctrl);528 529	return 0;530}531 532static int ak4619_dai_hw_params(struct snd_pcm_substream *substream,533				struct snd_pcm_hw_params *params,534				struct snd_soc_dai *dai)535{536	struct snd_soc_component *component = dai->component;537	struct ak4619_priv *ak4619 = snd_soc_component_get_drvdata(component);538	unsigned int width;539	unsigned int rate;540	unsigned int fs;541	bool is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;542	u8 dai_ctrl = 0;543	u8 clk_mode = 0;544 545	width = params_width(params);546	switch (width) {547	case 16:548		dai_ctrl |= is_play ? DIDL_16 : DODL_16;549		break;550	case 20:551		dai_ctrl |= is_play ? DIDL_20 : DODL_20;552		break;553	case 24:554		dai_ctrl |= is_play ? DIDL_24 : DODL_24;555		break;556	case 32:557		if (is_play)558			dai_ctrl |= DIDL_32;559		else560			return -EINVAL;561		break;562	default:563		return -EINVAL;564	}565 566	rate = params_rate(params);567	if (rate)568		fs = ak4619->sysclk / rate;569	else570		return -EINVAL;571 572	switch (rate) {573	case  8000:574	case 11025:575	case 12000:576	case 16000:577	case 22050:578	case 24000:579	case 32000:580	case 44100:581	case 48000:582		switch (fs) {583		case 256:584			clk_mode |= (0x0 << 0);585			break;586		case 384:587			clk_mode |= (0x2 << 0);588			break;589		case 512:590			clk_mode |= (0x3 << 0);591			break;592		default:593			return -EINVAL;594		}595		break;596	case 64000:597	case 88200:598	case 96000:599		if (fs == 256)600			clk_mode |= (0x1 << 0);601		else602			return -EINVAL;603		break;604	case 176400:605	case 192000:606		if (fs == 128)607			clk_mode |= (0x4 << 0);608		else609			return -EINVAL;610		break;611	default:612		return -EINVAL;613	}614 615	snd_soc_component_update_bits(component, SYS_CLK, FS_MASK, clk_mode);616	snd_soc_component_update_bits(component, AU_IFF2,617				      is_play ? DIDL_MASK : DODL_MASK, dai_ctrl);618 619	if (is_play) {620		ak4619->playback_rate = rate;621		ak4619_set_deemph(component);622	}623 624	return 0;625}626 627static int ak4619_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)628{629	struct snd_soc_component *component = dai->component;630	u8 dai_fmt1 = 0;631	u8 dai_fmt2 = 0;632 633	/* Set clock normal/inverted */634	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {635	case SND_SOC_DAIFMT_NB_NF:636		break;637	case SND_SOC_DAIFMT_IB_NF:638		dai_fmt1 |= BCKP;639		break;640	case SND_SOC_DAIFMT_NB_IF:641	case SND_SOC_DAIFMT_IB_IF:642	default:643		return -EINVAL;644	}645 646	/* Only Stereo modes are supported */647	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {648	case SND_SOC_DAIFMT_I2S:649		dai_fmt1 |= DCF_STEREO_I2S;650		break;651	case SND_SOC_DAIFMT_LEFT_J:652		dai_fmt1 |= DCF_STEREO_MSB;653		break;654	case SND_SOC_DAIFMT_DSP_A: /* L data MSB after FRM LRC */655		dai_fmt1 |= DCF_PCM_SF;656		dai_fmt2 |= SLOT;657		break;658	case SND_SOC_DAIFMT_DSP_B: /* L data MSB during FRM LRC */659		dai_fmt1 |= DCF_PCM_LF;660		dai_fmt2 |= SLOT;661		break;662	default:663		return -EINVAL;664	}665 666	/* Only slave mode is support */667	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {668	case SND_SOC_DAIFMT_CBC_CFC:669		break;670	default:671		return -EINVAL;672	}673 674	/* By default only 64 BICK per LRCLK is supported */675	dai_fmt1 |= DSL_32;676 677	snd_soc_component_update_bits(component, AU_IFF1, DCF_MASK |678					DSL_MASK | BCKP, dai_fmt1);679	snd_soc_component_update_bits(component, AU_IFF2, SLOT, dai_fmt2);680 681	return 0;682}683 684static int ak4619_dai_set_sysclk(struct snd_soc_dai *codec_dai,685				 int clk_id, unsigned int freq, int dir)686{687	struct snd_soc_component *component = codec_dai->component;688	struct ak4619_priv *ak4619 = snd_soc_component_get_drvdata(component);689 690	ak4619->sysclk = freq;691 692	return 0;693}694 695static int ak4619_dai_mute(struct snd_soc_dai *dai, int mute, int direction)696{697	struct snd_soc_component *component = dai->component;698 699	snd_soc_component_update_bits(component, DAC_MF, DA1MUTE_EN, mute ? DA1MUTE_EN : 0);700	snd_soc_component_update_bits(component, DAC_MF, DA2MUTE_EN, mute ? DA2MUTE_EN : 0);701 702	return 0;703}704 705static void ak4619_hw_constraints(struct ak4619_priv *ak4619,706				  struct snd_pcm_runtime *runtime)707{708	struct snd_pcm_hw_constraint_list *constraint = &ak4619->constraint;709	int ak4619_rate_mask = 0;710	unsigned int fs;711	int i;712	static const unsigned int ak4619_sr[] = {713		  8000,714		 11025,715		 12000,716		 16000,717		 22050,718		 24000,719		 32000,720		 44100,721		 48000,722		 64000,723		 88200,724		 96000,725		176400,726		192000,727	};728 729	/*730	 *	[8kHz - 48kHz]		: 256fs, 384fs or 512fs731	 *	[64kHz - 96kHz]		: 256fs732	 *	[176.4kHz, 192kHz]	: 128fs733	 */734 735	for (i = 0; i < ARRAY_SIZE(ak4619_sr); i++) {736		fs = ak4619->sysclk / ak4619_sr[i];737 738		switch (fs) {739		case 512:740		case 384:741		case 256:742			ak4619_rate_mask |= (1 << i);743			break;744		case 128:745			switch (i) {746			case (ARRAY_SIZE(ak4619_sr) - 1):747			case (ARRAY_SIZE(ak4619_sr) - 2):748				ak4619_rate_mask |= (1 << i);749				break;750			default:751				break;752			}753			break;754		default:755			break;756		}757	}758 759	constraint->list	= ak4619_sr;760	constraint->mask	= ak4619_rate_mask;761	constraint->count	= ARRAY_SIZE(ak4619_sr);762 763	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, constraint);764};765 766#define PLAYBACK_MODE	0767#define CAPTURE_MODE	1768 769static int ak4619_dai_startup(struct snd_pcm_substream *substream,770			      struct snd_soc_dai *dai)771{772	struct snd_soc_component *component = dai->component;773	struct ak4619_priv *ak4619 = snd_soc_component_get_drvdata(component);774 775	ak4619_hw_constraints(ak4619, substream->runtime);776 777	return 0;778}779 780static u64 ak4619_dai_formats[] = {781	/*782	 * Select below from Sound Card, not here783	 *	SND_SOC_DAIFMT_CBC_CFC784	 *	SND_SOC_DAIFMT_CBP_CFP785	 */786 787	/* First Priority */788	SND_SOC_POSSIBLE_DAIFMT_I2S	|789	SND_SOC_POSSIBLE_DAIFMT_LEFT_J,790 791	/* Second Priority */792	SND_SOC_POSSIBLE_DAIFMT_DSP_A	|793	SND_SOC_POSSIBLE_DAIFMT_DSP_B,794};795 796static const struct snd_soc_dai_ops ak4619_dai_ops = {797	.startup			= ak4619_dai_startup,798	.set_sysclk			= ak4619_dai_set_sysclk,799	.set_fmt			= ak4619_dai_set_fmt,800	.hw_params			= ak4619_dai_hw_params,801	.mute_stream			= ak4619_dai_mute,802	.auto_selectable_formats	= ak4619_dai_formats,803	.num_auto_selectable_formats	= ARRAY_SIZE(ak4619_dai_formats),804};805 806static const struct snd_soc_component_driver soc_component_dev_ak4619 = {807	.set_bias_level		= ak4619_set_bias_level,808	.controls		= ak4619_snd_controls,809	.num_controls		= ARRAY_SIZE(ak4619_snd_controls),810	.dapm_widgets		= ak4619_dapm_widgets,811	.num_dapm_widgets	= ARRAY_SIZE(ak4619_dapm_widgets),812	.dapm_routes		= ak4619_intercon,813	.num_dapm_routes	= ARRAY_SIZE(ak4619_intercon),814	.idle_bias_on		= 1,815	.endianness		= 1,816};817 818static const struct regmap_config ak4619_regmap_cfg = {819	.reg_bits		= 8,820	.val_bits		= 8,821	.max_register		= 0x14,822	.reg_defaults		= ak4619_reg_defaults,823	.num_reg_defaults	= ARRAY_SIZE(ak4619_reg_defaults),824	.cache_type		= REGCACHE_MAPLE,825};826 827static const struct of_device_id ak4619_of_match[] = {828	{ .compatible = "asahi-kasei,ak4619",	.data = &ak4619_regmap_cfg },829	{},830};831MODULE_DEVICE_TABLE(of, ak4619_of_match);832 833static const struct i2c_device_id ak4619_i2c_id[] = {834	{ "ak4619", (kernel_ulong_t)&ak4619_regmap_cfg },835	{ }836};837MODULE_DEVICE_TABLE(i2c, ak4619_i2c_id);838 839#define AK4619_RATES	SNDRV_PCM_RATE_8000_192000840 841#define AK4619_DAC_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE |\842				 SNDRV_PCM_FMTBIT_S20_LE |\843				 SNDRV_PCM_FMTBIT_S24_LE |\844				 SNDRV_PCM_FMTBIT_S32_LE)845 846#define AK4619_ADC_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE |\847				 SNDRV_PCM_FMTBIT_S20_LE |\848				 SNDRV_PCM_FMTBIT_S24_LE)849 850static struct snd_soc_dai_driver ak4619_dai = {851	.name = "ak4619-hifi",852	.playback = {853		.stream_name	= "Playback",854		.channels_min	= 1,855		.channels_max	= 2,856		.rates		= AK4619_RATES,857		.formats	= AK4619_DAC_FORMATS,858	},859	.capture = {860		.stream_name	= "Capture",861		.channels_min	= 1,862		.channels_max	= 2,863		.rates		= AK4619_RATES,864		.formats	= AK4619_ADC_FORMATS,865	},866	.ops			= &ak4619_dai_ops,867	.symmetric_rate		= 1,868};869 870static int ak4619_i2c_probe(struct i2c_client *i2c)871{872	struct device *dev = &i2c->dev;873	struct ak4619_priv *ak4619;874	int ret;875 876	ak4619 = devm_kzalloc(dev, sizeof(*ak4619), GFP_KERNEL);877	if (!ak4619)878		return -ENOMEM;879 880	i2c_set_clientdata(i2c, ak4619);881 882	ak4619->regmap = devm_regmap_init_i2c(i2c, &ak4619_regmap_cfg);883	if (IS_ERR(ak4619->regmap)) {884		ret = PTR_ERR(ak4619->regmap);885		dev_err(dev, "regmap_init() failed: %d\n", ret);886		return ret;887	}888 889	ret = devm_snd_soc_register_component(dev, &soc_component_dev_ak4619,890				      &ak4619_dai, 1);891	if (ret < 0) {892		dev_err(dev, "Failed to register ak4619 component: %d\n",893			ret);894		return ret;895	}896 897	return 0;898}899 900static struct i2c_driver ak4619_i2c_driver = {901	.driver = {902		.name = "ak4619-codec",903		.of_match_table = ak4619_of_match,904	},905	.probe		= ak4619_i2c_probe,906	.id_table	= ak4619_i2c_id,907};908module_i2c_driver(ak4619_i2c_driver);909 910MODULE_DESCRIPTION("SoC AK4619 driver");911MODULE_AUTHOR("Khanh Le <khanh.le.xr@renesas.com>");912MODULE_LICENSE("GPL v2");913