xref: /openbmc/u-boot/drivers/sound/max98090.c (revision e35171e9)
1*8cad63c7SSimon Glass // SPDX-License-Identifier: GPL-2.0+
2*8cad63c7SSimon Glass /*
3*8cad63c7SSimon Glass  * max98090.c -- MAX98090 ALSA SoC Audio driver
4*8cad63c7SSimon Glass  *
5*8cad63c7SSimon Glass  * Copyright 2011 Maxim Integrated Products
6*8cad63c7SSimon Glass  */
7*8cad63c7SSimon Glass 
8*8cad63c7SSimon Glass #include <common.h>
9*8cad63c7SSimon Glass #include <audio_codec.h>
10*8cad63c7SSimon Glass #include <div64.h>
11*8cad63c7SSimon Glass #include <dm.h>
12*8cad63c7SSimon Glass #include <i2c.h>
13*8cad63c7SSimon Glass #include <i2s.h>
14*8cad63c7SSimon Glass #include <sound.h>
15*8cad63c7SSimon Glass #include <asm/gpio.h>
16*8cad63c7SSimon Glass #include "maxim_codec.h"
17*8cad63c7SSimon Glass #include "max98090.h"
18*8cad63c7SSimon Glass 
19*8cad63c7SSimon Glass /*
20*8cad63c7SSimon Glass  * Sets hw params for max98090
21*8cad63c7SSimon Glass  *
22*8cad63c7SSimon Glass  * @priv: max98090 information pointer
23*8cad63c7SSimon Glass  * @rate: Sampling rate
24*8cad63c7SSimon Glass  * @bits_per_sample: Bits per sample
25*8cad63c7SSimon Glass  *
26*8cad63c7SSimon Glass  * @return -EIO for error, 0 for success.
27*8cad63c7SSimon Glass  */
max98090_hw_params(struct maxim_priv * priv,unsigned int rate,unsigned int bits_per_sample)28*8cad63c7SSimon Glass int max98090_hw_params(struct maxim_priv *priv, unsigned int rate,
29*8cad63c7SSimon Glass 		       unsigned int bits_per_sample)
30*8cad63c7SSimon Glass {
31*8cad63c7SSimon Glass 	int error;
32*8cad63c7SSimon Glass 	unsigned char value;
33*8cad63c7SSimon Glass 
34*8cad63c7SSimon Glass 	switch (bits_per_sample) {
35*8cad63c7SSimon Glass 	case 16:
36*8cad63c7SSimon Glass 		maxim_i2c_read(priv, M98090_REG_INTERFACE_FORMAT, &value);
37*8cad63c7SSimon Glass 		error = maxim_bic_or(priv, M98090_REG_INTERFACE_FORMAT,
38*8cad63c7SSimon Glass 				     M98090_WS_MASK, 0);
39*8cad63c7SSimon Glass 		maxim_i2c_read(priv, M98090_REG_INTERFACE_FORMAT, &value);
40*8cad63c7SSimon Glass 		break;
41*8cad63c7SSimon Glass 	default:
42*8cad63c7SSimon Glass 		debug("%s: Illegal bits per sample %d.\n",
43*8cad63c7SSimon Glass 		      __func__, bits_per_sample);
44*8cad63c7SSimon Glass 		return -1;
45*8cad63c7SSimon Glass 	}
46*8cad63c7SSimon Glass 
47*8cad63c7SSimon Glass 	/* Update filter mode */
48*8cad63c7SSimon Glass 	if (rate < 240000)
49*8cad63c7SSimon Glass 		error |= maxim_bic_or(priv, M98090_REG_FILTER_CONFIG,
50*8cad63c7SSimon Glass 				      M98090_MODE_MASK, 0);
51*8cad63c7SSimon Glass 	else
52*8cad63c7SSimon Glass 		error |= maxim_bic_or(priv, M98090_REG_FILTER_CONFIG,
53*8cad63c7SSimon Glass 				      M98090_MODE_MASK, M98090_MODE_MASK);
54*8cad63c7SSimon Glass 
55*8cad63c7SSimon Glass 	/* Update sample rate mode */
56*8cad63c7SSimon Glass 	if (rate < 50000)
57*8cad63c7SSimon Glass 		error |= maxim_bic_or(priv, M98090_REG_FILTER_CONFIG,
58*8cad63c7SSimon Glass 				      M98090_DHF_MASK, 0);
59*8cad63c7SSimon Glass 	else
60*8cad63c7SSimon Glass 		error |= maxim_bic_or(priv, M98090_REG_FILTER_CONFIG,
61*8cad63c7SSimon Glass 				      M98090_DHF_MASK, M98090_DHF_MASK);
62*8cad63c7SSimon Glass 
63*8cad63c7SSimon Glass 	if (error < 0) {
64*8cad63c7SSimon Glass 		debug("%s: Error setting hardware params.\n", __func__);
65*8cad63c7SSimon Glass 		return -EIO;
66*8cad63c7SSimon Glass 	}
67*8cad63c7SSimon Glass 	priv->rate = rate;
68*8cad63c7SSimon Glass 
69*8cad63c7SSimon Glass 	return 0;
70*8cad63c7SSimon Glass }
71*8cad63c7SSimon Glass 
72*8cad63c7SSimon Glass /*
73*8cad63c7SSimon Glass  * Configures Audio interface system clock for the given frequency
74*8cad63c7SSimon Glass  *
75*8cad63c7SSimon Glass  * @priv: max98090 information
76*8cad63c7SSimon Glass  * @freq: Sampling frequency in Hz
77*8cad63c7SSimon Glass  *
78*8cad63c7SSimon Glass  * @return -EIO for error, 0 for success.
79*8cad63c7SSimon Glass  */
max98090_set_sysclk(struct maxim_priv * priv,unsigned int freq)80*8cad63c7SSimon Glass int max98090_set_sysclk(struct maxim_priv *priv, unsigned int freq)
81*8cad63c7SSimon Glass {
82*8cad63c7SSimon Glass 	int error = 0;
83*8cad63c7SSimon Glass 
84*8cad63c7SSimon Glass 	/* Requested clock frequency is already setup */
85*8cad63c7SSimon Glass 	if (freq == priv->sysclk)
86*8cad63c7SSimon Glass 		return 0;
87*8cad63c7SSimon Glass 
88*8cad63c7SSimon Glass 	/* Setup clocks for slave mode, and using the PLL
89*8cad63c7SSimon Glass 	 * PSCLK = 0x01 (when master clk is 10MHz to 20MHz)
90*8cad63c7SSimon Glass 	 *	0x02 (when master clk is 20MHz to 40MHz)..
91*8cad63c7SSimon Glass 	 *	0x03 (when master clk is 40MHz to 60MHz)..
92*8cad63c7SSimon Glass 	 */
93*8cad63c7SSimon Glass 	if (freq >= 10000000 && freq < 20000000) {
94*8cad63c7SSimon Glass 		error = maxim_i2c_write(priv, M98090_REG_SYSTEM_CLOCK,
95*8cad63c7SSimon Glass 					M98090_PSCLK_DIV1);
96*8cad63c7SSimon Glass 	} else if (freq >= 20000000 && freq < 40000000) {
97*8cad63c7SSimon Glass 		error = maxim_i2c_write(priv, M98090_REG_SYSTEM_CLOCK,
98*8cad63c7SSimon Glass 					M98090_PSCLK_DIV2);
99*8cad63c7SSimon Glass 	} else if (freq >= 40000000 && freq < 60000000) {
100*8cad63c7SSimon Glass 		error = maxim_i2c_write(priv, M98090_REG_SYSTEM_CLOCK,
101*8cad63c7SSimon Glass 					M98090_PSCLK_DIV4);
102*8cad63c7SSimon Glass 	} else {
103*8cad63c7SSimon Glass 		debug("%s: Invalid master clock frequency\n", __func__);
104*8cad63c7SSimon Glass 		return -1;
105*8cad63c7SSimon Glass 	}
106*8cad63c7SSimon Glass 
107*8cad63c7SSimon Glass 	debug("%s: Clock at %uHz\n", __func__, freq);
108*8cad63c7SSimon Glass 
109*8cad63c7SSimon Glass 	if (error < 0)
110*8cad63c7SSimon Glass 		return -1;
111*8cad63c7SSimon Glass 
112*8cad63c7SSimon Glass 	priv->sysclk = freq;
113*8cad63c7SSimon Glass 
114*8cad63c7SSimon Glass 	return 0;
115*8cad63c7SSimon Glass }
116*8cad63c7SSimon Glass 
117*8cad63c7SSimon Glass /*
118*8cad63c7SSimon Glass  * Sets Max98090 I2S format
119*8cad63c7SSimon Glass  *
120*8cad63c7SSimon Glass  * @priv: max98090 information
121*8cad63c7SSimon Glass  * @fmt: i2S format - supports a subset of the options defined in i2s.h.
122*8cad63c7SSimon Glass  *
123*8cad63c7SSimon Glass  * @return -EIO for error, 0 for success.
124*8cad63c7SSimon Glass  */
max98090_set_fmt(struct maxim_priv * priv,int fmt)125*8cad63c7SSimon Glass int max98090_set_fmt(struct maxim_priv *priv, int fmt)
126*8cad63c7SSimon Glass {
127*8cad63c7SSimon Glass 	u8 regval = 0;
128*8cad63c7SSimon Glass 	int error = 0;
129*8cad63c7SSimon Glass 
130*8cad63c7SSimon Glass 	if (fmt == priv->fmt)
131*8cad63c7SSimon Glass 		return 0;
132*8cad63c7SSimon Glass 
133*8cad63c7SSimon Glass 	priv->fmt = fmt;
134*8cad63c7SSimon Glass 
135*8cad63c7SSimon Glass 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
136*8cad63c7SSimon Glass 	case SND_SOC_DAIFMT_CBS_CFS:
137*8cad63c7SSimon Glass 		/* Set to slave mode PLL - MAS mode off */
138*8cad63c7SSimon Glass 		error |= maxim_i2c_write(priv, M98090_REG_CLOCK_RATIO_NI_MSB,
139*8cad63c7SSimon Glass 					 0x00);
140*8cad63c7SSimon Glass 		error |= maxim_i2c_write(priv, M98090_REG_CLOCK_RATIO_NI_LSB,
141*8cad63c7SSimon Glass 					 0x00);
142*8cad63c7SSimon Glass 		error |= maxim_bic_or(priv, M98090_REG_CLOCK_MODE,
143*8cad63c7SSimon Glass 				      M98090_USE_M1_MASK, 0);
144*8cad63c7SSimon Glass 		break;
145*8cad63c7SSimon Glass 	case SND_SOC_DAIFMT_CBM_CFM:
146*8cad63c7SSimon Glass 		/* Set to master mode */
147*8cad63c7SSimon Glass 		debug("Master mode not supported\n");
148*8cad63c7SSimon Glass 		break;
149*8cad63c7SSimon Glass 	case SND_SOC_DAIFMT_CBS_CFM:
150*8cad63c7SSimon Glass 	case SND_SOC_DAIFMT_CBM_CFS:
151*8cad63c7SSimon Glass 	default:
152*8cad63c7SSimon Glass 		debug("%s: Clock mode unsupported\n", __func__);
153*8cad63c7SSimon Glass 		return -EINVAL;
154*8cad63c7SSimon Glass 	}
155*8cad63c7SSimon Glass 
156*8cad63c7SSimon Glass 	error |= maxim_i2c_write(priv, M98090_REG_MASTER_MODE, regval);
157*8cad63c7SSimon Glass 
158*8cad63c7SSimon Glass 	regval = 0;
159*8cad63c7SSimon Glass 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
160*8cad63c7SSimon Glass 	case SND_SOC_DAIFMT_I2S:
161*8cad63c7SSimon Glass 		regval |= M98090_DLY_MASK;
162*8cad63c7SSimon Glass 		break;
163*8cad63c7SSimon Glass 	case SND_SOC_DAIFMT_LEFT_J:
164*8cad63c7SSimon Glass 		break;
165*8cad63c7SSimon Glass 	case SND_SOC_DAIFMT_RIGHT_J:
166*8cad63c7SSimon Glass 		regval |= M98090_RJ_MASK;
167*8cad63c7SSimon Glass 		break;
168*8cad63c7SSimon Glass 	case SND_SOC_DAIFMT_DSP_A:
169*8cad63c7SSimon Glass 		/* Not supported mode */
170*8cad63c7SSimon Glass 	default:
171*8cad63c7SSimon Glass 		debug("%s: Unrecognized format.\n", __func__);
172*8cad63c7SSimon Glass 		return -EINVAL;
173*8cad63c7SSimon Glass 	}
174*8cad63c7SSimon Glass 
175*8cad63c7SSimon Glass 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
176*8cad63c7SSimon Glass 	case SND_SOC_DAIFMT_NB_NF:
177*8cad63c7SSimon Glass 		break;
178*8cad63c7SSimon Glass 	case SND_SOC_DAIFMT_NB_IF:
179*8cad63c7SSimon Glass 		regval |= M98090_WCI_MASK;
180*8cad63c7SSimon Glass 		break;
181*8cad63c7SSimon Glass 	case SND_SOC_DAIFMT_IB_NF:
182*8cad63c7SSimon Glass 		regval |= M98090_BCI_MASK;
183*8cad63c7SSimon Glass 		break;
184*8cad63c7SSimon Glass 	case SND_SOC_DAIFMT_IB_IF:
185*8cad63c7SSimon Glass 		regval |= M98090_BCI_MASK | M98090_WCI_MASK;
186*8cad63c7SSimon Glass 		break;
187*8cad63c7SSimon Glass 	default:
188*8cad63c7SSimon Glass 		debug("%s: Unrecognized inversion settings.\n", __func__);
189*8cad63c7SSimon Glass 		return -EINVAL;
190*8cad63c7SSimon Glass 	}
191*8cad63c7SSimon Glass 
192*8cad63c7SSimon Glass 	error |= maxim_i2c_write(priv, M98090_REG_INTERFACE_FORMAT, regval);
193*8cad63c7SSimon Glass 
194*8cad63c7SSimon Glass 	if (error < 0) {
195*8cad63c7SSimon Glass 		debug("%s: Error setting i2s format.\n", __func__);
196*8cad63c7SSimon Glass 		return -EIO;
197*8cad63c7SSimon Glass 	}
198*8cad63c7SSimon Glass 
199*8cad63c7SSimon Glass 	return 0;
200*8cad63c7SSimon Glass }
201*8cad63c7SSimon Glass 
202*8cad63c7SSimon Glass /*
203*8cad63c7SSimon Glass  * resets the audio codec
204*8cad63c7SSimon Glass  *
205*8cad63c7SSimon Glass  * @priv: max98090 information
206*8cad63c7SSimon Glass  * @return -EIO for error, 0 for success.
207*8cad63c7SSimon Glass  */
max98090_reset(struct maxim_priv * priv)208*8cad63c7SSimon Glass static int max98090_reset(struct maxim_priv *priv)
209*8cad63c7SSimon Glass {
210*8cad63c7SSimon Glass 	int ret;
211*8cad63c7SSimon Glass 
212*8cad63c7SSimon Glass 	/*
213*8cad63c7SSimon Glass 	 * Gracefully reset the DSP core and the codec hardware in a proper
214*8cad63c7SSimon Glass 	 * sequence.
215*8cad63c7SSimon Glass 	 */
216*8cad63c7SSimon Glass 	ret = maxim_i2c_write(priv, M98090_REG_SOFTWARE_RESET,
217*8cad63c7SSimon Glass 			      M98090_SWRESET_MASK);
218*8cad63c7SSimon Glass 	if (ret != 0) {
219*8cad63c7SSimon Glass 		debug("%s: Failed to reset DSP: %d\n", __func__, ret);
220*8cad63c7SSimon Glass 		return ret;
221*8cad63c7SSimon Glass 	}
222*8cad63c7SSimon Glass 	mdelay(20);
223*8cad63c7SSimon Glass 
224*8cad63c7SSimon Glass 	return 0;
225*8cad63c7SSimon Glass }
226*8cad63c7SSimon Glass 
227*8cad63c7SSimon Glass /*
228*8cad63c7SSimon Glass  * Initialise max98090 codec device
229*8cad63c7SSimon Glass  *
230*8cad63c7SSimon Glass  * @priv: max98090 information
231*8cad63c7SSimon Glass  *
232*8cad63c7SSimon Glass  * @return -EIO for error, 0 for success.
233*8cad63c7SSimon Glass  */
max98090_device_init(struct maxim_priv * priv)234*8cad63c7SSimon Glass int max98090_device_init(struct maxim_priv *priv)
235*8cad63c7SSimon Glass {
236*8cad63c7SSimon Glass 	unsigned char id;
237*8cad63c7SSimon Glass 	int error = 0;
238*8cad63c7SSimon Glass 
239*8cad63c7SSimon Glass 	/* reset the codec, the DSP core, and disable all interrupts */
240*8cad63c7SSimon Glass 	error = max98090_reset(priv);
241*8cad63c7SSimon Glass 	if (error != 0) {
242*8cad63c7SSimon Glass 		debug("Reset\n");
243*8cad63c7SSimon Glass 		return error;
244*8cad63c7SSimon Glass 	}
245*8cad63c7SSimon Glass 
246*8cad63c7SSimon Glass 	/* initialize private data */
247*8cad63c7SSimon Glass 	priv->sysclk = -1U;
248*8cad63c7SSimon Glass 	priv->rate = -1U;
249*8cad63c7SSimon Glass 	priv->fmt = -1U;
250*8cad63c7SSimon Glass 
251*8cad63c7SSimon Glass 	error = maxim_i2c_read(priv, M98090_REG_REVISION_ID, &id);
252*8cad63c7SSimon Glass 	if (error < 0) {
253*8cad63c7SSimon Glass 		debug("%s: Failure reading hardware revision: %d\n",
254*8cad63c7SSimon Glass 		      __func__, id);
255*8cad63c7SSimon Glass 		return -EIO;
256*8cad63c7SSimon Glass 	}
257*8cad63c7SSimon Glass 	debug("%s: Hardware revision: %d\n", __func__, id);
258*8cad63c7SSimon Glass 
259*8cad63c7SSimon Glass 	return 0;
260*8cad63c7SSimon Glass }
261*8cad63c7SSimon Glass 
max98090_setup_interface(struct maxim_priv * priv)262*8cad63c7SSimon Glass static int max98090_setup_interface(struct maxim_priv *priv)
263*8cad63c7SSimon Glass {
264*8cad63c7SSimon Glass 	unsigned char id;
265*8cad63c7SSimon Glass 	int error;
266*8cad63c7SSimon Glass 
267*8cad63c7SSimon Glass 	/* Reading interrupt status to clear them */
268*8cad63c7SSimon Glass 	error = maxim_i2c_read(priv, M98090_REG_DEVICE_STATUS, &id);
269*8cad63c7SSimon Glass 
270*8cad63c7SSimon Glass 	error |= maxim_i2c_write(priv, M98090_REG_DAC_CONTROL,
271*8cad63c7SSimon Glass 				 M98090_DACHP_MASK);
272*8cad63c7SSimon Glass 	error |= maxim_i2c_write(priv, M98090_REG_BIAS_CONTROL,
273*8cad63c7SSimon Glass 				 M98090_VCM_MODE_MASK);
274*8cad63c7SSimon Glass 
275*8cad63c7SSimon Glass 	error |= maxim_i2c_write(priv, M98090_REG_LEFT_SPK_MIXER, 0x1);
276*8cad63c7SSimon Glass 	error |= maxim_i2c_write(priv, M98090_REG_RIGHT_SPK_MIXER, 0x2);
277*8cad63c7SSimon Glass 
278*8cad63c7SSimon Glass 	error |= maxim_i2c_write(priv, M98090_REG_LEFT_SPK_VOLUME, 0x25);
279*8cad63c7SSimon Glass 	error |= maxim_i2c_write(priv, M98090_REG_RIGHT_SPK_VOLUME, 0x25);
280*8cad63c7SSimon Glass 
281*8cad63c7SSimon Glass 	error |= maxim_i2c_write(priv, M98090_REG_CLOCK_RATIO_NI_MSB, 0x0);
282*8cad63c7SSimon Glass 	error |= maxim_i2c_write(priv, M98090_REG_CLOCK_RATIO_NI_LSB, 0x0);
283*8cad63c7SSimon Glass 	error |= maxim_i2c_write(priv, M98090_REG_MASTER_MODE, 0x0);
284*8cad63c7SSimon Glass 	error |= maxim_i2c_write(priv, M98090_REG_INTERFACE_FORMAT, 0x0);
285*8cad63c7SSimon Glass 	error |= maxim_i2c_write(priv, M98090_REG_IO_CONFIGURATION,
286*8cad63c7SSimon Glass 				 M98090_SDIEN_MASK);
287*8cad63c7SSimon Glass 	error |= maxim_i2c_write(priv, M98090_REG_DEVICE_SHUTDOWN,
288*8cad63c7SSimon Glass 				 M98090_SHDNN_MASK);
289*8cad63c7SSimon Glass 	error |= maxim_i2c_write(priv, M98090_REG_OUTPUT_ENABLE,
290*8cad63c7SSimon Glass 				 M98090_HPREN_MASK | M98090_HPLEN_MASK |
291*8cad63c7SSimon Glass 				 M98090_SPREN_MASK | M98090_SPLEN_MASK |
292*8cad63c7SSimon Glass 				 M98090_DAREN_MASK | M98090_DALEN_MASK);
293*8cad63c7SSimon Glass 	error |= maxim_i2c_write(priv, M98090_REG_IO_CONFIGURATION,
294*8cad63c7SSimon Glass 				 M98090_SDOEN_MASK | M98090_SDIEN_MASK);
295*8cad63c7SSimon Glass 
296*8cad63c7SSimon Glass 	if (error < 0)
297*8cad63c7SSimon Glass 		return -EIO;
298*8cad63c7SSimon Glass 
299*8cad63c7SSimon Glass 	return 0;
300*8cad63c7SSimon Glass }
301*8cad63c7SSimon Glass 
max98090_do_init(struct maxim_priv * priv,int sampling_rate,int mclk_freq,int bits_per_sample)302*8cad63c7SSimon Glass static int max98090_do_init(struct maxim_priv *priv, int sampling_rate,
303*8cad63c7SSimon Glass 			    int mclk_freq, int bits_per_sample)
304*8cad63c7SSimon Glass {
305*8cad63c7SSimon Glass 	int ret = 0;
306*8cad63c7SSimon Glass 
307*8cad63c7SSimon Glass 	ret = max98090_setup_interface(priv);
308*8cad63c7SSimon Glass 	if (ret < 0) {
309*8cad63c7SSimon Glass 		debug("%s: max98090 setup interface failed\n", __func__);
310*8cad63c7SSimon Glass 		return ret;
311*8cad63c7SSimon Glass 	}
312*8cad63c7SSimon Glass 
313*8cad63c7SSimon Glass 	ret = max98090_set_sysclk(priv, mclk_freq);
314*8cad63c7SSimon Glass 	if (ret < 0) {
315*8cad63c7SSimon Glass 		debug("%s: max98090 codec set sys clock failed\n", __func__);
316*8cad63c7SSimon Glass 		return ret;
317*8cad63c7SSimon Glass 	}
318*8cad63c7SSimon Glass 
319*8cad63c7SSimon Glass 	ret = max98090_hw_params(priv, sampling_rate, bits_per_sample);
320*8cad63c7SSimon Glass 
321*8cad63c7SSimon Glass 	if (ret == 0) {
322*8cad63c7SSimon Glass 		ret = max98090_set_fmt(priv, SND_SOC_DAIFMT_I2S |
323*8cad63c7SSimon Glass 				       SND_SOC_DAIFMT_NB_NF |
324*8cad63c7SSimon Glass 				       SND_SOC_DAIFMT_CBS_CFS);
325*8cad63c7SSimon Glass 	}
326*8cad63c7SSimon Glass 
327*8cad63c7SSimon Glass 	return ret;
328*8cad63c7SSimon Glass }
329*8cad63c7SSimon Glass 
max98090_set_params(struct udevice * dev,int interface,int rate,int mclk_freq,int bits_per_sample,uint channels)330*8cad63c7SSimon Glass static int max98090_set_params(struct udevice *dev, int interface, int rate,
331*8cad63c7SSimon Glass 			       int mclk_freq, int bits_per_sample,
332*8cad63c7SSimon Glass 			       uint channels)
333*8cad63c7SSimon Glass {
334*8cad63c7SSimon Glass 	struct maxim_priv *priv = dev_get_priv(dev);
335*8cad63c7SSimon Glass 
336*8cad63c7SSimon Glass 	return max98090_do_init(priv, rate, mclk_freq, bits_per_sample);
337*8cad63c7SSimon Glass }
338*8cad63c7SSimon Glass 
max98090_probe(struct udevice * dev)339*8cad63c7SSimon Glass static int max98090_probe(struct udevice *dev)
340*8cad63c7SSimon Glass {
341*8cad63c7SSimon Glass 	struct maxim_priv *priv = dev_get_priv(dev);
342*8cad63c7SSimon Glass 	int ret;
343*8cad63c7SSimon Glass 
344*8cad63c7SSimon Glass 	priv->dev = dev;
345*8cad63c7SSimon Glass 	ret = max98090_device_init(priv);
346*8cad63c7SSimon Glass 	if (ret < 0) {
347*8cad63c7SSimon Glass 		debug("%s: max98090 codec chip init failed\n", __func__);
348*8cad63c7SSimon Glass 		return ret;
349*8cad63c7SSimon Glass 	}
350*8cad63c7SSimon Glass 
351*8cad63c7SSimon Glass 	return 0;
352*8cad63c7SSimon Glass }
353*8cad63c7SSimon Glass 
354*8cad63c7SSimon Glass static const struct audio_codec_ops max98090_ops = {
355*8cad63c7SSimon Glass 	.set_params	= max98090_set_params,
356*8cad63c7SSimon Glass };
357*8cad63c7SSimon Glass 
358*8cad63c7SSimon Glass static const struct udevice_id max98090_ids[] = {
359*8cad63c7SSimon Glass 	{ .compatible = "maxim,max98090" },
360*8cad63c7SSimon Glass 	{ }
361*8cad63c7SSimon Glass };
362*8cad63c7SSimon Glass 
363*8cad63c7SSimon Glass U_BOOT_DRIVER(max98090) = {
364*8cad63c7SSimon Glass 	.name		= "max98090",
365*8cad63c7SSimon Glass 	.id		= UCLASS_AUDIO_CODEC,
366*8cad63c7SSimon Glass 	.of_match	= max98090_ids,
367*8cad63c7SSimon Glass 	.probe		= max98090_probe,
368*8cad63c7SSimon Glass 	.ops		= &max98090_ops,
369*8cad63c7SSimon Glass 	.priv_auto_alloc_size	= sizeof(struct maxim_priv),
370*8cad63c7SSimon Glass };
371