Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.14.15.
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * ak4619.c -- Asahi Kasei ALSA SoC Audio driver
  4 *
  5 * Copyright (C) 2023 Renesas Electronics Corporation
  6 * Khanh Le <khanh.le.xr@renesas.com>
  7 *
  8 * Based on ak4613.c by Kuninori Morimoto
  9 * Based on da7213.c by Adam Thomson
 10 * Based on ak4641.c by Harald Welte
 11 */
 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 * Registers
 27 */
 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 fields
 52 */
 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		0x7
 85
 86/* MIC AMP Gain */
 87#define MGNL_SHIFT	4
 88#define MGNR_SHIFT	0
 89#define MGN_MAX		0xB
 90
 91/* ADC Digital Volume */
 92#define VOLAD_SHIFT	0
 93#define VOLAD_MAX	0xFF
 94
 95/* ADC Digital Filter Setting */
 96#define AD1SL_SHIFT	0
 97#define AD2SL_SHIFT	4
 98
 99/* Analog Input Select */
100#define AD1LSEL_SHIFT	6
101#define AD1RSEL_SHIFT	4
102#define AD2LSEL_SHIFT	2
103#define AD2RSEL_SHIFT	0
104
105/* ADC Mute & HPF Control */
106#define ATSPAD_SHIFT	7
107#define AD1MUTE_SHIFT	5
108#define AD2MUTE_SHIFT	6
109#define AD1MUTE_MAX	1
110#define AD2MUTE_MAX	1
111#define AD1MUTE_EN	BIT(5)
112#define AD2MUTE_EN	BIT(6)
113#define AD1HPFN_SHIFT	1
114#define AD1HPFN_MAX	1
115#define AD2HPFN_SHIFT	2
116#define AD2HPFN_MAX	1
117
118/* DAC Digital Volume */
119#define VOLDA_SHIFT	0
120#define VOLDA_MAX	0xFF
121
122/* DAC Input Select Setting */
123#define DAC1SEL_SHIFT	0
124#define DAC2SEL_SHIFT	2
125
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	0
138#define DEM2_SHIFT	2
139
140/* DAC Mute & Filter Setting */
141#define DA1MUTE_SHIFT	4
142#define DA1MUTE_MAX	1
143#define DA2MUTE_SHIFT	5
144#define DA2MUTE_MAX	1
145#define DA1MUTE_EN	BIT(4)
146#define DA2MUTE_EN	BIT(5)
147#define ATSPDA_SHIFT	7
148#define DA1SL_SHIFT	0
149#define DA2SL_SHIFT	2
150
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 Volume
162 *
163 * max : 0x00 : +12.0 dB
164 *	( 0.5 dB step )
165 * min : 0xFE : -115.0 dB
166 * mute: 0xFF
167 */
168static const DECLARE_TLV_DB_SCALE(dac_tlv, -11550, 50, 1);
169
170/*
171 * MIC Volume
172 *
173 * max : 0x0B : +27.0 dB
174 *	( 3 dB step )
175 * min: 0x00 : -6.0 dB
176 */
177static const DECLARE_TLV_DB_SCALE(mic_tlv, -600, 300, 0);
178
179/*
180 * ADC Volume
181 *
182 * max : 0x00 : +24.0 dB
183 *	( 0.5 dB step )
184 * min : 0xFE : -103.0 dB
185 * mute: 0xFF
186 */
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 functions
230 */
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 * KControls
295 */
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 * DAPM
336 */
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		else
560			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	else
570		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		else
602			return -EINVAL;
603		break;
604	case 176400:
605	case 192000:
606		if (fs == 128)
607			clk_mode |= (0x4 << 0);
608		else
609			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 512fs
731	 *	[64kHz - 96kHz]		: 256fs
732	 *	[176.4kHz, 192kHz]	: 128fs
733	 */
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	0
767#define CAPTURE_MODE	1
768
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 here
783	 *	SND_SOC_DAIFMT_CBC_CFC
784	 *	SND_SOC_DAIFMT_CBP_CFP
785	 */
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_192000
840
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");