xref: /OK3568_Linux_fs/kernel/sound/soc/codecs/pcm512x.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Driver for the PCM512x CODECs
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Author:	Mark Brown <broonie@kernel.org>
6*4882a593Smuzhiyun  *		Copyright 2014 Linaro Ltd
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <linux/init.h>
11*4882a593Smuzhiyun #include <linux/module.h>
12*4882a593Smuzhiyun #include <linux/clk.h>
13*4882a593Smuzhiyun #include <linux/kernel.h>
14*4882a593Smuzhiyun #include <linux/pm_runtime.h>
15*4882a593Smuzhiyun #include <linux/regmap.h>
16*4882a593Smuzhiyun #include <linux/regulator/consumer.h>
17*4882a593Smuzhiyun #include <linux/gcd.h>
18*4882a593Smuzhiyun #include <sound/soc.h>
19*4882a593Smuzhiyun #include <sound/soc-dapm.h>
20*4882a593Smuzhiyun #include <sound/pcm_params.h>
21*4882a593Smuzhiyun #include <sound/tlv.h>
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #include "pcm512x.h"
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #define PCM512x_NUM_SUPPLIES 3
26*4882a593Smuzhiyun static const char * const pcm512x_supply_names[PCM512x_NUM_SUPPLIES] = {
27*4882a593Smuzhiyun 	"AVDD",
28*4882a593Smuzhiyun 	"DVDD",
29*4882a593Smuzhiyun 	"CPVDD",
30*4882a593Smuzhiyun };
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun struct pcm512x_priv {
33*4882a593Smuzhiyun 	struct regmap *regmap;
34*4882a593Smuzhiyun 	struct clk *sclk;
35*4882a593Smuzhiyun 	struct regulator_bulk_data supplies[PCM512x_NUM_SUPPLIES];
36*4882a593Smuzhiyun 	struct notifier_block supply_nb[PCM512x_NUM_SUPPLIES];
37*4882a593Smuzhiyun 	int fmt;
38*4882a593Smuzhiyun 	int pll_in;
39*4882a593Smuzhiyun 	int pll_out;
40*4882a593Smuzhiyun 	int pll_r;
41*4882a593Smuzhiyun 	int pll_j;
42*4882a593Smuzhiyun 	int pll_d;
43*4882a593Smuzhiyun 	int pll_p;
44*4882a593Smuzhiyun 	unsigned long real_pll;
45*4882a593Smuzhiyun 	unsigned long overclock_pll;
46*4882a593Smuzhiyun 	unsigned long overclock_dac;
47*4882a593Smuzhiyun 	unsigned long overclock_dsp;
48*4882a593Smuzhiyun 	int mute;
49*4882a593Smuzhiyun 	struct mutex mutex;
50*4882a593Smuzhiyun 	unsigned int bclk_ratio;
51*4882a593Smuzhiyun };
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun /*
54*4882a593Smuzhiyun  * We can't use the same notifier block for more than one supply and
55*4882a593Smuzhiyun  * there's no way I can see to get from a callback to the caller
56*4882a593Smuzhiyun  * except container_of().
57*4882a593Smuzhiyun  */
58*4882a593Smuzhiyun #define PCM512x_REGULATOR_EVENT(n) \
59*4882a593Smuzhiyun static int pcm512x_regulator_event_##n(struct notifier_block *nb, \
60*4882a593Smuzhiyun 				      unsigned long event, void *data)    \
61*4882a593Smuzhiyun { \
62*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = container_of(nb, struct pcm512x_priv, \
63*4882a593Smuzhiyun 						    supply_nb[n]); \
64*4882a593Smuzhiyun 	if (event & REGULATOR_EVENT_DISABLE) { \
65*4882a593Smuzhiyun 		regcache_mark_dirty(pcm512x->regmap);	\
66*4882a593Smuzhiyun 		regcache_cache_only(pcm512x->regmap, true);	\
67*4882a593Smuzhiyun 	} \
68*4882a593Smuzhiyun 	return 0; \
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun PCM512x_REGULATOR_EVENT(0)
72*4882a593Smuzhiyun PCM512x_REGULATOR_EVENT(1)
73*4882a593Smuzhiyun PCM512x_REGULATOR_EVENT(2)
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun static const struct reg_default pcm512x_reg_defaults[] = {
76*4882a593Smuzhiyun 	{ PCM512x_RESET,             0x00 },
77*4882a593Smuzhiyun 	{ PCM512x_POWER,             0x00 },
78*4882a593Smuzhiyun 	{ PCM512x_MUTE,              0x00 },
79*4882a593Smuzhiyun 	{ PCM512x_DSP,               0x00 },
80*4882a593Smuzhiyun 	{ PCM512x_PLL_REF,           0x00 },
81*4882a593Smuzhiyun 	{ PCM512x_DAC_REF,           0x00 },
82*4882a593Smuzhiyun 	{ PCM512x_DAC_ROUTING,       0x11 },
83*4882a593Smuzhiyun 	{ PCM512x_DSP_PROGRAM,       0x01 },
84*4882a593Smuzhiyun 	{ PCM512x_CLKDET,            0x00 },
85*4882a593Smuzhiyun 	{ PCM512x_AUTO_MUTE,         0x00 },
86*4882a593Smuzhiyun 	{ PCM512x_ERROR_DETECT,      0x00 },
87*4882a593Smuzhiyun 	{ PCM512x_DIGITAL_VOLUME_1,  0x00 },
88*4882a593Smuzhiyun 	{ PCM512x_DIGITAL_VOLUME_2,  0x30 },
89*4882a593Smuzhiyun 	{ PCM512x_DIGITAL_VOLUME_3,  0x30 },
90*4882a593Smuzhiyun 	{ PCM512x_DIGITAL_MUTE_1,    0x22 },
91*4882a593Smuzhiyun 	{ PCM512x_DIGITAL_MUTE_2,    0x00 },
92*4882a593Smuzhiyun 	{ PCM512x_DIGITAL_MUTE_3,    0x07 },
93*4882a593Smuzhiyun 	{ PCM512x_OUTPUT_AMPLITUDE,  0x00 },
94*4882a593Smuzhiyun 	{ PCM512x_ANALOG_GAIN_CTRL,  0x00 },
95*4882a593Smuzhiyun 	{ PCM512x_UNDERVOLTAGE_PROT, 0x00 },
96*4882a593Smuzhiyun 	{ PCM512x_ANALOG_MUTE_CTRL,  0x00 },
97*4882a593Smuzhiyun 	{ PCM512x_ANALOG_GAIN_BOOST, 0x00 },
98*4882a593Smuzhiyun 	{ PCM512x_VCOM_CTRL_1,       0x00 },
99*4882a593Smuzhiyun 	{ PCM512x_VCOM_CTRL_2,       0x01 },
100*4882a593Smuzhiyun 	{ PCM512x_BCLK_LRCLK_CFG,    0x00 },
101*4882a593Smuzhiyun 	{ PCM512x_MASTER_MODE,       0x7c },
102*4882a593Smuzhiyun 	{ PCM512x_GPIO_DACIN,        0x00 },
103*4882a593Smuzhiyun 	{ PCM512x_GPIO_PLLIN,        0x00 },
104*4882a593Smuzhiyun 	{ PCM512x_SYNCHRONIZE,       0x10 },
105*4882a593Smuzhiyun 	{ PCM512x_PLL_COEFF_0,       0x00 },
106*4882a593Smuzhiyun 	{ PCM512x_PLL_COEFF_1,       0x00 },
107*4882a593Smuzhiyun 	{ PCM512x_PLL_COEFF_2,       0x00 },
108*4882a593Smuzhiyun 	{ PCM512x_PLL_COEFF_3,       0x00 },
109*4882a593Smuzhiyun 	{ PCM512x_PLL_COEFF_4,       0x00 },
110*4882a593Smuzhiyun 	{ PCM512x_DSP_CLKDIV,        0x00 },
111*4882a593Smuzhiyun 	{ PCM512x_DAC_CLKDIV,        0x00 },
112*4882a593Smuzhiyun 	{ PCM512x_NCP_CLKDIV,        0x00 },
113*4882a593Smuzhiyun 	{ PCM512x_OSR_CLKDIV,        0x00 },
114*4882a593Smuzhiyun 	{ PCM512x_MASTER_CLKDIV_1,   0x00 },
115*4882a593Smuzhiyun 	{ PCM512x_MASTER_CLKDIV_2,   0x00 },
116*4882a593Smuzhiyun 	{ PCM512x_FS_SPEED_MODE,     0x00 },
117*4882a593Smuzhiyun 	{ PCM512x_IDAC_1,            0x01 },
118*4882a593Smuzhiyun 	{ PCM512x_IDAC_2,            0x00 },
119*4882a593Smuzhiyun };
120*4882a593Smuzhiyun 
pcm512x_readable(struct device * dev,unsigned int reg)121*4882a593Smuzhiyun static bool pcm512x_readable(struct device *dev, unsigned int reg)
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun 	switch (reg) {
124*4882a593Smuzhiyun 	case PCM512x_RESET:
125*4882a593Smuzhiyun 	case PCM512x_POWER:
126*4882a593Smuzhiyun 	case PCM512x_MUTE:
127*4882a593Smuzhiyun 	case PCM512x_PLL_EN:
128*4882a593Smuzhiyun 	case PCM512x_SPI_MISO_FUNCTION:
129*4882a593Smuzhiyun 	case PCM512x_DSP:
130*4882a593Smuzhiyun 	case PCM512x_GPIO_EN:
131*4882a593Smuzhiyun 	case PCM512x_BCLK_LRCLK_CFG:
132*4882a593Smuzhiyun 	case PCM512x_DSP_GPIO_INPUT:
133*4882a593Smuzhiyun 	case PCM512x_MASTER_MODE:
134*4882a593Smuzhiyun 	case PCM512x_PLL_REF:
135*4882a593Smuzhiyun 	case PCM512x_DAC_REF:
136*4882a593Smuzhiyun 	case PCM512x_GPIO_DACIN:
137*4882a593Smuzhiyun 	case PCM512x_GPIO_PLLIN:
138*4882a593Smuzhiyun 	case PCM512x_SYNCHRONIZE:
139*4882a593Smuzhiyun 	case PCM512x_PLL_COEFF_0:
140*4882a593Smuzhiyun 	case PCM512x_PLL_COEFF_1:
141*4882a593Smuzhiyun 	case PCM512x_PLL_COEFF_2:
142*4882a593Smuzhiyun 	case PCM512x_PLL_COEFF_3:
143*4882a593Smuzhiyun 	case PCM512x_PLL_COEFF_4:
144*4882a593Smuzhiyun 	case PCM512x_DSP_CLKDIV:
145*4882a593Smuzhiyun 	case PCM512x_DAC_CLKDIV:
146*4882a593Smuzhiyun 	case PCM512x_NCP_CLKDIV:
147*4882a593Smuzhiyun 	case PCM512x_OSR_CLKDIV:
148*4882a593Smuzhiyun 	case PCM512x_MASTER_CLKDIV_1:
149*4882a593Smuzhiyun 	case PCM512x_MASTER_CLKDIV_2:
150*4882a593Smuzhiyun 	case PCM512x_FS_SPEED_MODE:
151*4882a593Smuzhiyun 	case PCM512x_IDAC_1:
152*4882a593Smuzhiyun 	case PCM512x_IDAC_2:
153*4882a593Smuzhiyun 	case PCM512x_ERROR_DETECT:
154*4882a593Smuzhiyun 	case PCM512x_I2S_1:
155*4882a593Smuzhiyun 	case PCM512x_I2S_2:
156*4882a593Smuzhiyun 	case PCM512x_DAC_ROUTING:
157*4882a593Smuzhiyun 	case PCM512x_DSP_PROGRAM:
158*4882a593Smuzhiyun 	case PCM512x_CLKDET:
159*4882a593Smuzhiyun 	case PCM512x_AUTO_MUTE:
160*4882a593Smuzhiyun 	case PCM512x_DIGITAL_VOLUME_1:
161*4882a593Smuzhiyun 	case PCM512x_DIGITAL_VOLUME_2:
162*4882a593Smuzhiyun 	case PCM512x_DIGITAL_VOLUME_3:
163*4882a593Smuzhiyun 	case PCM512x_DIGITAL_MUTE_1:
164*4882a593Smuzhiyun 	case PCM512x_DIGITAL_MUTE_2:
165*4882a593Smuzhiyun 	case PCM512x_DIGITAL_MUTE_3:
166*4882a593Smuzhiyun 	case PCM512x_GPIO_OUTPUT_1:
167*4882a593Smuzhiyun 	case PCM512x_GPIO_OUTPUT_2:
168*4882a593Smuzhiyun 	case PCM512x_GPIO_OUTPUT_3:
169*4882a593Smuzhiyun 	case PCM512x_GPIO_OUTPUT_4:
170*4882a593Smuzhiyun 	case PCM512x_GPIO_OUTPUT_5:
171*4882a593Smuzhiyun 	case PCM512x_GPIO_OUTPUT_6:
172*4882a593Smuzhiyun 	case PCM512x_GPIO_CONTROL_1:
173*4882a593Smuzhiyun 	case PCM512x_GPIO_CONTROL_2:
174*4882a593Smuzhiyun 	case PCM512x_OVERFLOW:
175*4882a593Smuzhiyun 	case PCM512x_RATE_DET_1:
176*4882a593Smuzhiyun 	case PCM512x_RATE_DET_2:
177*4882a593Smuzhiyun 	case PCM512x_RATE_DET_3:
178*4882a593Smuzhiyun 	case PCM512x_RATE_DET_4:
179*4882a593Smuzhiyun 	case PCM512x_CLOCK_STATUS:
180*4882a593Smuzhiyun 	case PCM512x_ANALOG_MUTE_DET:
181*4882a593Smuzhiyun 	case PCM512x_GPIN:
182*4882a593Smuzhiyun 	case PCM512x_DIGITAL_MUTE_DET:
183*4882a593Smuzhiyun 	case PCM512x_OUTPUT_AMPLITUDE:
184*4882a593Smuzhiyun 	case PCM512x_ANALOG_GAIN_CTRL:
185*4882a593Smuzhiyun 	case PCM512x_UNDERVOLTAGE_PROT:
186*4882a593Smuzhiyun 	case PCM512x_ANALOG_MUTE_CTRL:
187*4882a593Smuzhiyun 	case PCM512x_ANALOG_GAIN_BOOST:
188*4882a593Smuzhiyun 	case PCM512x_VCOM_CTRL_1:
189*4882a593Smuzhiyun 	case PCM512x_VCOM_CTRL_2:
190*4882a593Smuzhiyun 	case PCM512x_CRAM_CTRL:
191*4882a593Smuzhiyun 	case PCM512x_FLEX_A:
192*4882a593Smuzhiyun 	case PCM512x_FLEX_B:
193*4882a593Smuzhiyun 		return true;
194*4882a593Smuzhiyun 	default:
195*4882a593Smuzhiyun 		/* There are 256 raw register addresses */
196*4882a593Smuzhiyun 		return reg < 0xff;
197*4882a593Smuzhiyun 	}
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun 
pcm512x_volatile(struct device * dev,unsigned int reg)200*4882a593Smuzhiyun static bool pcm512x_volatile(struct device *dev, unsigned int reg)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun 	switch (reg) {
203*4882a593Smuzhiyun 	case PCM512x_PLL_EN:
204*4882a593Smuzhiyun 	case PCM512x_OVERFLOW:
205*4882a593Smuzhiyun 	case PCM512x_RATE_DET_1:
206*4882a593Smuzhiyun 	case PCM512x_RATE_DET_2:
207*4882a593Smuzhiyun 	case PCM512x_RATE_DET_3:
208*4882a593Smuzhiyun 	case PCM512x_RATE_DET_4:
209*4882a593Smuzhiyun 	case PCM512x_CLOCK_STATUS:
210*4882a593Smuzhiyun 	case PCM512x_ANALOG_MUTE_DET:
211*4882a593Smuzhiyun 	case PCM512x_GPIN:
212*4882a593Smuzhiyun 	case PCM512x_DIGITAL_MUTE_DET:
213*4882a593Smuzhiyun 	case PCM512x_CRAM_CTRL:
214*4882a593Smuzhiyun 		return true;
215*4882a593Smuzhiyun 	default:
216*4882a593Smuzhiyun 		/* There are 256 raw register addresses */
217*4882a593Smuzhiyun 		return reg < 0xff;
218*4882a593Smuzhiyun 	}
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun 
pcm512x_overclock_pll_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)221*4882a593Smuzhiyun static int pcm512x_overclock_pll_get(struct snd_kcontrol *kcontrol,
222*4882a593Smuzhiyun 				     struct snd_ctl_elem_value *ucontrol)
223*4882a593Smuzhiyun {
224*4882a593Smuzhiyun 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
225*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 	ucontrol->value.integer.value[0] = pcm512x->overclock_pll;
228*4882a593Smuzhiyun 	return 0;
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun 
pcm512x_overclock_pll_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)231*4882a593Smuzhiyun static int pcm512x_overclock_pll_put(struct snd_kcontrol *kcontrol,
232*4882a593Smuzhiyun 				     struct snd_ctl_elem_value *ucontrol)
233*4882a593Smuzhiyun {
234*4882a593Smuzhiyun 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
235*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 	switch (snd_soc_component_get_bias_level(component)) {
238*4882a593Smuzhiyun 	case SND_SOC_BIAS_OFF:
239*4882a593Smuzhiyun 	case SND_SOC_BIAS_STANDBY:
240*4882a593Smuzhiyun 		break;
241*4882a593Smuzhiyun 	default:
242*4882a593Smuzhiyun 		return -EBUSY;
243*4882a593Smuzhiyun 	}
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	pcm512x->overclock_pll = ucontrol->value.integer.value[0];
246*4882a593Smuzhiyun 	return 0;
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun 
pcm512x_overclock_dsp_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)249*4882a593Smuzhiyun static int pcm512x_overclock_dsp_get(struct snd_kcontrol *kcontrol,
250*4882a593Smuzhiyun 				     struct snd_ctl_elem_value *ucontrol)
251*4882a593Smuzhiyun {
252*4882a593Smuzhiyun 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
253*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	ucontrol->value.integer.value[0] = pcm512x->overclock_dsp;
256*4882a593Smuzhiyun 	return 0;
257*4882a593Smuzhiyun }
258*4882a593Smuzhiyun 
pcm512x_overclock_dsp_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)259*4882a593Smuzhiyun static int pcm512x_overclock_dsp_put(struct snd_kcontrol *kcontrol,
260*4882a593Smuzhiyun 				     struct snd_ctl_elem_value *ucontrol)
261*4882a593Smuzhiyun {
262*4882a593Smuzhiyun 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
263*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 	switch (snd_soc_component_get_bias_level(component)) {
266*4882a593Smuzhiyun 	case SND_SOC_BIAS_OFF:
267*4882a593Smuzhiyun 	case SND_SOC_BIAS_STANDBY:
268*4882a593Smuzhiyun 		break;
269*4882a593Smuzhiyun 	default:
270*4882a593Smuzhiyun 		return -EBUSY;
271*4882a593Smuzhiyun 	}
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun 	pcm512x->overclock_dsp = ucontrol->value.integer.value[0];
274*4882a593Smuzhiyun 	return 0;
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun 
pcm512x_overclock_dac_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)277*4882a593Smuzhiyun static int pcm512x_overclock_dac_get(struct snd_kcontrol *kcontrol,
278*4882a593Smuzhiyun 				     struct snd_ctl_elem_value *ucontrol)
279*4882a593Smuzhiyun {
280*4882a593Smuzhiyun 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
281*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun 	ucontrol->value.integer.value[0] = pcm512x->overclock_dac;
284*4882a593Smuzhiyun 	return 0;
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun 
pcm512x_overclock_dac_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)287*4882a593Smuzhiyun static int pcm512x_overclock_dac_put(struct snd_kcontrol *kcontrol,
288*4882a593Smuzhiyun 				     struct snd_ctl_elem_value *ucontrol)
289*4882a593Smuzhiyun {
290*4882a593Smuzhiyun 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
291*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun 	switch (snd_soc_component_get_bias_level(component)) {
294*4882a593Smuzhiyun 	case SND_SOC_BIAS_OFF:
295*4882a593Smuzhiyun 	case SND_SOC_BIAS_STANDBY:
296*4882a593Smuzhiyun 		break;
297*4882a593Smuzhiyun 	default:
298*4882a593Smuzhiyun 		return -EBUSY;
299*4882a593Smuzhiyun 	}
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 	pcm512x->overclock_dac = ucontrol->value.integer.value[0];
302*4882a593Smuzhiyun 	return 0;
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun static const DECLARE_TLV_DB_SCALE(digital_tlv, -10350, 50, 1);
306*4882a593Smuzhiyun static const DECLARE_TLV_DB_SCALE(analog_tlv, -600, 600, 0);
307*4882a593Smuzhiyun static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 80, 0);
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun static const char * const pcm512x_dsp_program_texts[] = {
310*4882a593Smuzhiyun 	"FIR interpolation with de-emphasis",
311*4882a593Smuzhiyun 	"Low latency IIR with de-emphasis",
312*4882a593Smuzhiyun 	"High attenuation with de-emphasis",
313*4882a593Smuzhiyun 	"Fixed process flow",
314*4882a593Smuzhiyun 	"Ringing-less low latency FIR",
315*4882a593Smuzhiyun };
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun static const unsigned int pcm512x_dsp_program_values[] = {
318*4882a593Smuzhiyun 	1,
319*4882a593Smuzhiyun 	2,
320*4882a593Smuzhiyun 	3,
321*4882a593Smuzhiyun 	5,
322*4882a593Smuzhiyun 	7,
323*4882a593Smuzhiyun };
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun static SOC_VALUE_ENUM_SINGLE_DECL(pcm512x_dsp_program,
326*4882a593Smuzhiyun 				  PCM512x_DSP_PROGRAM, 0, 0x1f,
327*4882a593Smuzhiyun 				  pcm512x_dsp_program_texts,
328*4882a593Smuzhiyun 				  pcm512x_dsp_program_values);
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun static const char * const pcm512x_clk_missing_text[] = {
331*4882a593Smuzhiyun 	"1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s"
332*4882a593Smuzhiyun };
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun static const struct soc_enum pcm512x_clk_missing =
335*4882a593Smuzhiyun 	SOC_ENUM_SINGLE(PCM512x_CLKDET, 0,  8, pcm512x_clk_missing_text);
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun static const char * const pcm512x_autom_text[] = {
338*4882a593Smuzhiyun 	"21ms", "106ms", "213ms", "533ms", "1.07s", "2.13s", "5.33s", "10.66s"
339*4882a593Smuzhiyun };
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun static const struct soc_enum pcm512x_autom_l =
342*4882a593Smuzhiyun 	SOC_ENUM_SINGLE(PCM512x_AUTO_MUTE, PCM512x_ATML_SHIFT, 8,
343*4882a593Smuzhiyun 			pcm512x_autom_text);
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun static const struct soc_enum pcm512x_autom_r =
346*4882a593Smuzhiyun 	SOC_ENUM_SINGLE(PCM512x_AUTO_MUTE, PCM512x_ATMR_SHIFT, 8,
347*4882a593Smuzhiyun 			pcm512x_autom_text);
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun static const char * const pcm512x_ramp_rate_text[] = {
350*4882a593Smuzhiyun 	"1 sample/update", "2 samples/update", "4 samples/update",
351*4882a593Smuzhiyun 	"Immediate"
352*4882a593Smuzhiyun };
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun static const struct soc_enum pcm512x_vndf =
355*4882a593Smuzhiyun 	SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNDF_SHIFT, 4,
356*4882a593Smuzhiyun 			pcm512x_ramp_rate_text);
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun static const struct soc_enum pcm512x_vnuf =
359*4882a593Smuzhiyun 	SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNUF_SHIFT, 4,
360*4882a593Smuzhiyun 			pcm512x_ramp_rate_text);
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun static const struct soc_enum pcm512x_vedf =
363*4882a593Smuzhiyun 	SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDF_SHIFT, 4,
364*4882a593Smuzhiyun 			pcm512x_ramp_rate_text);
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun static const char * const pcm512x_ramp_step_text[] = {
367*4882a593Smuzhiyun 	"4dB/step", "2dB/step", "1dB/step", "0.5dB/step"
368*4882a593Smuzhiyun };
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun static const struct soc_enum pcm512x_vnds =
371*4882a593Smuzhiyun 	SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNDS_SHIFT, 4,
372*4882a593Smuzhiyun 			pcm512x_ramp_step_text);
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun static const struct soc_enum pcm512x_vnus =
375*4882a593Smuzhiyun 	SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNUS_SHIFT, 4,
376*4882a593Smuzhiyun 			pcm512x_ramp_step_text);
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun static const struct soc_enum pcm512x_veds =
379*4882a593Smuzhiyun 	SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDS_SHIFT, 4,
380*4882a593Smuzhiyun 			pcm512x_ramp_step_text);
381*4882a593Smuzhiyun 
pcm512x_update_mute(struct pcm512x_priv * pcm512x)382*4882a593Smuzhiyun static int pcm512x_update_mute(struct pcm512x_priv *pcm512x)
383*4882a593Smuzhiyun {
384*4882a593Smuzhiyun 	return regmap_update_bits(
385*4882a593Smuzhiyun 		pcm512x->regmap, PCM512x_MUTE, PCM512x_RQML | PCM512x_RQMR,
386*4882a593Smuzhiyun 		(!!(pcm512x->mute & 0x5) << PCM512x_RQML_SHIFT)
387*4882a593Smuzhiyun 		| (!!(pcm512x->mute & 0x3) << PCM512x_RQMR_SHIFT));
388*4882a593Smuzhiyun }
389*4882a593Smuzhiyun 
pcm512x_digital_playback_switch_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)390*4882a593Smuzhiyun static int pcm512x_digital_playback_switch_get(struct snd_kcontrol *kcontrol,
391*4882a593Smuzhiyun 					       struct snd_ctl_elem_value *ucontrol)
392*4882a593Smuzhiyun {
393*4882a593Smuzhiyun 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
394*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun 	mutex_lock(&pcm512x->mutex);
397*4882a593Smuzhiyun 	ucontrol->value.integer.value[0] = !(pcm512x->mute & 0x4);
398*4882a593Smuzhiyun 	ucontrol->value.integer.value[1] = !(pcm512x->mute & 0x2);
399*4882a593Smuzhiyun 	mutex_unlock(&pcm512x->mutex);
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun 	return 0;
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun 
pcm512x_digital_playback_switch_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)404*4882a593Smuzhiyun static int pcm512x_digital_playback_switch_put(struct snd_kcontrol *kcontrol,
405*4882a593Smuzhiyun 					       struct snd_ctl_elem_value *ucontrol)
406*4882a593Smuzhiyun {
407*4882a593Smuzhiyun 	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
408*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
409*4882a593Smuzhiyun 	int ret, changed = 0;
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun 	mutex_lock(&pcm512x->mutex);
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 	if ((pcm512x->mute & 0x4) == (ucontrol->value.integer.value[0] << 2)) {
414*4882a593Smuzhiyun 		pcm512x->mute ^= 0x4;
415*4882a593Smuzhiyun 		changed = 1;
416*4882a593Smuzhiyun 	}
417*4882a593Smuzhiyun 	if ((pcm512x->mute & 0x2) == (ucontrol->value.integer.value[1] << 1)) {
418*4882a593Smuzhiyun 		pcm512x->mute ^= 0x2;
419*4882a593Smuzhiyun 		changed = 1;
420*4882a593Smuzhiyun 	}
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 	if (changed) {
423*4882a593Smuzhiyun 		ret = pcm512x_update_mute(pcm512x);
424*4882a593Smuzhiyun 		if (ret != 0) {
425*4882a593Smuzhiyun 			dev_err(component->dev,
426*4882a593Smuzhiyun 				"Failed to update digital mute: %d\n", ret);
427*4882a593Smuzhiyun 			mutex_unlock(&pcm512x->mutex);
428*4882a593Smuzhiyun 			return ret;
429*4882a593Smuzhiyun 		}
430*4882a593Smuzhiyun 	}
431*4882a593Smuzhiyun 
432*4882a593Smuzhiyun 	mutex_unlock(&pcm512x->mutex);
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun 	return changed;
435*4882a593Smuzhiyun }
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun static const struct snd_kcontrol_new pcm512x_controls[] = {
438*4882a593Smuzhiyun SOC_DOUBLE_R_TLV("Digital Playback Volume", PCM512x_DIGITAL_VOLUME_2,
439*4882a593Smuzhiyun 		 PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv),
440*4882a593Smuzhiyun SOC_DOUBLE_TLV("Analogue Playback Volume", PCM512x_ANALOG_GAIN_CTRL,
441*4882a593Smuzhiyun 	       PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv),
442*4882a593Smuzhiyun SOC_DOUBLE_TLV("Analogue Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST,
443*4882a593Smuzhiyun 	       PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv),
444*4882a593Smuzhiyun {
445*4882a593Smuzhiyun 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
446*4882a593Smuzhiyun 	.name = "Digital Playback Switch",
447*4882a593Smuzhiyun 	.index = 0,
448*4882a593Smuzhiyun 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
449*4882a593Smuzhiyun 	.info = snd_ctl_boolean_stereo_info,
450*4882a593Smuzhiyun 	.get = pcm512x_digital_playback_switch_get,
451*4882a593Smuzhiyun 	.put = pcm512x_digital_playback_switch_put
452*4882a593Smuzhiyun },
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1),
455*4882a593Smuzhiyun SOC_ENUM("DSP Program", pcm512x_dsp_program),
456*4882a593Smuzhiyun 
457*4882a593Smuzhiyun SOC_ENUM("Clock Missing Period", pcm512x_clk_missing),
458*4882a593Smuzhiyun SOC_ENUM("Auto Mute Time Left", pcm512x_autom_l),
459*4882a593Smuzhiyun SOC_ENUM("Auto Mute Time Right", pcm512x_autom_r),
460*4882a593Smuzhiyun SOC_SINGLE("Auto Mute Mono Switch", PCM512x_DIGITAL_MUTE_3,
461*4882a593Smuzhiyun 	   PCM512x_ACTL_SHIFT, 1, 0),
462*4882a593Smuzhiyun SOC_DOUBLE("Auto Mute Switch", PCM512x_DIGITAL_MUTE_3, PCM512x_AMLE_SHIFT,
463*4882a593Smuzhiyun 	   PCM512x_AMRE_SHIFT, 1, 0),
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun SOC_ENUM("Volume Ramp Down Rate", pcm512x_vndf),
466*4882a593Smuzhiyun SOC_ENUM("Volume Ramp Down Step", pcm512x_vnds),
467*4882a593Smuzhiyun SOC_ENUM("Volume Ramp Up Rate", pcm512x_vnuf),
468*4882a593Smuzhiyun SOC_ENUM("Volume Ramp Up Step", pcm512x_vnus),
469*4882a593Smuzhiyun SOC_ENUM("Volume Ramp Down Emergency Rate", pcm512x_vedf),
470*4882a593Smuzhiyun SOC_ENUM("Volume Ramp Down Emergency Step", pcm512x_veds),
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun SOC_SINGLE_EXT("Max Overclock PLL", SND_SOC_NOPM, 0, 20, 0,
473*4882a593Smuzhiyun 	       pcm512x_overclock_pll_get, pcm512x_overclock_pll_put),
474*4882a593Smuzhiyun SOC_SINGLE_EXT("Max Overclock DSP", SND_SOC_NOPM, 0, 40, 0,
475*4882a593Smuzhiyun 	       pcm512x_overclock_dsp_get, pcm512x_overclock_dsp_put),
476*4882a593Smuzhiyun SOC_SINGLE_EXT("Max Overclock DAC", SND_SOC_NOPM, 0, 40, 0,
477*4882a593Smuzhiyun 	       pcm512x_overclock_dac_get, pcm512x_overclock_dac_put),
478*4882a593Smuzhiyun };
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun static const struct snd_soc_dapm_widget pcm512x_dapm_widgets[] = {
481*4882a593Smuzhiyun SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0),
482*4882a593Smuzhiyun SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0),
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun SND_SOC_DAPM_OUTPUT("OUTL"),
485*4882a593Smuzhiyun SND_SOC_DAPM_OUTPUT("OUTR"),
486*4882a593Smuzhiyun };
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun static const struct snd_soc_dapm_route pcm512x_dapm_routes[] = {
489*4882a593Smuzhiyun 	{ "DACL", NULL, "Playback" },
490*4882a593Smuzhiyun 	{ "DACR", NULL, "Playback" },
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 	{ "OUTL", NULL, "DACL" },
493*4882a593Smuzhiyun 	{ "OUTR", NULL, "DACR" },
494*4882a593Smuzhiyun };
495*4882a593Smuzhiyun 
pcm512x_pll_max(struct pcm512x_priv * pcm512x)496*4882a593Smuzhiyun static unsigned long pcm512x_pll_max(struct pcm512x_priv *pcm512x)
497*4882a593Smuzhiyun {
498*4882a593Smuzhiyun 	return 25000000 + 25000000 * pcm512x->overclock_pll / 100;
499*4882a593Smuzhiyun }
500*4882a593Smuzhiyun 
pcm512x_dsp_max(struct pcm512x_priv * pcm512x)501*4882a593Smuzhiyun static unsigned long pcm512x_dsp_max(struct pcm512x_priv *pcm512x)
502*4882a593Smuzhiyun {
503*4882a593Smuzhiyun 	return 50000000 + 50000000 * pcm512x->overclock_dsp / 100;
504*4882a593Smuzhiyun }
505*4882a593Smuzhiyun 
pcm512x_dac_max(struct pcm512x_priv * pcm512x,unsigned long rate)506*4882a593Smuzhiyun static unsigned long pcm512x_dac_max(struct pcm512x_priv *pcm512x,
507*4882a593Smuzhiyun 				     unsigned long rate)
508*4882a593Smuzhiyun {
509*4882a593Smuzhiyun 	return rate + rate * pcm512x->overclock_dac / 100;
510*4882a593Smuzhiyun }
511*4882a593Smuzhiyun 
pcm512x_sck_max(struct pcm512x_priv * pcm512x)512*4882a593Smuzhiyun static unsigned long pcm512x_sck_max(struct pcm512x_priv *pcm512x)
513*4882a593Smuzhiyun {
514*4882a593Smuzhiyun 	if (!pcm512x->pll_out)
515*4882a593Smuzhiyun 		return 25000000;
516*4882a593Smuzhiyun 	return pcm512x_pll_max(pcm512x);
517*4882a593Smuzhiyun }
518*4882a593Smuzhiyun 
pcm512x_ncp_target(struct pcm512x_priv * pcm512x,unsigned long dac_rate)519*4882a593Smuzhiyun static unsigned long pcm512x_ncp_target(struct pcm512x_priv *pcm512x,
520*4882a593Smuzhiyun 					unsigned long dac_rate)
521*4882a593Smuzhiyun {
522*4882a593Smuzhiyun 	/*
523*4882a593Smuzhiyun 	 * If the DAC is not actually overclocked, use the good old
524*4882a593Smuzhiyun 	 * NCP target rate...
525*4882a593Smuzhiyun 	 */
526*4882a593Smuzhiyun 	if (dac_rate <= 6144000)
527*4882a593Smuzhiyun 		return 1536000;
528*4882a593Smuzhiyun 	/*
529*4882a593Smuzhiyun 	 * ...but if the DAC is in fact overclocked, bump the NCP target
530*4882a593Smuzhiyun 	 * rate to get the recommended dividers even when overclocking.
531*4882a593Smuzhiyun 	 */
532*4882a593Smuzhiyun 	return pcm512x_dac_max(pcm512x, 1536000);
533*4882a593Smuzhiyun }
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun static const u32 pcm512x_dai_rates[] = {
536*4882a593Smuzhiyun 	8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000,
537*4882a593Smuzhiyun 	88200, 96000, 176400, 192000, 384000,
538*4882a593Smuzhiyun };
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun static const struct snd_pcm_hw_constraint_list constraints_slave = {
541*4882a593Smuzhiyun 	.count = ARRAY_SIZE(pcm512x_dai_rates),
542*4882a593Smuzhiyun 	.list  = pcm512x_dai_rates,
543*4882a593Smuzhiyun };
544*4882a593Smuzhiyun 
pcm512x_hw_rule_rate(struct snd_pcm_hw_params * params,struct snd_pcm_hw_rule * rule)545*4882a593Smuzhiyun static int pcm512x_hw_rule_rate(struct snd_pcm_hw_params *params,
546*4882a593Smuzhiyun 				struct snd_pcm_hw_rule *rule)
547*4882a593Smuzhiyun {
548*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = rule->private;
549*4882a593Smuzhiyun 	struct snd_interval ranges[2];
550*4882a593Smuzhiyun 	int frame_size;
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun 	frame_size = snd_soc_params_to_frame_size(params);
553*4882a593Smuzhiyun 	if (frame_size < 0)
554*4882a593Smuzhiyun 		return frame_size;
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun 	switch (frame_size) {
557*4882a593Smuzhiyun 	case 32:
558*4882a593Smuzhiyun 		/* No hole when the frame size is 32. */
559*4882a593Smuzhiyun 		return 0;
560*4882a593Smuzhiyun 	case 48:
561*4882a593Smuzhiyun 	case 64:
562*4882a593Smuzhiyun 		/* There is only one hole in the range of supported
563*4882a593Smuzhiyun 		 * rates, but it moves with the frame size.
564*4882a593Smuzhiyun 		 */
565*4882a593Smuzhiyun 		memset(ranges, 0, sizeof(ranges));
566*4882a593Smuzhiyun 		ranges[0].min = 8000;
567*4882a593Smuzhiyun 		ranges[0].max = pcm512x_sck_max(pcm512x) / frame_size / 2;
568*4882a593Smuzhiyun 		ranges[1].min = DIV_ROUND_UP(16000000, frame_size);
569*4882a593Smuzhiyun 		ranges[1].max = 384000;
570*4882a593Smuzhiyun 		break;
571*4882a593Smuzhiyun 	default:
572*4882a593Smuzhiyun 		return -EINVAL;
573*4882a593Smuzhiyun 	}
574*4882a593Smuzhiyun 
575*4882a593Smuzhiyun 	return snd_interval_ranges(hw_param_interval(params, rule->var),
576*4882a593Smuzhiyun 				   ARRAY_SIZE(ranges), ranges, 0);
577*4882a593Smuzhiyun }
578*4882a593Smuzhiyun 
pcm512x_dai_startup_master(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)579*4882a593Smuzhiyun static int pcm512x_dai_startup_master(struct snd_pcm_substream *substream,
580*4882a593Smuzhiyun 				      struct snd_soc_dai *dai)
581*4882a593Smuzhiyun {
582*4882a593Smuzhiyun 	struct snd_soc_component *component = dai->component;
583*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
584*4882a593Smuzhiyun 	struct device *dev = dai->dev;
585*4882a593Smuzhiyun 	struct snd_pcm_hw_constraint_ratnums *constraints_no_pll;
586*4882a593Smuzhiyun 	struct snd_ratnum *rats_no_pll;
587*4882a593Smuzhiyun 
588*4882a593Smuzhiyun 	if (IS_ERR(pcm512x->sclk)) {
589*4882a593Smuzhiyun 		dev_err(dev, "Need SCLK for master mode: %ld\n",
590*4882a593Smuzhiyun 			PTR_ERR(pcm512x->sclk));
591*4882a593Smuzhiyun 		return PTR_ERR(pcm512x->sclk);
592*4882a593Smuzhiyun 	}
593*4882a593Smuzhiyun 
594*4882a593Smuzhiyun 	if (pcm512x->pll_out)
595*4882a593Smuzhiyun 		return snd_pcm_hw_rule_add(substream->runtime, 0,
596*4882a593Smuzhiyun 					   SNDRV_PCM_HW_PARAM_RATE,
597*4882a593Smuzhiyun 					   pcm512x_hw_rule_rate,
598*4882a593Smuzhiyun 					   pcm512x,
599*4882a593Smuzhiyun 					   SNDRV_PCM_HW_PARAM_FRAME_BITS,
600*4882a593Smuzhiyun 					   SNDRV_PCM_HW_PARAM_CHANNELS, -1);
601*4882a593Smuzhiyun 
602*4882a593Smuzhiyun 	constraints_no_pll = devm_kzalloc(dev, sizeof(*constraints_no_pll),
603*4882a593Smuzhiyun 					  GFP_KERNEL);
604*4882a593Smuzhiyun 	if (!constraints_no_pll)
605*4882a593Smuzhiyun 		return -ENOMEM;
606*4882a593Smuzhiyun 	constraints_no_pll->nrats = 1;
607*4882a593Smuzhiyun 	rats_no_pll = devm_kzalloc(dev, sizeof(*rats_no_pll), GFP_KERNEL);
608*4882a593Smuzhiyun 	if (!rats_no_pll)
609*4882a593Smuzhiyun 		return -ENOMEM;
610*4882a593Smuzhiyun 	constraints_no_pll->rats = rats_no_pll;
611*4882a593Smuzhiyun 	rats_no_pll->num = clk_get_rate(pcm512x->sclk) / 64;
612*4882a593Smuzhiyun 	rats_no_pll->den_min = 1;
613*4882a593Smuzhiyun 	rats_no_pll->den_max = 128;
614*4882a593Smuzhiyun 	rats_no_pll->den_step = 1;
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun 	return snd_pcm_hw_constraint_ratnums(substream->runtime, 0,
617*4882a593Smuzhiyun 					     SNDRV_PCM_HW_PARAM_RATE,
618*4882a593Smuzhiyun 					     constraints_no_pll);
619*4882a593Smuzhiyun }
620*4882a593Smuzhiyun 
pcm512x_dai_startup_slave(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)621*4882a593Smuzhiyun static int pcm512x_dai_startup_slave(struct snd_pcm_substream *substream,
622*4882a593Smuzhiyun 				     struct snd_soc_dai *dai)
623*4882a593Smuzhiyun {
624*4882a593Smuzhiyun 	struct snd_soc_component *component = dai->component;
625*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
626*4882a593Smuzhiyun 	struct device *dev = dai->dev;
627*4882a593Smuzhiyun 	struct regmap *regmap = pcm512x->regmap;
628*4882a593Smuzhiyun 
629*4882a593Smuzhiyun 	if (IS_ERR(pcm512x->sclk)) {
630*4882a593Smuzhiyun 		dev_info(dev, "No SCLK, using BCLK: %ld\n",
631*4882a593Smuzhiyun 			 PTR_ERR(pcm512x->sclk));
632*4882a593Smuzhiyun 
633*4882a593Smuzhiyun 		/* Disable reporting of missing SCLK as an error */
634*4882a593Smuzhiyun 		regmap_update_bits(regmap, PCM512x_ERROR_DETECT,
635*4882a593Smuzhiyun 				   PCM512x_IDCH, PCM512x_IDCH);
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun 		/* Switch PLL input to BCLK */
638*4882a593Smuzhiyun 		regmap_update_bits(regmap, PCM512x_PLL_REF,
639*4882a593Smuzhiyun 				   PCM512x_SREF, PCM512x_SREF_BCK);
640*4882a593Smuzhiyun 	}
641*4882a593Smuzhiyun 
642*4882a593Smuzhiyun 	return snd_pcm_hw_constraint_list(substream->runtime, 0,
643*4882a593Smuzhiyun 					  SNDRV_PCM_HW_PARAM_RATE,
644*4882a593Smuzhiyun 					  &constraints_slave);
645*4882a593Smuzhiyun }
646*4882a593Smuzhiyun 
pcm512x_dai_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)647*4882a593Smuzhiyun static int pcm512x_dai_startup(struct snd_pcm_substream *substream,
648*4882a593Smuzhiyun 			       struct snd_soc_dai *dai)
649*4882a593Smuzhiyun {
650*4882a593Smuzhiyun 	struct snd_soc_component *component = dai->component;
651*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun 	switch (pcm512x->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
654*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_CBM_CFM:
655*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_CBM_CFS:
656*4882a593Smuzhiyun 		return pcm512x_dai_startup_master(substream, dai);
657*4882a593Smuzhiyun 
658*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_CBS_CFS:
659*4882a593Smuzhiyun 		return pcm512x_dai_startup_slave(substream, dai);
660*4882a593Smuzhiyun 
661*4882a593Smuzhiyun 	default:
662*4882a593Smuzhiyun 		return -EINVAL;
663*4882a593Smuzhiyun 	}
664*4882a593Smuzhiyun }
665*4882a593Smuzhiyun 
pcm512x_set_bias_level(struct snd_soc_component * component,enum snd_soc_bias_level level)666*4882a593Smuzhiyun static int pcm512x_set_bias_level(struct snd_soc_component *component,
667*4882a593Smuzhiyun 				  enum snd_soc_bias_level level)
668*4882a593Smuzhiyun {
669*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = dev_get_drvdata(component->dev);
670*4882a593Smuzhiyun 	int ret;
671*4882a593Smuzhiyun 
672*4882a593Smuzhiyun 	switch (level) {
673*4882a593Smuzhiyun 	case SND_SOC_BIAS_ON:
674*4882a593Smuzhiyun 	case SND_SOC_BIAS_PREPARE:
675*4882a593Smuzhiyun 		break;
676*4882a593Smuzhiyun 
677*4882a593Smuzhiyun 	case SND_SOC_BIAS_STANDBY:
678*4882a593Smuzhiyun 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
679*4882a593Smuzhiyun 					 PCM512x_RQST, 0);
680*4882a593Smuzhiyun 		if (ret != 0) {
681*4882a593Smuzhiyun 			dev_err(component->dev, "Failed to remove standby: %d\n",
682*4882a593Smuzhiyun 				ret);
683*4882a593Smuzhiyun 			return ret;
684*4882a593Smuzhiyun 		}
685*4882a593Smuzhiyun 		break;
686*4882a593Smuzhiyun 
687*4882a593Smuzhiyun 	case SND_SOC_BIAS_OFF:
688*4882a593Smuzhiyun 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
689*4882a593Smuzhiyun 					 PCM512x_RQST, PCM512x_RQST);
690*4882a593Smuzhiyun 		if (ret != 0) {
691*4882a593Smuzhiyun 			dev_err(component->dev, "Failed to request standby: %d\n",
692*4882a593Smuzhiyun 				ret);
693*4882a593Smuzhiyun 			return ret;
694*4882a593Smuzhiyun 		}
695*4882a593Smuzhiyun 		break;
696*4882a593Smuzhiyun 	}
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun 	return 0;
699*4882a593Smuzhiyun }
700*4882a593Smuzhiyun 
pcm512x_find_sck(struct snd_soc_dai * dai,unsigned long bclk_rate)701*4882a593Smuzhiyun static unsigned long pcm512x_find_sck(struct snd_soc_dai *dai,
702*4882a593Smuzhiyun 				      unsigned long bclk_rate)
703*4882a593Smuzhiyun {
704*4882a593Smuzhiyun 	struct device *dev = dai->dev;
705*4882a593Smuzhiyun 	struct snd_soc_component *component = dai->component;
706*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
707*4882a593Smuzhiyun 	unsigned long sck_rate;
708*4882a593Smuzhiyun 	int pow2;
709*4882a593Smuzhiyun 
710*4882a593Smuzhiyun 	/* 64 MHz <= pll_rate <= 100 MHz, VREF mode */
711*4882a593Smuzhiyun 	/* 16 MHz <= sck_rate <=  25 MHz, VREF mode */
712*4882a593Smuzhiyun 
713*4882a593Smuzhiyun 	/* select sck_rate as a multiple of bclk_rate but still with
714*4882a593Smuzhiyun 	 * as many factors of 2 as possible, as that makes it easier
715*4882a593Smuzhiyun 	 * to find a fast DAC rate
716*4882a593Smuzhiyun 	 */
717*4882a593Smuzhiyun 	pow2 = 1 << fls((pcm512x_pll_max(pcm512x) - 16000000) / bclk_rate);
718*4882a593Smuzhiyun 	for (; pow2; pow2 >>= 1) {
719*4882a593Smuzhiyun 		sck_rate = rounddown(pcm512x_pll_max(pcm512x),
720*4882a593Smuzhiyun 				     bclk_rate * pow2);
721*4882a593Smuzhiyun 		if (sck_rate >= 16000000)
722*4882a593Smuzhiyun 			break;
723*4882a593Smuzhiyun 	}
724*4882a593Smuzhiyun 	if (!pow2) {
725*4882a593Smuzhiyun 		dev_err(dev, "Impossible to generate a suitable SCK\n");
726*4882a593Smuzhiyun 		return 0;
727*4882a593Smuzhiyun 	}
728*4882a593Smuzhiyun 
729*4882a593Smuzhiyun 	dev_dbg(dev, "sck_rate %lu\n", sck_rate);
730*4882a593Smuzhiyun 	return sck_rate;
731*4882a593Smuzhiyun }
732*4882a593Smuzhiyun 
733*4882a593Smuzhiyun /* pll_rate = pllin_rate * R * J.D / P
734*4882a593Smuzhiyun  * 1 <= R <= 16
735*4882a593Smuzhiyun  * 1 <= J <= 63
736*4882a593Smuzhiyun  * 0 <= D <= 9999
737*4882a593Smuzhiyun  * 1 <= P <= 15
738*4882a593Smuzhiyun  * 64 MHz <= pll_rate <= 100 MHz
739*4882a593Smuzhiyun  * if D == 0
740*4882a593Smuzhiyun  *     1 MHz <= pllin_rate / P <= 20 MHz
741*4882a593Smuzhiyun  * else if D > 0
742*4882a593Smuzhiyun  *     6.667 MHz <= pllin_rate / P <= 20 MHz
743*4882a593Smuzhiyun  *     4 <= J <= 11
744*4882a593Smuzhiyun  *     R = 1
745*4882a593Smuzhiyun  */
pcm512x_find_pll_coeff(struct snd_soc_dai * dai,unsigned long pllin_rate,unsigned long pll_rate)746*4882a593Smuzhiyun static int pcm512x_find_pll_coeff(struct snd_soc_dai *dai,
747*4882a593Smuzhiyun 				  unsigned long pllin_rate,
748*4882a593Smuzhiyun 				  unsigned long pll_rate)
749*4882a593Smuzhiyun {
750*4882a593Smuzhiyun 	struct device *dev = dai->dev;
751*4882a593Smuzhiyun 	struct snd_soc_component *component = dai->component;
752*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
753*4882a593Smuzhiyun 	unsigned long common;
754*4882a593Smuzhiyun 	int R, J, D, P;
755*4882a593Smuzhiyun 	unsigned long K; /* 10000 * J.D */
756*4882a593Smuzhiyun 	unsigned long num;
757*4882a593Smuzhiyun 	unsigned long den;
758*4882a593Smuzhiyun 
759*4882a593Smuzhiyun 	common = gcd(pll_rate, pllin_rate);
760*4882a593Smuzhiyun 	dev_dbg(dev, "pll %lu pllin %lu common %lu\n",
761*4882a593Smuzhiyun 		pll_rate, pllin_rate, common);
762*4882a593Smuzhiyun 	num = pll_rate / common;
763*4882a593Smuzhiyun 	den = pllin_rate / common;
764*4882a593Smuzhiyun 
765*4882a593Smuzhiyun 	/* pllin_rate / P (or here, den) cannot be greater than 20 MHz */
766*4882a593Smuzhiyun 	if (pllin_rate / den > 20000000 && num < 8) {
767*4882a593Smuzhiyun 		num *= DIV_ROUND_UP(pllin_rate / den, 20000000);
768*4882a593Smuzhiyun 		den *= DIV_ROUND_UP(pllin_rate / den, 20000000);
769*4882a593Smuzhiyun 	}
770*4882a593Smuzhiyun 	dev_dbg(dev, "num / den = %lu / %lu\n", num, den);
771*4882a593Smuzhiyun 
772*4882a593Smuzhiyun 	P = den;
773*4882a593Smuzhiyun 	if (den <= 15 && num <= 16 * 63
774*4882a593Smuzhiyun 	    && 1000000 <= pllin_rate / P && pllin_rate / P <= 20000000) {
775*4882a593Smuzhiyun 		/* Try the case with D = 0 */
776*4882a593Smuzhiyun 		D = 0;
777*4882a593Smuzhiyun 		/* factor 'num' into J and R, such that R <= 16 and J <= 63 */
778*4882a593Smuzhiyun 		for (R = 16; R; R--) {
779*4882a593Smuzhiyun 			if (num % R)
780*4882a593Smuzhiyun 				continue;
781*4882a593Smuzhiyun 			J = num / R;
782*4882a593Smuzhiyun 			if (J == 0 || J > 63)
783*4882a593Smuzhiyun 				continue;
784*4882a593Smuzhiyun 
785*4882a593Smuzhiyun 			dev_dbg(dev, "R * J / P = %d * %d / %d\n", R, J, P);
786*4882a593Smuzhiyun 			pcm512x->real_pll = pll_rate;
787*4882a593Smuzhiyun 			goto done;
788*4882a593Smuzhiyun 		}
789*4882a593Smuzhiyun 		/* no luck */
790*4882a593Smuzhiyun 	}
791*4882a593Smuzhiyun 
792*4882a593Smuzhiyun 	R = 1;
793*4882a593Smuzhiyun 
794*4882a593Smuzhiyun 	if (num > 0xffffffffUL / 10000)
795*4882a593Smuzhiyun 		goto fallback;
796*4882a593Smuzhiyun 
797*4882a593Smuzhiyun 	/* Try to find an exact pll_rate using the D > 0 case */
798*4882a593Smuzhiyun 	common = gcd(10000 * num, den);
799*4882a593Smuzhiyun 	num = 10000 * num / common;
800*4882a593Smuzhiyun 	den /= common;
801*4882a593Smuzhiyun 	dev_dbg(dev, "num %lu den %lu common %lu\n", num, den, common);
802*4882a593Smuzhiyun 
803*4882a593Smuzhiyun 	for (P = den; P <= 15; P++) {
804*4882a593Smuzhiyun 		if (pllin_rate / P < 6667000 || 200000000 < pllin_rate / P)
805*4882a593Smuzhiyun 			continue;
806*4882a593Smuzhiyun 		if (num * P % den)
807*4882a593Smuzhiyun 			continue;
808*4882a593Smuzhiyun 		K = num * P / den;
809*4882a593Smuzhiyun 		/* J == 12 is ok if D == 0 */
810*4882a593Smuzhiyun 		if (K < 40000 || K > 120000)
811*4882a593Smuzhiyun 			continue;
812*4882a593Smuzhiyun 
813*4882a593Smuzhiyun 		J = K / 10000;
814*4882a593Smuzhiyun 		D = K % 10000;
815*4882a593Smuzhiyun 		dev_dbg(dev, "J.D / P = %d.%04d / %d\n", J, D, P);
816*4882a593Smuzhiyun 		pcm512x->real_pll = pll_rate;
817*4882a593Smuzhiyun 		goto done;
818*4882a593Smuzhiyun 	}
819*4882a593Smuzhiyun 
820*4882a593Smuzhiyun 	/* Fall back to an approximate pll_rate */
821*4882a593Smuzhiyun 
822*4882a593Smuzhiyun fallback:
823*4882a593Smuzhiyun 	/* find smallest possible P */
824*4882a593Smuzhiyun 	P = DIV_ROUND_UP(pllin_rate, 20000000);
825*4882a593Smuzhiyun 	if (!P)
826*4882a593Smuzhiyun 		P = 1;
827*4882a593Smuzhiyun 	else if (P > 15) {
828*4882a593Smuzhiyun 		dev_err(dev, "Need a slower clock as pll-input\n");
829*4882a593Smuzhiyun 		return -EINVAL;
830*4882a593Smuzhiyun 	}
831*4882a593Smuzhiyun 	if (pllin_rate / P < 6667000) {
832*4882a593Smuzhiyun 		dev_err(dev, "Need a faster clock as pll-input\n");
833*4882a593Smuzhiyun 		return -EINVAL;
834*4882a593Smuzhiyun 	}
835*4882a593Smuzhiyun 	K = DIV_ROUND_CLOSEST_ULL(10000ULL * pll_rate * P, pllin_rate);
836*4882a593Smuzhiyun 	if (K < 40000)
837*4882a593Smuzhiyun 		K = 40000;
838*4882a593Smuzhiyun 	/* J == 12 is ok if D == 0 */
839*4882a593Smuzhiyun 	if (K > 120000)
840*4882a593Smuzhiyun 		K = 120000;
841*4882a593Smuzhiyun 	J = K / 10000;
842*4882a593Smuzhiyun 	D = K % 10000;
843*4882a593Smuzhiyun 	dev_dbg(dev, "J.D / P ~ %d.%04d / %d\n", J, D, P);
844*4882a593Smuzhiyun 	pcm512x->real_pll = DIV_ROUND_DOWN_ULL((u64)K * pllin_rate, 10000 * P);
845*4882a593Smuzhiyun 
846*4882a593Smuzhiyun done:
847*4882a593Smuzhiyun 	pcm512x->pll_r = R;
848*4882a593Smuzhiyun 	pcm512x->pll_j = J;
849*4882a593Smuzhiyun 	pcm512x->pll_d = D;
850*4882a593Smuzhiyun 	pcm512x->pll_p = P;
851*4882a593Smuzhiyun 	return 0;
852*4882a593Smuzhiyun }
853*4882a593Smuzhiyun 
pcm512x_pllin_dac_rate(struct snd_soc_dai * dai,unsigned long osr_rate,unsigned long pllin_rate)854*4882a593Smuzhiyun static unsigned long pcm512x_pllin_dac_rate(struct snd_soc_dai *dai,
855*4882a593Smuzhiyun 					    unsigned long osr_rate,
856*4882a593Smuzhiyun 					    unsigned long pllin_rate)
857*4882a593Smuzhiyun {
858*4882a593Smuzhiyun 	struct snd_soc_component *component = dai->component;
859*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
860*4882a593Smuzhiyun 	unsigned long dac_rate;
861*4882a593Smuzhiyun 
862*4882a593Smuzhiyun 	if (!pcm512x->pll_out)
863*4882a593Smuzhiyun 		return 0; /* no PLL to bypass, force SCK as DAC input */
864*4882a593Smuzhiyun 
865*4882a593Smuzhiyun 	if (pllin_rate % osr_rate)
866*4882a593Smuzhiyun 		return 0; /* futile, quit early */
867*4882a593Smuzhiyun 
868*4882a593Smuzhiyun 	/* run DAC no faster than 6144000 Hz */
869*4882a593Smuzhiyun 	for (dac_rate = rounddown(pcm512x_dac_max(pcm512x, 6144000), osr_rate);
870*4882a593Smuzhiyun 	     dac_rate;
871*4882a593Smuzhiyun 	     dac_rate -= osr_rate) {
872*4882a593Smuzhiyun 
873*4882a593Smuzhiyun 		if (pllin_rate / dac_rate > 128)
874*4882a593Smuzhiyun 			return 0; /* DAC divider would be too big */
875*4882a593Smuzhiyun 
876*4882a593Smuzhiyun 		if (!(pllin_rate % dac_rate))
877*4882a593Smuzhiyun 			return dac_rate;
878*4882a593Smuzhiyun 
879*4882a593Smuzhiyun 		dac_rate -= osr_rate;
880*4882a593Smuzhiyun 	}
881*4882a593Smuzhiyun 
882*4882a593Smuzhiyun 	return 0;
883*4882a593Smuzhiyun }
884*4882a593Smuzhiyun 
pcm512x_set_dividers(struct snd_soc_dai * dai,struct snd_pcm_hw_params * params)885*4882a593Smuzhiyun static int pcm512x_set_dividers(struct snd_soc_dai *dai,
886*4882a593Smuzhiyun 				struct snd_pcm_hw_params *params)
887*4882a593Smuzhiyun {
888*4882a593Smuzhiyun 	struct device *dev = dai->dev;
889*4882a593Smuzhiyun 	struct snd_soc_component *component = dai->component;
890*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
891*4882a593Smuzhiyun 	unsigned long pllin_rate = 0;
892*4882a593Smuzhiyun 	unsigned long pll_rate;
893*4882a593Smuzhiyun 	unsigned long sck_rate;
894*4882a593Smuzhiyun 	unsigned long mck_rate;
895*4882a593Smuzhiyun 	unsigned long bclk_rate;
896*4882a593Smuzhiyun 	unsigned long sample_rate;
897*4882a593Smuzhiyun 	unsigned long osr_rate;
898*4882a593Smuzhiyun 	unsigned long dacsrc_rate;
899*4882a593Smuzhiyun 	int bclk_div;
900*4882a593Smuzhiyun 	int lrclk_div;
901*4882a593Smuzhiyun 	int dsp_div;
902*4882a593Smuzhiyun 	int dac_div;
903*4882a593Smuzhiyun 	unsigned long dac_rate;
904*4882a593Smuzhiyun 	int ncp_div;
905*4882a593Smuzhiyun 	int osr_div;
906*4882a593Smuzhiyun 	int ret;
907*4882a593Smuzhiyun 	int idac;
908*4882a593Smuzhiyun 	int fssp;
909*4882a593Smuzhiyun 	int gpio;
910*4882a593Smuzhiyun 
911*4882a593Smuzhiyun 	if (pcm512x->bclk_ratio > 0) {
912*4882a593Smuzhiyun 		lrclk_div = pcm512x->bclk_ratio;
913*4882a593Smuzhiyun 	} else {
914*4882a593Smuzhiyun 		lrclk_div = snd_soc_params_to_frame_size(params);
915*4882a593Smuzhiyun 
916*4882a593Smuzhiyun 		if (lrclk_div == 0) {
917*4882a593Smuzhiyun 			dev_err(dev, "No LRCLK?\n");
918*4882a593Smuzhiyun 			return -EINVAL;
919*4882a593Smuzhiyun 		}
920*4882a593Smuzhiyun 	}
921*4882a593Smuzhiyun 
922*4882a593Smuzhiyun 	if (!pcm512x->pll_out) {
923*4882a593Smuzhiyun 		sck_rate = clk_get_rate(pcm512x->sclk);
924*4882a593Smuzhiyun 		bclk_rate = params_rate(params) * lrclk_div;
925*4882a593Smuzhiyun 		bclk_div = DIV_ROUND_CLOSEST(sck_rate, bclk_rate);
926*4882a593Smuzhiyun 
927*4882a593Smuzhiyun 		mck_rate = sck_rate;
928*4882a593Smuzhiyun 	} else {
929*4882a593Smuzhiyun 		ret = snd_soc_params_to_bclk(params);
930*4882a593Smuzhiyun 		if (ret < 0) {
931*4882a593Smuzhiyun 			dev_err(dev, "Failed to find suitable BCLK: %d\n", ret);
932*4882a593Smuzhiyun 			return ret;
933*4882a593Smuzhiyun 		}
934*4882a593Smuzhiyun 		if (ret == 0) {
935*4882a593Smuzhiyun 			dev_err(dev, "No BCLK?\n");
936*4882a593Smuzhiyun 			return -EINVAL;
937*4882a593Smuzhiyun 		}
938*4882a593Smuzhiyun 		bclk_rate = ret;
939*4882a593Smuzhiyun 
940*4882a593Smuzhiyun 		pllin_rate = clk_get_rate(pcm512x->sclk);
941*4882a593Smuzhiyun 
942*4882a593Smuzhiyun 		sck_rate = pcm512x_find_sck(dai, bclk_rate);
943*4882a593Smuzhiyun 		if (!sck_rate)
944*4882a593Smuzhiyun 			return -EINVAL;
945*4882a593Smuzhiyun 		pll_rate = 4 * sck_rate;
946*4882a593Smuzhiyun 
947*4882a593Smuzhiyun 		ret = pcm512x_find_pll_coeff(dai, pllin_rate, pll_rate);
948*4882a593Smuzhiyun 		if (ret != 0)
949*4882a593Smuzhiyun 			return ret;
950*4882a593Smuzhiyun 
951*4882a593Smuzhiyun 		ret = regmap_write(pcm512x->regmap,
952*4882a593Smuzhiyun 				   PCM512x_PLL_COEFF_0, pcm512x->pll_p - 1);
953*4882a593Smuzhiyun 		if (ret != 0) {
954*4882a593Smuzhiyun 			dev_err(dev, "Failed to write PLL P: %d\n", ret);
955*4882a593Smuzhiyun 			return ret;
956*4882a593Smuzhiyun 		}
957*4882a593Smuzhiyun 
958*4882a593Smuzhiyun 		ret = regmap_write(pcm512x->regmap,
959*4882a593Smuzhiyun 				   PCM512x_PLL_COEFF_1, pcm512x->pll_j);
960*4882a593Smuzhiyun 		if (ret != 0) {
961*4882a593Smuzhiyun 			dev_err(dev, "Failed to write PLL J: %d\n", ret);
962*4882a593Smuzhiyun 			return ret;
963*4882a593Smuzhiyun 		}
964*4882a593Smuzhiyun 
965*4882a593Smuzhiyun 		ret = regmap_write(pcm512x->regmap,
966*4882a593Smuzhiyun 				   PCM512x_PLL_COEFF_2, pcm512x->pll_d >> 8);
967*4882a593Smuzhiyun 		if (ret != 0) {
968*4882a593Smuzhiyun 			dev_err(dev, "Failed to write PLL D msb: %d\n", ret);
969*4882a593Smuzhiyun 			return ret;
970*4882a593Smuzhiyun 		}
971*4882a593Smuzhiyun 
972*4882a593Smuzhiyun 		ret = regmap_write(pcm512x->regmap,
973*4882a593Smuzhiyun 				   PCM512x_PLL_COEFF_3, pcm512x->pll_d & 0xff);
974*4882a593Smuzhiyun 		if (ret != 0) {
975*4882a593Smuzhiyun 			dev_err(dev, "Failed to write PLL D lsb: %d\n", ret);
976*4882a593Smuzhiyun 			return ret;
977*4882a593Smuzhiyun 		}
978*4882a593Smuzhiyun 
979*4882a593Smuzhiyun 		ret = regmap_write(pcm512x->regmap,
980*4882a593Smuzhiyun 				   PCM512x_PLL_COEFF_4, pcm512x->pll_r - 1);
981*4882a593Smuzhiyun 		if (ret != 0) {
982*4882a593Smuzhiyun 			dev_err(dev, "Failed to write PLL R: %d\n", ret);
983*4882a593Smuzhiyun 			return ret;
984*4882a593Smuzhiyun 		}
985*4882a593Smuzhiyun 
986*4882a593Smuzhiyun 		mck_rate = pcm512x->real_pll;
987*4882a593Smuzhiyun 
988*4882a593Smuzhiyun 		bclk_div = DIV_ROUND_CLOSEST(sck_rate, bclk_rate);
989*4882a593Smuzhiyun 	}
990*4882a593Smuzhiyun 
991*4882a593Smuzhiyun 	if (bclk_div > 128) {
992*4882a593Smuzhiyun 		dev_err(dev, "Failed to find BCLK divider\n");
993*4882a593Smuzhiyun 		return -EINVAL;
994*4882a593Smuzhiyun 	}
995*4882a593Smuzhiyun 
996*4882a593Smuzhiyun 	/* the actual rate */
997*4882a593Smuzhiyun 	sample_rate = sck_rate / bclk_div / lrclk_div;
998*4882a593Smuzhiyun 	osr_rate = 16 * sample_rate;
999*4882a593Smuzhiyun 
1000*4882a593Smuzhiyun 	/* run DSP no faster than 50 MHz */
1001*4882a593Smuzhiyun 	dsp_div = mck_rate > pcm512x_dsp_max(pcm512x) ? 2 : 1;
1002*4882a593Smuzhiyun 
1003*4882a593Smuzhiyun 	dac_rate = pcm512x_pllin_dac_rate(dai, osr_rate, pllin_rate);
1004*4882a593Smuzhiyun 	if (dac_rate) {
1005*4882a593Smuzhiyun 		/* the desired clock rate is "compatible" with the pll input
1006*4882a593Smuzhiyun 		 * clock, so use that clock as dac input instead of the pll
1007*4882a593Smuzhiyun 		 * output clock since the pll will introduce jitter and thus
1008*4882a593Smuzhiyun 		 * noise.
1009*4882a593Smuzhiyun 		 */
1010*4882a593Smuzhiyun 		dev_dbg(dev, "using pll input as dac input\n");
1011*4882a593Smuzhiyun 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_DAC_REF,
1012*4882a593Smuzhiyun 					 PCM512x_SDAC, PCM512x_SDAC_GPIO);
1013*4882a593Smuzhiyun 		if (ret != 0) {
1014*4882a593Smuzhiyun 			dev_err(component->dev,
1015*4882a593Smuzhiyun 				"Failed to set gpio as dacref: %d\n", ret);
1016*4882a593Smuzhiyun 			return ret;
1017*4882a593Smuzhiyun 		}
1018*4882a593Smuzhiyun 
1019*4882a593Smuzhiyun 		gpio = PCM512x_GREF_GPIO1 + pcm512x->pll_in - 1;
1020*4882a593Smuzhiyun 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_DACIN,
1021*4882a593Smuzhiyun 					 PCM512x_GREF, gpio);
1022*4882a593Smuzhiyun 		if (ret != 0) {
1023*4882a593Smuzhiyun 			dev_err(component->dev,
1024*4882a593Smuzhiyun 				"Failed to set gpio %d as dacin: %d\n",
1025*4882a593Smuzhiyun 				pcm512x->pll_in, ret);
1026*4882a593Smuzhiyun 			return ret;
1027*4882a593Smuzhiyun 		}
1028*4882a593Smuzhiyun 
1029*4882a593Smuzhiyun 		dacsrc_rate = pllin_rate;
1030*4882a593Smuzhiyun 	} else {
1031*4882a593Smuzhiyun 		/* run DAC no faster than 6144000 Hz */
1032*4882a593Smuzhiyun 		unsigned long dac_mul = pcm512x_dac_max(pcm512x, 6144000)
1033*4882a593Smuzhiyun 			/ osr_rate;
1034*4882a593Smuzhiyun 		unsigned long sck_mul = sck_rate / osr_rate;
1035*4882a593Smuzhiyun 
1036*4882a593Smuzhiyun 		for (; dac_mul; dac_mul--) {
1037*4882a593Smuzhiyun 			if (!(sck_mul % dac_mul))
1038*4882a593Smuzhiyun 				break;
1039*4882a593Smuzhiyun 		}
1040*4882a593Smuzhiyun 		if (!dac_mul) {
1041*4882a593Smuzhiyun 			dev_err(dev, "Failed to find DAC rate\n");
1042*4882a593Smuzhiyun 			return -EINVAL;
1043*4882a593Smuzhiyun 		}
1044*4882a593Smuzhiyun 
1045*4882a593Smuzhiyun 		dac_rate = dac_mul * osr_rate;
1046*4882a593Smuzhiyun 		dev_dbg(dev, "dac_rate %lu sample_rate %lu\n",
1047*4882a593Smuzhiyun 			dac_rate, sample_rate);
1048*4882a593Smuzhiyun 
1049*4882a593Smuzhiyun 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_DAC_REF,
1050*4882a593Smuzhiyun 					 PCM512x_SDAC, PCM512x_SDAC_SCK);
1051*4882a593Smuzhiyun 		if (ret != 0) {
1052*4882a593Smuzhiyun 			dev_err(component->dev,
1053*4882a593Smuzhiyun 				"Failed to set sck as dacref: %d\n", ret);
1054*4882a593Smuzhiyun 			return ret;
1055*4882a593Smuzhiyun 		}
1056*4882a593Smuzhiyun 
1057*4882a593Smuzhiyun 		dacsrc_rate = sck_rate;
1058*4882a593Smuzhiyun 	}
1059*4882a593Smuzhiyun 
1060*4882a593Smuzhiyun 	osr_div = DIV_ROUND_CLOSEST(dac_rate, osr_rate);
1061*4882a593Smuzhiyun 	if (osr_div > 128) {
1062*4882a593Smuzhiyun 		dev_err(dev, "Failed to find OSR divider\n");
1063*4882a593Smuzhiyun 		return -EINVAL;
1064*4882a593Smuzhiyun 	}
1065*4882a593Smuzhiyun 
1066*4882a593Smuzhiyun 	dac_div = DIV_ROUND_CLOSEST(dacsrc_rate, dac_rate);
1067*4882a593Smuzhiyun 	if (dac_div > 128) {
1068*4882a593Smuzhiyun 		dev_err(dev, "Failed to find DAC divider\n");
1069*4882a593Smuzhiyun 		return -EINVAL;
1070*4882a593Smuzhiyun 	}
1071*4882a593Smuzhiyun 	dac_rate = dacsrc_rate / dac_div;
1072*4882a593Smuzhiyun 
1073*4882a593Smuzhiyun 	ncp_div = DIV_ROUND_CLOSEST(dac_rate,
1074*4882a593Smuzhiyun 				    pcm512x_ncp_target(pcm512x, dac_rate));
1075*4882a593Smuzhiyun 	if (ncp_div > 128 || dac_rate / ncp_div > 2048000) {
1076*4882a593Smuzhiyun 		/* run NCP no faster than 2048000 Hz, but why? */
1077*4882a593Smuzhiyun 		ncp_div = DIV_ROUND_UP(dac_rate, 2048000);
1078*4882a593Smuzhiyun 		if (ncp_div > 128) {
1079*4882a593Smuzhiyun 			dev_err(dev, "Failed to find NCP divider\n");
1080*4882a593Smuzhiyun 			return -EINVAL;
1081*4882a593Smuzhiyun 		}
1082*4882a593Smuzhiyun 	}
1083*4882a593Smuzhiyun 
1084*4882a593Smuzhiyun 	idac = mck_rate / (dsp_div * sample_rate);
1085*4882a593Smuzhiyun 
1086*4882a593Smuzhiyun 	ret = regmap_write(pcm512x->regmap, PCM512x_DSP_CLKDIV, dsp_div - 1);
1087*4882a593Smuzhiyun 	if (ret != 0) {
1088*4882a593Smuzhiyun 		dev_err(dev, "Failed to write DSP divider: %d\n", ret);
1089*4882a593Smuzhiyun 		return ret;
1090*4882a593Smuzhiyun 	}
1091*4882a593Smuzhiyun 
1092*4882a593Smuzhiyun 	ret = regmap_write(pcm512x->regmap, PCM512x_DAC_CLKDIV, dac_div - 1);
1093*4882a593Smuzhiyun 	if (ret != 0) {
1094*4882a593Smuzhiyun 		dev_err(dev, "Failed to write DAC divider: %d\n", ret);
1095*4882a593Smuzhiyun 		return ret;
1096*4882a593Smuzhiyun 	}
1097*4882a593Smuzhiyun 
1098*4882a593Smuzhiyun 	ret = regmap_write(pcm512x->regmap, PCM512x_NCP_CLKDIV, ncp_div - 1);
1099*4882a593Smuzhiyun 	if (ret != 0) {
1100*4882a593Smuzhiyun 		dev_err(dev, "Failed to write NCP divider: %d\n", ret);
1101*4882a593Smuzhiyun 		return ret;
1102*4882a593Smuzhiyun 	}
1103*4882a593Smuzhiyun 
1104*4882a593Smuzhiyun 	ret = regmap_write(pcm512x->regmap, PCM512x_OSR_CLKDIV, osr_div - 1);
1105*4882a593Smuzhiyun 	if (ret != 0) {
1106*4882a593Smuzhiyun 		dev_err(dev, "Failed to write OSR divider: %d\n", ret);
1107*4882a593Smuzhiyun 		return ret;
1108*4882a593Smuzhiyun 	}
1109*4882a593Smuzhiyun 
1110*4882a593Smuzhiyun 	ret = regmap_write(pcm512x->regmap,
1111*4882a593Smuzhiyun 			   PCM512x_MASTER_CLKDIV_1, bclk_div - 1);
1112*4882a593Smuzhiyun 	if (ret != 0) {
1113*4882a593Smuzhiyun 		dev_err(dev, "Failed to write BCLK divider: %d\n", ret);
1114*4882a593Smuzhiyun 		return ret;
1115*4882a593Smuzhiyun 	}
1116*4882a593Smuzhiyun 
1117*4882a593Smuzhiyun 	ret = regmap_write(pcm512x->regmap,
1118*4882a593Smuzhiyun 			   PCM512x_MASTER_CLKDIV_2, lrclk_div - 1);
1119*4882a593Smuzhiyun 	if (ret != 0) {
1120*4882a593Smuzhiyun 		dev_err(dev, "Failed to write LRCLK divider: %d\n", ret);
1121*4882a593Smuzhiyun 		return ret;
1122*4882a593Smuzhiyun 	}
1123*4882a593Smuzhiyun 
1124*4882a593Smuzhiyun 	ret = regmap_write(pcm512x->regmap, PCM512x_IDAC_1, idac >> 8);
1125*4882a593Smuzhiyun 	if (ret != 0) {
1126*4882a593Smuzhiyun 		dev_err(dev, "Failed to write IDAC msb divider: %d\n", ret);
1127*4882a593Smuzhiyun 		return ret;
1128*4882a593Smuzhiyun 	}
1129*4882a593Smuzhiyun 
1130*4882a593Smuzhiyun 	ret = regmap_write(pcm512x->regmap, PCM512x_IDAC_2, idac & 0xff);
1131*4882a593Smuzhiyun 	if (ret != 0) {
1132*4882a593Smuzhiyun 		dev_err(dev, "Failed to write IDAC lsb divider: %d\n", ret);
1133*4882a593Smuzhiyun 		return ret;
1134*4882a593Smuzhiyun 	}
1135*4882a593Smuzhiyun 
1136*4882a593Smuzhiyun 	if (sample_rate <= pcm512x_dac_max(pcm512x, 48000))
1137*4882a593Smuzhiyun 		fssp = PCM512x_FSSP_48KHZ;
1138*4882a593Smuzhiyun 	else if (sample_rate <= pcm512x_dac_max(pcm512x, 96000))
1139*4882a593Smuzhiyun 		fssp = PCM512x_FSSP_96KHZ;
1140*4882a593Smuzhiyun 	else if (sample_rate <= pcm512x_dac_max(pcm512x, 192000))
1141*4882a593Smuzhiyun 		fssp = PCM512x_FSSP_192KHZ;
1142*4882a593Smuzhiyun 	else
1143*4882a593Smuzhiyun 		fssp = PCM512x_FSSP_384KHZ;
1144*4882a593Smuzhiyun 	ret = regmap_update_bits(pcm512x->regmap, PCM512x_FS_SPEED_MODE,
1145*4882a593Smuzhiyun 				 PCM512x_FSSP, fssp);
1146*4882a593Smuzhiyun 	if (ret != 0) {
1147*4882a593Smuzhiyun 		dev_err(component->dev, "Failed to set fs speed: %d\n", ret);
1148*4882a593Smuzhiyun 		return ret;
1149*4882a593Smuzhiyun 	}
1150*4882a593Smuzhiyun 
1151*4882a593Smuzhiyun 	dev_dbg(component->dev, "DSP divider %d\n", dsp_div);
1152*4882a593Smuzhiyun 	dev_dbg(component->dev, "DAC divider %d\n", dac_div);
1153*4882a593Smuzhiyun 	dev_dbg(component->dev, "NCP divider %d\n", ncp_div);
1154*4882a593Smuzhiyun 	dev_dbg(component->dev, "OSR divider %d\n", osr_div);
1155*4882a593Smuzhiyun 	dev_dbg(component->dev, "BCK divider %d\n", bclk_div);
1156*4882a593Smuzhiyun 	dev_dbg(component->dev, "LRCK divider %d\n", lrclk_div);
1157*4882a593Smuzhiyun 	dev_dbg(component->dev, "IDAC %d\n", idac);
1158*4882a593Smuzhiyun 	dev_dbg(component->dev, "1<<FSSP %d\n", 1 << fssp);
1159*4882a593Smuzhiyun 
1160*4882a593Smuzhiyun 	return 0;
1161*4882a593Smuzhiyun }
1162*4882a593Smuzhiyun 
pcm512x_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)1163*4882a593Smuzhiyun static int pcm512x_hw_params(struct snd_pcm_substream *substream,
1164*4882a593Smuzhiyun 			     struct snd_pcm_hw_params *params,
1165*4882a593Smuzhiyun 			     struct snd_soc_dai *dai)
1166*4882a593Smuzhiyun {
1167*4882a593Smuzhiyun 	struct snd_soc_component *component = dai->component;
1168*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
1169*4882a593Smuzhiyun 	int alen;
1170*4882a593Smuzhiyun 	int gpio;
1171*4882a593Smuzhiyun 	int clock_output;
1172*4882a593Smuzhiyun 	int master_mode;
1173*4882a593Smuzhiyun 	int ret;
1174*4882a593Smuzhiyun 
1175*4882a593Smuzhiyun 	dev_dbg(component->dev, "hw_params %u Hz, %u channels\n",
1176*4882a593Smuzhiyun 		params_rate(params),
1177*4882a593Smuzhiyun 		params_channels(params));
1178*4882a593Smuzhiyun 
1179*4882a593Smuzhiyun 	switch (params_width(params)) {
1180*4882a593Smuzhiyun 	case 16:
1181*4882a593Smuzhiyun 		alen = PCM512x_ALEN_16;
1182*4882a593Smuzhiyun 		break;
1183*4882a593Smuzhiyun 	case 20:
1184*4882a593Smuzhiyun 		alen = PCM512x_ALEN_20;
1185*4882a593Smuzhiyun 		break;
1186*4882a593Smuzhiyun 	case 24:
1187*4882a593Smuzhiyun 		alen = PCM512x_ALEN_24;
1188*4882a593Smuzhiyun 		break;
1189*4882a593Smuzhiyun 	case 32:
1190*4882a593Smuzhiyun 		alen = PCM512x_ALEN_32;
1191*4882a593Smuzhiyun 		break;
1192*4882a593Smuzhiyun 	default:
1193*4882a593Smuzhiyun 		dev_err(component->dev, "Bad frame size: %d\n",
1194*4882a593Smuzhiyun 			params_width(params));
1195*4882a593Smuzhiyun 		return -EINVAL;
1196*4882a593Smuzhiyun 	}
1197*4882a593Smuzhiyun 
1198*4882a593Smuzhiyun 	switch (pcm512x->fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1199*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_CBS_CFS:
1200*4882a593Smuzhiyun 		ret = regmap_update_bits(pcm512x->regmap,
1201*4882a593Smuzhiyun 					 PCM512x_BCLK_LRCLK_CFG,
1202*4882a593Smuzhiyun 					 PCM512x_BCKP
1203*4882a593Smuzhiyun 					 | PCM512x_BCKO | PCM512x_LRKO,
1204*4882a593Smuzhiyun 					 0);
1205*4882a593Smuzhiyun 		if (ret != 0) {
1206*4882a593Smuzhiyun 			dev_err(component->dev,
1207*4882a593Smuzhiyun 				"Failed to enable slave mode: %d\n", ret);
1208*4882a593Smuzhiyun 			return ret;
1209*4882a593Smuzhiyun 		}
1210*4882a593Smuzhiyun 
1211*4882a593Smuzhiyun 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_ERROR_DETECT,
1212*4882a593Smuzhiyun 					 PCM512x_DCAS, 0);
1213*4882a593Smuzhiyun 		if (ret != 0) {
1214*4882a593Smuzhiyun 			dev_err(component->dev,
1215*4882a593Smuzhiyun 				"Failed to enable clock divider autoset: %d\n",
1216*4882a593Smuzhiyun 				ret);
1217*4882a593Smuzhiyun 			return ret;
1218*4882a593Smuzhiyun 		}
1219*4882a593Smuzhiyun 		return 0;
1220*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_CBM_CFM:
1221*4882a593Smuzhiyun 		clock_output = PCM512x_BCKO | PCM512x_LRKO;
1222*4882a593Smuzhiyun 		master_mode = PCM512x_RLRK | PCM512x_RBCK;
1223*4882a593Smuzhiyun 		break;
1224*4882a593Smuzhiyun 	case SND_SOC_DAIFMT_CBM_CFS:
1225*4882a593Smuzhiyun 		clock_output = PCM512x_BCKO;
1226*4882a593Smuzhiyun 		master_mode = PCM512x_RBCK;
1227*4882a593Smuzhiyun 		break;
1228*4882a593Smuzhiyun 	default:
1229*4882a593Smuzhiyun 		return -EINVAL;
1230*4882a593Smuzhiyun 	}
1231*4882a593Smuzhiyun 
1232*4882a593Smuzhiyun 	ret = regmap_update_bits(pcm512x->regmap, PCM512x_I2S_1,
1233*4882a593Smuzhiyun 				 PCM512x_ALEN, alen);
1234*4882a593Smuzhiyun 	if (ret != 0) {
1235*4882a593Smuzhiyun 		dev_err(component->dev, "Failed to set frame size: %d\n", ret);
1236*4882a593Smuzhiyun 		return ret;
1237*4882a593Smuzhiyun 	}
1238*4882a593Smuzhiyun 
1239*4882a593Smuzhiyun 	if (pcm512x->pll_out) {
1240*4882a593Smuzhiyun 		ret = regmap_write(pcm512x->regmap, PCM512x_FLEX_A, 0x11);
1241*4882a593Smuzhiyun 		if (ret != 0) {
1242*4882a593Smuzhiyun 			dev_err(component->dev, "Failed to set FLEX_A: %d\n", ret);
1243*4882a593Smuzhiyun 			return ret;
1244*4882a593Smuzhiyun 		}
1245*4882a593Smuzhiyun 
1246*4882a593Smuzhiyun 		ret = regmap_write(pcm512x->regmap, PCM512x_FLEX_B, 0xff);
1247*4882a593Smuzhiyun 		if (ret != 0) {
1248*4882a593Smuzhiyun 			dev_err(component->dev, "Failed to set FLEX_B: %d\n", ret);
1249*4882a593Smuzhiyun 			return ret;
1250*4882a593Smuzhiyun 		}
1251*4882a593Smuzhiyun 
1252*4882a593Smuzhiyun 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_ERROR_DETECT,
1253*4882a593Smuzhiyun 					 PCM512x_IDFS | PCM512x_IDBK
1254*4882a593Smuzhiyun 					 | PCM512x_IDSK | PCM512x_IDCH
1255*4882a593Smuzhiyun 					 | PCM512x_IDCM | PCM512x_DCAS
1256*4882a593Smuzhiyun 					 | PCM512x_IPLK,
1257*4882a593Smuzhiyun 					 PCM512x_IDFS | PCM512x_IDBK
1258*4882a593Smuzhiyun 					 | PCM512x_IDSK | PCM512x_IDCH
1259*4882a593Smuzhiyun 					 | PCM512x_DCAS);
1260*4882a593Smuzhiyun 		if (ret != 0) {
1261*4882a593Smuzhiyun 			dev_err(component->dev,
1262*4882a593Smuzhiyun 				"Failed to ignore auto-clock failures: %d\n",
1263*4882a593Smuzhiyun 				ret);
1264*4882a593Smuzhiyun 			return ret;
1265*4882a593Smuzhiyun 		}
1266*4882a593Smuzhiyun 	} else {
1267*4882a593Smuzhiyun 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_ERROR_DETECT,
1268*4882a593Smuzhiyun 					 PCM512x_IDFS | PCM512x_IDBK
1269*4882a593Smuzhiyun 					 | PCM512x_IDSK | PCM512x_IDCH
1270*4882a593Smuzhiyun 					 | PCM512x_IDCM | PCM512x_DCAS
1271*4882a593Smuzhiyun 					 | PCM512x_IPLK,
1272*4882a593Smuzhiyun 					 PCM512x_IDFS | PCM512x_IDBK
1273*4882a593Smuzhiyun 					 | PCM512x_IDSK | PCM512x_IDCH
1274*4882a593Smuzhiyun 					 | PCM512x_DCAS | PCM512x_IPLK);
1275*4882a593Smuzhiyun 		if (ret != 0) {
1276*4882a593Smuzhiyun 			dev_err(component->dev,
1277*4882a593Smuzhiyun 				"Failed to ignore auto-clock failures: %d\n",
1278*4882a593Smuzhiyun 				ret);
1279*4882a593Smuzhiyun 			return ret;
1280*4882a593Smuzhiyun 		}
1281*4882a593Smuzhiyun 
1282*4882a593Smuzhiyun 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_PLL_EN,
1283*4882a593Smuzhiyun 					 PCM512x_PLLE, 0);
1284*4882a593Smuzhiyun 		if (ret != 0) {
1285*4882a593Smuzhiyun 			dev_err(component->dev, "Failed to disable pll: %d\n", ret);
1286*4882a593Smuzhiyun 			return ret;
1287*4882a593Smuzhiyun 		}
1288*4882a593Smuzhiyun 	}
1289*4882a593Smuzhiyun 
1290*4882a593Smuzhiyun 	ret = pcm512x_set_dividers(dai, params);
1291*4882a593Smuzhiyun 	if (ret != 0)
1292*4882a593Smuzhiyun 		return ret;
1293*4882a593Smuzhiyun 
1294*4882a593Smuzhiyun 	if (pcm512x->pll_out) {
1295*4882a593Smuzhiyun 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_PLL_REF,
1296*4882a593Smuzhiyun 					 PCM512x_SREF, PCM512x_SREF_GPIO);
1297*4882a593Smuzhiyun 		if (ret != 0) {
1298*4882a593Smuzhiyun 			dev_err(component->dev,
1299*4882a593Smuzhiyun 				"Failed to set gpio as pllref: %d\n", ret);
1300*4882a593Smuzhiyun 			return ret;
1301*4882a593Smuzhiyun 		}
1302*4882a593Smuzhiyun 
1303*4882a593Smuzhiyun 		gpio = PCM512x_GREF_GPIO1 + pcm512x->pll_in - 1;
1304*4882a593Smuzhiyun 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_PLLIN,
1305*4882a593Smuzhiyun 					 PCM512x_GREF, gpio);
1306*4882a593Smuzhiyun 		if (ret != 0) {
1307*4882a593Smuzhiyun 			dev_err(component->dev,
1308*4882a593Smuzhiyun 				"Failed to set gpio %d as pllin: %d\n",
1309*4882a593Smuzhiyun 				pcm512x->pll_in, ret);
1310*4882a593Smuzhiyun 			return ret;
1311*4882a593Smuzhiyun 		}
1312*4882a593Smuzhiyun 
1313*4882a593Smuzhiyun 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_PLL_EN,
1314*4882a593Smuzhiyun 					 PCM512x_PLLE, PCM512x_PLLE);
1315*4882a593Smuzhiyun 		if (ret != 0) {
1316*4882a593Smuzhiyun 			dev_err(component->dev, "Failed to enable pll: %d\n", ret);
1317*4882a593Smuzhiyun 			return ret;
1318*4882a593Smuzhiyun 		}
1319*4882a593Smuzhiyun 	}
1320*4882a593Smuzhiyun 
1321*4882a593Smuzhiyun 	ret = regmap_update_bits(pcm512x->regmap, PCM512x_BCLK_LRCLK_CFG,
1322*4882a593Smuzhiyun 				 PCM512x_BCKP | PCM512x_BCKO | PCM512x_LRKO,
1323*4882a593Smuzhiyun 				 clock_output);
1324*4882a593Smuzhiyun 	if (ret != 0) {
1325*4882a593Smuzhiyun 		dev_err(component->dev, "Failed to enable clock output: %d\n", ret);
1326*4882a593Smuzhiyun 		return ret;
1327*4882a593Smuzhiyun 	}
1328*4882a593Smuzhiyun 
1329*4882a593Smuzhiyun 	ret = regmap_update_bits(pcm512x->regmap, PCM512x_MASTER_MODE,
1330*4882a593Smuzhiyun 				 PCM512x_RLRK | PCM512x_RBCK,
1331*4882a593Smuzhiyun 				 master_mode);
1332*4882a593Smuzhiyun 	if (ret != 0) {
1333*4882a593Smuzhiyun 		dev_err(component->dev, "Failed to enable master mode: %d\n", ret);
1334*4882a593Smuzhiyun 		return ret;
1335*4882a593Smuzhiyun 	}
1336*4882a593Smuzhiyun 
1337*4882a593Smuzhiyun 	if (pcm512x->pll_out) {
1338*4882a593Smuzhiyun 		gpio = PCM512x_G1OE << (pcm512x->pll_out - 1);
1339*4882a593Smuzhiyun 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_GPIO_EN,
1340*4882a593Smuzhiyun 					 gpio, gpio);
1341*4882a593Smuzhiyun 		if (ret != 0) {
1342*4882a593Smuzhiyun 			dev_err(component->dev, "Failed to enable gpio %d: %d\n",
1343*4882a593Smuzhiyun 				pcm512x->pll_out, ret);
1344*4882a593Smuzhiyun 			return ret;
1345*4882a593Smuzhiyun 		}
1346*4882a593Smuzhiyun 
1347*4882a593Smuzhiyun 		gpio = PCM512x_GPIO_OUTPUT_1 + pcm512x->pll_out - 1;
1348*4882a593Smuzhiyun 		ret = regmap_update_bits(pcm512x->regmap, gpio,
1349*4882a593Smuzhiyun 					 PCM512x_GxSL, PCM512x_GxSL_PLLCK);
1350*4882a593Smuzhiyun 		if (ret != 0) {
1351*4882a593Smuzhiyun 			dev_err(component->dev, "Failed to output pll on %d: %d\n",
1352*4882a593Smuzhiyun 				ret, pcm512x->pll_out);
1353*4882a593Smuzhiyun 			return ret;
1354*4882a593Smuzhiyun 		}
1355*4882a593Smuzhiyun 	}
1356*4882a593Smuzhiyun 
1357*4882a593Smuzhiyun 	ret = regmap_update_bits(pcm512x->regmap, PCM512x_SYNCHRONIZE,
1358*4882a593Smuzhiyun 				 PCM512x_RQSY, PCM512x_RQSY_HALT);
1359*4882a593Smuzhiyun 	if (ret != 0) {
1360*4882a593Smuzhiyun 		dev_err(component->dev, "Failed to halt clocks: %d\n", ret);
1361*4882a593Smuzhiyun 		return ret;
1362*4882a593Smuzhiyun 	}
1363*4882a593Smuzhiyun 
1364*4882a593Smuzhiyun 	ret = regmap_update_bits(pcm512x->regmap, PCM512x_SYNCHRONIZE,
1365*4882a593Smuzhiyun 				 PCM512x_RQSY, PCM512x_RQSY_RESUME);
1366*4882a593Smuzhiyun 	if (ret != 0) {
1367*4882a593Smuzhiyun 		dev_err(component->dev, "Failed to resume clocks: %d\n", ret);
1368*4882a593Smuzhiyun 		return ret;
1369*4882a593Smuzhiyun 	}
1370*4882a593Smuzhiyun 
1371*4882a593Smuzhiyun 	return 0;
1372*4882a593Smuzhiyun }
1373*4882a593Smuzhiyun 
pcm512x_set_fmt(struct snd_soc_dai * dai,unsigned int fmt)1374*4882a593Smuzhiyun static int pcm512x_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1375*4882a593Smuzhiyun {
1376*4882a593Smuzhiyun 	struct snd_soc_component *component = dai->component;
1377*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
1378*4882a593Smuzhiyun 
1379*4882a593Smuzhiyun 	pcm512x->fmt = fmt;
1380*4882a593Smuzhiyun 
1381*4882a593Smuzhiyun 	return 0;
1382*4882a593Smuzhiyun }
1383*4882a593Smuzhiyun 
pcm512x_set_bclk_ratio(struct snd_soc_dai * dai,unsigned int ratio)1384*4882a593Smuzhiyun static int pcm512x_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
1385*4882a593Smuzhiyun {
1386*4882a593Smuzhiyun 	struct snd_soc_component *component = dai->component;
1387*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
1388*4882a593Smuzhiyun 
1389*4882a593Smuzhiyun 	if (ratio > 256)
1390*4882a593Smuzhiyun 		return -EINVAL;
1391*4882a593Smuzhiyun 
1392*4882a593Smuzhiyun 	pcm512x->bclk_ratio = ratio;
1393*4882a593Smuzhiyun 
1394*4882a593Smuzhiyun 	return 0;
1395*4882a593Smuzhiyun }
1396*4882a593Smuzhiyun 
pcm512x_mute(struct snd_soc_dai * dai,int mute,int direction)1397*4882a593Smuzhiyun static int pcm512x_mute(struct snd_soc_dai *dai, int mute, int direction)
1398*4882a593Smuzhiyun {
1399*4882a593Smuzhiyun 	struct snd_soc_component *component = dai->component;
1400*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
1401*4882a593Smuzhiyun 	int ret;
1402*4882a593Smuzhiyun 	unsigned int mute_det;
1403*4882a593Smuzhiyun 
1404*4882a593Smuzhiyun 	mutex_lock(&pcm512x->mutex);
1405*4882a593Smuzhiyun 
1406*4882a593Smuzhiyun 	if (mute) {
1407*4882a593Smuzhiyun 		pcm512x->mute |= 0x1;
1408*4882a593Smuzhiyun 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_MUTE,
1409*4882a593Smuzhiyun 					 PCM512x_RQML | PCM512x_RQMR,
1410*4882a593Smuzhiyun 					 PCM512x_RQML | PCM512x_RQMR);
1411*4882a593Smuzhiyun 		if (ret != 0) {
1412*4882a593Smuzhiyun 			dev_err(component->dev,
1413*4882a593Smuzhiyun 				"Failed to set digital mute: %d\n", ret);
1414*4882a593Smuzhiyun 			goto unlock;
1415*4882a593Smuzhiyun 		}
1416*4882a593Smuzhiyun 
1417*4882a593Smuzhiyun 		regmap_read_poll_timeout(pcm512x->regmap,
1418*4882a593Smuzhiyun 					 PCM512x_ANALOG_MUTE_DET,
1419*4882a593Smuzhiyun 					 mute_det, (mute_det & 0x3) == 0,
1420*4882a593Smuzhiyun 					 200, 10000);
1421*4882a593Smuzhiyun 	} else {
1422*4882a593Smuzhiyun 		pcm512x->mute &= ~0x1;
1423*4882a593Smuzhiyun 		ret = pcm512x_update_mute(pcm512x);
1424*4882a593Smuzhiyun 		if (ret != 0) {
1425*4882a593Smuzhiyun 			dev_err(component->dev,
1426*4882a593Smuzhiyun 				"Failed to update digital mute: %d\n", ret);
1427*4882a593Smuzhiyun 			goto unlock;
1428*4882a593Smuzhiyun 		}
1429*4882a593Smuzhiyun 
1430*4882a593Smuzhiyun 		regmap_read_poll_timeout(pcm512x->regmap,
1431*4882a593Smuzhiyun 					 PCM512x_ANALOG_MUTE_DET,
1432*4882a593Smuzhiyun 					 mute_det,
1433*4882a593Smuzhiyun 					 (mute_det & 0x3)
1434*4882a593Smuzhiyun 					 == ((~pcm512x->mute >> 1) & 0x3),
1435*4882a593Smuzhiyun 					 200, 10000);
1436*4882a593Smuzhiyun 	}
1437*4882a593Smuzhiyun 
1438*4882a593Smuzhiyun unlock:
1439*4882a593Smuzhiyun 	mutex_unlock(&pcm512x->mutex);
1440*4882a593Smuzhiyun 
1441*4882a593Smuzhiyun 	return ret;
1442*4882a593Smuzhiyun }
1443*4882a593Smuzhiyun 
1444*4882a593Smuzhiyun static const struct snd_soc_dai_ops pcm512x_dai_ops = {
1445*4882a593Smuzhiyun 	.startup = pcm512x_dai_startup,
1446*4882a593Smuzhiyun 	.hw_params = pcm512x_hw_params,
1447*4882a593Smuzhiyun 	.set_fmt = pcm512x_set_fmt,
1448*4882a593Smuzhiyun 	.mute_stream = pcm512x_mute,
1449*4882a593Smuzhiyun 	.set_bclk_ratio = pcm512x_set_bclk_ratio,
1450*4882a593Smuzhiyun 	.no_capture_mute = 1,
1451*4882a593Smuzhiyun };
1452*4882a593Smuzhiyun 
1453*4882a593Smuzhiyun static struct snd_soc_dai_driver pcm512x_dai = {
1454*4882a593Smuzhiyun 	.name = "pcm512x-hifi",
1455*4882a593Smuzhiyun 	.playback = {
1456*4882a593Smuzhiyun 		.stream_name = "Playback",
1457*4882a593Smuzhiyun 		.channels_min = 2,
1458*4882a593Smuzhiyun 		.channels_max = 2,
1459*4882a593Smuzhiyun 		.rates = SNDRV_PCM_RATE_CONTINUOUS,
1460*4882a593Smuzhiyun 		.rate_min = 8000,
1461*4882a593Smuzhiyun 		.rate_max = 384000,
1462*4882a593Smuzhiyun 		.formats = SNDRV_PCM_FMTBIT_S16_LE |
1463*4882a593Smuzhiyun 			   SNDRV_PCM_FMTBIT_S24_LE |
1464*4882a593Smuzhiyun 			   SNDRV_PCM_FMTBIT_S32_LE
1465*4882a593Smuzhiyun 	},
1466*4882a593Smuzhiyun 	.ops = &pcm512x_dai_ops,
1467*4882a593Smuzhiyun };
1468*4882a593Smuzhiyun 
1469*4882a593Smuzhiyun static const struct snd_soc_component_driver pcm512x_component_driver = {
1470*4882a593Smuzhiyun 	.set_bias_level		= pcm512x_set_bias_level,
1471*4882a593Smuzhiyun 	.controls		= pcm512x_controls,
1472*4882a593Smuzhiyun 	.num_controls		= ARRAY_SIZE(pcm512x_controls),
1473*4882a593Smuzhiyun 	.dapm_widgets		= pcm512x_dapm_widgets,
1474*4882a593Smuzhiyun 	.num_dapm_widgets	= ARRAY_SIZE(pcm512x_dapm_widgets),
1475*4882a593Smuzhiyun 	.dapm_routes		= pcm512x_dapm_routes,
1476*4882a593Smuzhiyun 	.num_dapm_routes	= ARRAY_SIZE(pcm512x_dapm_routes),
1477*4882a593Smuzhiyun 	.use_pmdown_time	= 1,
1478*4882a593Smuzhiyun 	.endianness		= 1,
1479*4882a593Smuzhiyun 	.non_legacy_dai_naming	= 1,
1480*4882a593Smuzhiyun };
1481*4882a593Smuzhiyun 
1482*4882a593Smuzhiyun static const struct regmap_range_cfg pcm512x_range = {
1483*4882a593Smuzhiyun 	.name = "Pages", .range_min = PCM512x_VIRT_BASE,
1484*4882a593Smuzhiyun 	.range_max = PCM512x_MAX_REGISTER,
1485*4882a593Smuzhiyun 	.selector_reg = PCM512x_PAGE,
1486*4882a593Smuzhiyun 	.selector_mask = 0xff,
1487*4882a593Smuzhiyun 	.window_start = 0, .window_len = 0x100,
1488*4882a593Smuzhiyun };
1489*4882a593Smuzhiyun 
1490*4882a593Smuzhiyun const struct regmap_config pcm512x_regmap = {
1491*4882a593Smuzhiyun 	.reg_bits = 8,
1492*4882a593Smuzhiyun 	.val_bits = 8,
1493*4882a593Smuzhiyun 
1494*4882a593Smuzhiyun 	.readable_reg = pcm512x_readable,
1495*4882a593Smuzhiyun 	.volatile_reg = pcm512x_volatile,
1496*4882a593Smuzhiyun 
1497*4882a593Smuzhiyun 	.ranges = &pcm512x_range,
1498*4882a593Smuzhiyun 	.num_ranges = 1,
1499*4882a593Smuzhiyun 
1500*4882a593Smuzhiyun 	.max_register = PCM512x_MAX_REGISTER,
1501*4882a593Smuzhiyun 	.reg_defaults = pcm512x_reg_defaults,
1502*4882a593Smuzhiyun 	.num_reg_defaults = ARRAY_SIZE(pcm512x_reg_defaults),
1503*4882a593Smuzhiyun 	.cache_type = REGCACHE_RBTREE,
1504*4882a593Smuzhiyun };
1505*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pcm512x_regmap);
1506*4882a593Smuzhiyun 
pcm512x_probe(struct device * dev,struct regmap * regmap)1507*4882a593Smuzhiyun int pcm512x_probe(struct device *dev, struct regmap *regmap)
1508*4882a593Smuzhiyun {
1509*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x;
1510*4882a593Smuzhiyun 	int i, ret;
1511*4882a593Smuzhiyun 
1512*4882a593Smuzhiyun 	pcm512x = devm_kzalloc(dev, sizeof(struct pcm512x_priv), GFP_KERNEL);
1513*4882a593Smuzhiyun 	if (!pcm512x)
1514*4882a593Smuzhiyun 		return -ENOMEM;
1515*4882a593Smuzhiyun 
1516*4882a593Smuzhiyun 	mutex_init(&pcm512x->mutex);
1517*4882a593Smuzhiyun 
1518*4882a593Smuzhiyun 	dev_set_drvdata(dev, pcm512x);
1519*4882a593Smuzhiyun 	pcm512x->regmap = regmap;
1520*4882a593Smuzhiyun 
1521*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++)
1522*4882a593Smuzhiyun 		pcm512x->supplies[i].supply = pcm512x_supply_names[i];
1523*4882a593Smuzhiyun 
1524*4882a593Smuzhiyun 	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(pcm512x->supplies),
1525*4882a593Smuzhiyun 				      pcm512x->supplies);
1526*4882a593Smuzhiyun 	if (ret != 0) {
1527*4882a593Smuzhiyun 		dev_err(dev, "Failed to get supplies: %d\n", ret);
1528*4882a593Smuzhiyun 		return ret;
1529*4882a593Smuzhiyun 	}
1530*4882a593Smuzhiyun 
1531*4882a593Smuzhiyun 	pcm512x->supply_nb[0].notifier_call = pcm512x_regulator_event_0;
1532*4882a593Smuzhiyun 	pcm512x->supply_nb[1].notifier_call = pcm512x_regulator_event_1;
1533*4882a593Smuzhiyun 	pcm512x->supply_nb[2].notifier_call = pcm512x_regulator_event_2;
1534*4882a593Smuzhiyun 
1535*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++) {
1536*4882a593Smuzhiyun 		ret = devm_regulator_register_notifier(
1537*4882a593Smuzhiyun 						pcm512x->supplies[i].consumer,
1538*4882a593Smuzhiyun 						&pcm512x->supply_nb[i]);
1539*4882a593Smuzhiyun 		if (ret != 0) {
1540*4882a593Smuzhiyun 			dev_err(dev,
1541*4882a593Smuzhiyun 				"Failed to register regulator notifier: %d\n",
1542*4882a593Smuzhiyun 				ret);
1543*4882a593Smuzhiyun 		}
1544*4882a593Smuzhiyun 	}
1545*4882a593Smuzhiyun 
1546*4882a593Smuzhiyun 	ret = regulator_bulk_enable(ARRAY_SIZE(pcm512x->supplies),
1547*4882a593Smuzhiyun 				    pcm512x->supplies);
1548*4882a593Smuzhiyun 	if (ret != 0) {
1549*4882a593Smuzhiyun 		dev_err(dev, "Failed to enable supplies: %d\n", ret);
1550*4882a593Smuzhiyun 		return ret;
1551*4882a593Smuzhiyun 	}
1552*4882a593Smuzhiyun 
1553*4882a593Smuzhiyun 	/* Reset the device, verifying I/O in the process for I2C */
1554*4882a593Smuzhiyun 	ret = regmap_write(regmap, PCM512x_RESET,
1555*4882a593Smuzhiyun 			   PCM512x_RSTM | PCM512x_RSTR);
1556*4882a593Smuzhiyun 	if (ret != 0) {
1557*4882a593Smuzhiyun 		dev_err(dev, "Failed to reset device: %d\n", ret);
1558*4882a593Smuzhiyun 		goto err;
1559*4882a593Smuzhiyun 	}
1560*4882a593Smuzhiyun 
1561*4882a593Smuzhiyun 	ret = regmap_write(regmap, PCM512x_RESET, 0);
1562*4882a593Smuzhiyun 	if (ret != 0) {
1563*4882a593Smuzhiyun 		dev_err(dev, "Failed to reset device: %d\n", ret);
1564*4882a593Smuzhiyun 		goto err;
1565*4882a593Smuzhiyun 	}
1566*4882a593Smuzhiyun 
1567*4882a593Smuzhiyun 	pcm512x->sclk = devm_clk_get(dev, NULL);
1568*4882a593Smuzhiyun 	if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER) {
1569*4882a593Smuzhiyun 		ret = -EPROBE_DEFER;
1570*4882a593Smuzhiyun 		goto err;
1571*4882a593Smuzhiyun 	}
1572*4882a593Smuzhiyun 	if (!IS_ERR(pcm512x->sclk)) {
1573*4882a593Smuzhiyun 		ret = clk_prepare_enable(pcm512x->sclk);
1574*4882a593Smuzhiyun 		if (ret != 0) {
1575*4882a593Smuzhiyun 			dev_err(dev, "Failed to enable SCLK: %d\n", ret);
1576*4882a593Smuzhiyun 			goto err;
1577*4882a593Smuzhiyun 		}
1578*4882a593Smuzhiyun 	}
1579*4882a593Smuzhiyun 
1580*4882a593Smuzhiyun 	/* Default to standby mode */
1581*4882a593Smuzhiyun 	ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
1582*4882a593Smuzhiyun 				 PCM512x_RQST, PCM512x_RQST);
1583*4882a593Smuzhiyun 	if (ret != 0) {
1584*4882a593Smuzhiyun 		dev_err(dev, "Failed to request standby: %d\n",
1585*4882a593Smuzhiyun 			ret);
1586*4882a593Smuzhiyun 		goto err_clk;
1587*4882a593Smuzhiyun 	}
1588*4882a593Smuzhiyun 
1589*4882a593Smuzhiyun 	pm_runtime_set_active(dev);
1590*4882a593Smuzhiyun 	pm_runtime_enable(dev);
1591*4882a593Smuzhiyun 	pm_runtime_idle(dev);
1592*4882a593Smuzhiyun 
1593*4882a593Smuzhiyun #ifdef CONFIG_OF
1594*4882a593Smuzhiyun 	if (dev->of_node) {
1595*4882a593Smuzhiyun 		const struct device_node *np = dev->of_node;
1596*4882a593Smuzhiyun 		u32 val;
1597*4882a593Smuzhiyun 
1598*4882a593Smuzhiyun 		if (of_property_read_u32(np, "pll-in", &val) >= 0) {
1599*4882a593Smuzhiyun 			if (val > 6) {
1600*4882a593Smuzhiyun 				dev_err(dev, "Invalid pll-in\n");
1601*4882a593Smuzhiyun 				ret = -EINVAL;
1602*4882a593Smuzhiyun 				goto err_clk;
1603*4882a593Smuzhiyun 			}
1604*4882a593Smuzhiyun 			pcm512x->pll_in = val;
1605*4882a593Smuzhiyun 		}
1606*4882a593Smuzhiyun 
1607*4882a593Smuzhiyun 		if (of_property_read_u32(np, "pll-out", &val) >= 0) {
1608*4882a593Smuzhiyun 			if (val > 6) {
1609*4882a593Smuzhiyun 				dev_err(dev, "Invalid pll-out\n");
1610*4882a593Smuzhiyun 				ret = -EINVAL;
1611*4882a593Smuzhiyun 				goto err_clk;
1612*4882a593Smuzhiyun 			}
1613*4882a593Smuzhiyun 			pcm512x->pll_out = val;
1614*4882a593Smuzhiyun 		}
1615*4882a593Smuzhiyun 
1616*4882a593Smuzhiyun 		if (!pcm512x->pll_in != !pcm512x->pll_out) {
1617*4882a593Smuzhiyun 			dev_err(dev,
1618*4882a593Smuzhiyun 				"Error: both pll-in and pll-out, or none\n");
1619*4882a593Smuzhiyun 			ret = -EINVAL;
1620*4882a593Smuzhiyun 			goto err_clk;
1621*4882a593Smuzhiyun 		}
1622*4882a593Smuzhiyun 		if (pcm512x->pll_in && pcm512x->pll_in == pcm512x->pll_out) {
1623*4882a593Smuzhiyun 			dev_err(dev, "Error: pll-in == pll-out\n");
1624*4882a593Smuzhiyun 			ret = -EINVAL;
1625*4882a593Smuzhiyun 			goto err_clk;
1626*4882a593Smuzhiyun 		}
1627*4882a593Smuzhiyun 	}
1628*4882a593Smuzhiyun #endif
1629*4882a593Smuzhiyun 
1630*4882a593Smuzhiyun 	ret = devm_snd_soc_register_component(dev, &pcm512x_component_driver,
1631*4882a593Smuzhiyun 				    &pcm512x_dai, 1);
1632*4882a593Smuzhiyun 	if (ret != 0) {
1633*4882a593Smuzhiyun 		dev_err(dev, "Failed to register CODEC: %d\n", ret);
1634*4882a593Smuzhiyun 		goto err_pm;
1635*4882a593Smuzhiyun 	}
1636*4882a593Smuzhiyun 
1637*4882a593Smuzhiyun 	return 0;
1638*4882a593Smuzhiyun 
1639*4882a593Smuzhiyun err_pm:
1640*4882a593Smuzhiyun 	pm_runtime_disable(dev);
1641*4882a593Smuzhiyun err_clk:
1642*4882a593Smuzhiyun 	if (!IS_ERR(pcm512x->sclk))
1643*4882a593Smuzhiyun 		clk_disable_unprepare(pcm512x->sclk);
1644*4882a593Smuzhiyun err:
1645*4882a593Smuzhiyun 	regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies),
1646*4882a593Smuzhiyun 				     pcm512x->supplies);
1647*4882a593Smuzhiyun 	return ret;
1648*4882a593Smuzhiyun }
1649*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pcm512x_probe);
1650*4882a593Smuzhiyun 
pcm512x_remove(struct device * dev)1651*4882a593Smuzhiyun void pcm512x_remove(struct device *dev)
1652*4882a593Smuzhiyun {
1653*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
1654*4882a593Smuzhiyun 
1655*4882a593Smuzhiyun 	pm_runtime_disable(dev);
1656*4882a593Smuzhiyun 	if (!IS_ERR(pcm512x->sclk))
1657*4882a593Smuzhiyun 		clk_disable_unprepare(pcm512x->sclk);
1658*4882a593Smuzhiyun 	regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies),
1659*4882a593Smuzhiyun 			       pcm512x->supplies);
1660*4882a593Smuzhiyun }
1661*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pcm512x_remove);
1662*4882a593Smuzhiyun 
1663*4882a593Smuzhiyun #ifdef CONFIG_PM
pcm512x_suspend(struct device * dev)1664*4882a593Smuzhiyun static int pcm512x_suspend(struct device *dev)
1665*4882a593Smuzhiyun {
1666*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
1667*4882a593Smuzhiyun 	int ret;
1668*4882a593Smuzhiyun 
1669*4882a593Smuzhiyun 	ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
1670*4882a593Smuzhiyun 				 PCM512x_RQPD, PCM512x_RQPD);
1671*4882a593Smuzhiyun 	if (ret != 0) {
1672*4882a593Smuzhiyun 		dev_err(dev, "Failed to request power down: %d\n", ret);
1673*4882a593Smuzhiyun 		return ret;
1674*4882a593Smuzhiyun 	}
1675*4882a593Smuzhiyun 
1676*4882a593Smuzhiyun 	ret = regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies),
1677*4882a593Smuzhiyun 				     pcm512x->supplies);
1678*4882a593Smuzhiyun 	if (ret != 0) {
1679*4882a593Smuzhiyun 		dev_err(dev, "Failed to disable supplies: %d\n", ret);
1680*4882a593Smuzhiyun 		return ret;
1681*4882a593Smuzhiyun 	}
1682*4882a593Smuzhiyun 
1683*4882a593Smuzhiyun 	if (!IS_ERR(pcm512x->sclk))
1684*4882a593Smuzhiyun 		clk_disable_unprepare(pcm512x->sclk);
1685*4882a593Smuzhiyun 
1686*4882a593Smuzhiyun 	return 0;
1687*4882a593Smuzhiyun }
1688*4882a593Smuzhiyun 
pcm512x_resume(struct device * dev)1689*4882a593Smuzhiyun static int pcm512x_resume(struct device *dev)
1690*4882a593Smuzhiyun {
1691*4882a593Smuzhiyun 	struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
1692*4882a593Smuzhiyun 	int ret;
1693*4882a593Smuzhiyun 
1694*4882a593Smuzhiyun 	if (!IS_ERR(pcm512x->sclk)) {
1695*4882a593Smuzhiyun 		ret = clk_prepare_enable(pcm512x->sclk);
1696*4882a593Smuzhiyun 		if (ret != 0) {
1697*4882a593Smuzhiyun 			dev_err(dev, "Failed to enable SCLK: %d\n", ret);
1698*4882a593Smuzhiyun 			return ret;
1699*4882a593Smuzhiyun 		}
1700*4882a593Smuzhiyun 	}
1701*4882a593Smuzhiyun 
1702*4882a593Smuzhiyun 	ret = regulator_bulk_enable(ARRAY_SIZE(pcm512x->supplies),
1703*4882a593Smuzhiyun 				    pcm512x->supplies);
1704*4882a593Smuzhiyun 	if (ret != 0) {
1705*4882a593Smuzhiyun 		dev_err(dev, "Failed to enable supplies: %d\n", ret);
1706*4882a593Smuzhiyun 		return ret;
1707*4882a593Smuzhiyun 	}
1708*4882a593Smuzhiyun 
1709*4882a593Smuzhiyun 	regcache_cache_only(pcm512x->regmap, false);
1710*4882a593Smuzhiyun 	ret = regcache_sync(pcm512x->regmap);
1711*4882a593Smuzhiyun 	if (ret != 0) {
1712*4882a593Smuzhiyun 		dev_err(dev, "Failed to sync cache: %d\n", ret);
1713*4882a593Smuzhiyun 		return ret;
1714*4882a593Smuzhiyun 	}
1715*4882a593Smuzhiyun 
1716*4882a593Smuzhiyun 	ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
1717*4882a593Smuzhiyun 				 PCM512x_RQPD, 0);
1718*4882a593Smuzhiyun 	if (ret != 0) {
1719*4882a593Smuzhiyun 		dev_err(dev, "Failed to remove power down: %d\n", ret);
1720*4882a593Smuzhiyun 		return ret;
1721*4882a593Smuzhiyun 	}
1722*4882a593Smuzhiyun 
1723*4882a593Smuzhiyun 	return 0;
1724*4882a593Smuzhiyun }
1725*4882a593Smuzhiyun #endif
1726*4882a593Smuzhiyun 
1727*4882a593Smuzhiyun const struct dev_pm_ops pcm512x_pm_ops = {
1728*4882a593Smuzhiyun 	SET_RUNTIME_PM_OPS(pcm512x_suspend, pcm512x_resume, NULL)
1729*4882a593Smuzhiyun };
1730*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pcm512x_pm_ops);
1731*4882a593Smuzhiyun 
1732*4882a593Smuzhiyun MODULE_DESCRIPTION("ASoC PCM512x codec driver");
1733*4882a593Smuzhiyun MODULE_AUTHOR("Mark Brown <broonie@kernel.org>");
1734*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
1735