Blame view

drivers/sound/max98095.c 11.2 KB
e9f66f4f5   Simon Glass   dm: sound: Fix li...
1
  // SPDX-License-Identifier: GPL-2.0+
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
2
3
4
5
6
  /*
   * max98095.c -- MAX98095 ALSA SoC Audio driver
   *
   * Copyright 2011 Maxim Integrated Products
   *
e9f66f4f5   Simon Glass   dm: sound: Fix li...
7
   * Modified for U-Boot by R. Chandrasekar (rcsekar@samsung.com)
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
8
   */
150c5afe5   Simon Glass   dm: gpio: Add liv...
9
10
  
  #include <common.h>
d6cadd591   Simon Glass   dm: sound: Add co...
11
12
  #include <audio_codec.h>
  #include <dm.h>
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
13
14
15
16
  #include <div64.h>
  #include <fdtdec.h>
  #include <i2c.h>
  #include <sound.h>
a1efd49ee   Simon Glass   dm: sound: Fix up...
17
  #include <asm/gpio.h>
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
18
19
  #include "i2s.h"
  #include "max98095.h"
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
20
21
22
23
24
  /* Index 0 is reserved. */
  int rate_table[] = {0, 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000,
  		88200, 96000};
  
  /*
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
   * codec mclk clock divider coefficients based on sampling rate
   *
   * @param rate sampling rate
   * @param value address of indexvalue to be stored
   *
   * @return	0 for success or negative error code.
   */
  static int rate_value(int rate, u8 *value)
  {
  	int i;
  
  	for (i = 1; i < ARRAY_SIZE(rate_table); i++) {
  		if (rate_table[i] >= rate) {
  			*value = i;
  			return 0;
  		}
  	}
  	*value = 1;
bc58184ec   Simon Glass   dm: sound: max980...
43
  	return -EINVAL;
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
44
45
46
47
48
  }
  
  /*
   * Sets hw params for max98095
   *
a832a3e36   Simon Glass   dm: sound: max980...
49
   * @param priv		max98095 information pointer
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
50
51
52
   * @param rate		Sampling rate
   * @param bits_per_sample	Bits per sample
   *
bc58184ec   Simon Glass   dm: sound: max980...
53
   * @return	0 for success or negative error code.
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
54
   */
0ab6f0b35   Simon Glass   dm: sound: Move c...
55
  static int max98095_hw_params(struct maxim_priv *priv,
6b40852da   Dani Krishna Mohan   Sound: MAX98095: ...
56
57
  			      enum en_max_audio_interface aif_id,
  			      unsigned int rate, unsigned int bits_per_sample)
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
58
59
60
  {
  	u8 regval;
  	int error;
6b40852da   Dani Krishna Mohan   Sound: MAX98095: ...
61
62
63
64
65
66
67
68
69
70
71
72
73
  	unsigned short M98095_DAI_CLKMODE;
  	unsigned short M98095_DAI_FORMAT;
  	unsigned short M98095_DAI_FILTERS;
  
  	if (aif_id == AIF1) {
  		M98095_DAI_CLKMODE = M98095_027_DAI1_CLKMODE;
  		M98095_DAI_FORMAT = M98095_02A_DAI1_FORMAT;
  		M98095_DAI_FILTERS = M98095_02E_DAI1_FILTERS;
  	} else {
  		M98095_DAI_CLKMODE = M98095_031_DAI2_CLKMODE;
  		M98095_DAI_FORMAT = M98095_034_DAI2_FORMAT;
  		M98095_DAI_FILTERS = M98095_038_DAI2_FILTERS;
  	}
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
74
75
76
  
  	switch (bits_per_sample) {
  	case 16:
0ab6f0b35   Simon Glass   dm: sound: Move c...
77
  		error = maxim_bic_or(priv, M98095_DAI_FORMAT, M98095_DAI_WS, 0);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
78
79
  		break;
  	case 24:
0ab6f0b35   Simon Glass   dm: sound: Move c...
80
81
  		error = maxim_bic_or(priv, M98095_DAI_FORMAT, M98095_DAI_WS,
  				     M98095_DAI_WS);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
82
83
84
85
  		break;
  	default:
  		debug("%s: Illegal bits per sample %d.
  ",
6b40852da   Dani Krishna Mohan   Sound: MAX98095: ...
86
  		      __func__, bits_per_sample);
bc58184ec   Simon Glass   dm: sound: max980...
87
  		return -EINVAL;
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
88
89
90
91
92
  	}
  
  	if (rate_value(rate, &regval)) {
  		debug("%s: Failed to set sample rate to %d.
  ",
6b40852da   Dani Krishna Mohan   Sound: MAX98095: ...
93
  		      __func__, rate);
bc58184ec   Simon Glass   dm: sound: max980...
94
  		return -EINVAL;
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
95
  	}
a832a3e36   Simon Glass   dm: sound: max980...
96
  	priv->rate = rate;
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
97

0ab6f0b35   Simon Glass   dm: sound: Move c...
98
  	error |= maxim_bic_or(priv, M98095_DAI_CLKMODE, M98095_CLKMODE_MASK,
a832a3e36   Simon Glass   dm: sound: max980...
99
  				 regval);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
100
101
102
  
  	/* Update sample rate mode */
  	if (rate < 50000)
0ab6f0b35   Simon Glass   dm: sound: Move c...
103
  		error |= maxim_bic_or(priv, M98095_DAI_FILTERS,
a832a3e36   Simon Glass   dm: sound: max980...
104
  					 M98095_DAI_DHF, 0);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
105
  	else
0ab6f0b35   Simon Glass   dm: sound: Move c...
106
  		error |= maxim_bic_or(priv, M98095_DAI_FILTERS,
a832a3e36   Simon Glass   dm: sound: max980...
107
  					 M98095_DAI_DHF, M98095_DAI_DHF);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
108
109
110
111
  
  	if (error < 0) {
  		debug("%s: Error setting hardware params.
  ", __func__);
bc58184ec   Simon Glass   dm: sound: max980...
112
  		return -EIO;
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
113
114
115
116
117
118
119
120
  	}
  
  	return 0;
  }
  
  /*
   * Configures Audio interface system clock for the given frequency
   *
a832a3e36   Simon Glass   dm: sound: max980...
121
   * @param priv		max98095 information
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
122
123
   * @param freq		Sampling frequency in Hz
   *
bc58184ec   Simon Glass   dm: sound: max980...
124
   * @return	0 for success or negative error code.
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
125
   */
0ab6f0b35   Simon Glass   dm: sound: Move c...
126
  static int max98095_set_sysclk(struct maxim_priv *priv, unsigned int freq)
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
127
128
129
130
  {
  	int error = 0;
  
  	/* Requested clock frequency is already setup */
a832a3e36   Simon Glass   dm: sound: max980...
131
  	if (freq == priv->sysclk)
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
132
133
134
135
136
137
138
139
  		return 0;
  
  	/* Setup clocks for slave mode, and using the PLL
  	 * PSCLK = 0x01 (when master clk is 10MHz to 20MHz)
  	 *	0x02 (when master clk is 20MHz to 40MHz)..
  	 *	0x03 (when master clk is 40MHz to 60MHz)..
  	 */
  	if ((freq >= 10000000) && (freq < 20000000)) {
0ab6f0b35   Simon Glass   dm: sound: Move c...
140
  		error = maxim_i2c_write(priv, M98095_026_SYS_CLK, 0x10);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
141
  	} else if ((freq >= 20000000) && (freq < 40000000)) {
0ab6f0b35   Simon Glass   dm: sound: Move c...
142
  		error = maxim_i2c_write(priv, M98095_026_SYS_CLK, 0x20);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
143
  	} else if ((freq >= 40000000) && (freq < 60000000)) {
0ab6f0b35   Simon Glass   dm: sound: Move c...
144
  		error = maxim_i2c_write(priv, M98095_026_SYS_CLK, 0x30);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
145
146
147
  	} else {
  		debug("%s: Invalid master clock frequency
  ", __func__);
bc58184ec   Simon Glass   dm: sound: max980...
148
  		return -EINVAL;
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
149
150
151
152
153
154
  	}
  
  	debug("%s: Clock at %uHz
  ", __func__, freq);
  
  	if (error < 0)
bc58184ec   Simon Glass   dm: sound: max980...
155
  		return -EIO;
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
156

a832a3e36   Simon Glass   dm: sound: max980...
157
  	priv->sysclk = freq;
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
158
159
160
161
162
163
  	return 0;
  }
  
  /*
   * Sets Max98095 I2S format
   *
a832a3e36   Simon Glass   dm: sound: max980...
164
   * @param priv		max98095 information
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
165
166
167
   * @param fmt		i2S format - supports a subset of the options defined
   *			in i2s.h.
   *
bc58184ec   Simon Glass   dm: sound: max980...
168
   * @return	0 for success or negative error code.
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
169
   */
0ab6f0b35   Simon Glass   dm: sound: Move c...
170
  static int max98095_set_fmt(struct maxim_priv *priv, int fmt,
6b40852da   Dani Krishna Mohan   Sound: MAX98095: ...
171
  			    enum en_max_audio_interface aif_id)
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
172
173
174
  {
  	u8 regval = 0;
  	int error = 0;
6b40852da   Dani Krishna Mohan   Sound: MAX98095: ...
175
176
177
178
  	unsigned short M98095_DAI_CLKCFG_HI;
  	unsigned short M98095_DAI_CLKCFG_LO;
  	unsigned short M98095_DAI_FORMAT;
  	unsigned short M98095_DAI_CLOCK;
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
179

a832a3e36   Simon Glass   dm: sound: max980...
180
  	if (fmt == priv->fmt)
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
181
  		return 0;
a832a3e36   Simon Glass   dm: sound: max980...
182
  	priv->fmt = fmt;
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
183

6b40852da   Dani Krishna Mohan   Sound: MAX98095: ...
184
185
186
187
188
189
190
191
192
193
194
  	if (aif_id == AIF1) {
  		M98095_DAI_CLKCFG_HI = M98095_028_DAI1_CLKCFG_HI;
  		M98095_DAI_CLKCFG_LO = M98095_029_DAI1_CLKCFG_LO;
  		M98095_DAI_FORMAT = M98095_02A_DAI1_FORMAT;
  		M98095_DAI_CLOCK = M98095_02B_DAI1_CLOCK;
  	} else {
  		M98095_DAI_CLKCFG_HI = M98095_032_DAI2_CLKCFG_HI;
  		M98095_DAI_CLKCFG_LO = M98095_033_DAI2_CLKCFG_LO;
  		M98095_DAI_FORMAT = M98095_034_DAI2_FORMAT;
  		M98095_DAI_CLOCK = M98095_035_DAI2_CLOCK;
  	}
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
195
196
197
  	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
  	case SND_SOC_DAIFMT_CBS_CFS:
  		/* Slave mode PLL */
0ab6f0b35   Simon Glass   dm: sound: Move c...
198
199
  		error |= maxim_i2c_write(priv, M98095_DAI_CLKCFG_HI, 0x80);
  		error |= maxim_i2c_write(priv, M98095_DAI_CLKCFG_LO, 0x00);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
200
201
202
203
204
205
206
207
208
209
  		break;
  	case SND_SOC_DAIFMT_CBM_CFM:
  		/* Set to master mode */
  		regval |= M98095_DAI_MAS;
  		break;
  	case SND_SOC_DAIFMT_CBS_CFM:
  	case SND_SOC_DAIFMT_CBM_CFS:
  	default:
  		debug("%s: Clock mode unsupported
  ", __func__);
bc58184ec   Simon Glass   dm: sound: max980...
210
  		return -EINVAL;
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
211
212
213
214
215
216
217
218
219
220
221
  	}
  
  	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  	case SND_SOC_DAIFMT_I2S:
  		regval |= M98095_DAI_DLY;
  		break;
  	case SND_SOC_DAIFMT_LEFT_J:
  		break;
  	default:
  		debug("%s: Unrecognized format.
  ", __func__);
bc58184ec   Simon Glass   dm: sound: max980...
222
  		return -EINVAL;
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
  	}
  
  	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
  	case SND_SOC_DAIFMT_NB_NF:
  		break;
  	case SND_SOC_DAIFMT_NB_IF:
  		regval |= M98095_DAI_WCI;
  		break;
  	case SND_SOC_DAIFMT_IB_NF:
  		regval |= M98095_DAI_BCI;
  		break;
  	case SND_SOC_DAIFMT_IB_IF:
  		regval |= M98095_DAI_BCI | M98095_DAI_WCI;
  		break;
  	default:
  		debug("%s: Unrecognized inversion settings.
  ", __func__);
bc58184ec   Simon Glass   dm: sound: max980...
240
  		return -EINVAL;
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
241
  	}
0ab6f0b35   Simon Glass   dm: sound: Move c...
242
  	error |= maxim_bic_or(priv, M98095_DAI_FORMAT,
a832a3e36   Simon Glass   dm: sound: max980...
243
244
  				 M98095_DAI_MAS | M98095_DAI_DLY |
  				 M98095_DAI_BCI | M98095_DAI_WCI, regval);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
245

0ab6f0b35   Simon Glass   dm: sound: Move c...
246
  	error |= maxim_i2c_write(priv, M98095_DAI_CLOCK, M98095_DAI_BSEL64);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
247
248
249
250
  
  	if (error < 0) {
  		debug("%s: Error setting i2s format.
  ", __func__);
bc58184ec   Simon Glass   dm: sound: max980...
251
  		return -EIO;
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
252
253
254
255
256
257
258
259
  	}
  
  	return 0;
  }
  
  /*
   * resets the audio codec
   *
a832a3e36   Simon Glass   dm: sound: max980...
260
   * @param priv	Private data for driver
bc58184ec   Simon Glass   dm: sound: max980...
261
   * @return	0 for success or negative error code.
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
262
   */
0ab6f0b35   Simon Glass   dm: sound: Move c...
263
  static int max98095_reset(struct maxim_priv *priv)
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
264
265
266
267
268
269
270
  {
  	int i, ret;
  
  	/*
  	 * Gracefully reset the DSP core and the codec hardware in a proper
  	 * sequence.
  	 */
0ab6f0b35   Simon Glass   dm: sound: Move c...
271
  	ret = maxim_i2c_write(priv, M98095_00F_HOST_CFG, 0);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
272
273
274
275
276
  	if (ret != 0) {
  		debug("%s: Failed to reset DSP: %d
  ", __func__, ret);
  		return ret;
  	}
0ab6f0b35   Simon Glass   dm: sound: Move c...
277
  	ret = maxim_i2c_write(priv, M98095_097_PWR_SYS, 0);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
278
279
280
281
282
283
284
285
286
287
288
  	if (ret != 0) {
  		debug("%s: Failed to reset codec: %d
  ", __func__, ret);
  		return ret;
  	}
  
  	/*
  	 * Reset to hardware default for registers, as there is not a soft
  	 * reset hardware control register.
  	 */
  	for (i = M98095_010_HOST_INT_CFG; i < M98095_REG_MAX_CACHED; i++) {
0ab6f0b35   Simon Glass   dm: sound: Move c...
289
  		ret = maxim_i2c_write(priv, i, 0);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
290
291
292
293
294
295
296
297
298
299
300
301
302
  		if (ret < 0) {
  			debug("%s: Failed to reset: %d
  ", __func__, ret);
  			return ret;
  		}
  	}
  
  	return 0;
  }
  
  /*
   * Intialise max98095 codec device
   *
a832a3e36   Simon Glass   dm: sound: max980...
303
   * @param priv		max98095 information
bc58184ec   Simon Glass   dm: sound: max980...
304
   * @return	0 for success or negative error code.
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
305
   */
0ab6f0b35   Simon Glass   dm: sound: Move c...
306
  static int max98095_device_init(struct maxim_priv *priv)
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
307
308
  {
  	unsigned char id;
bc58184ec   Simon Glass   dm: sound: max980...
309
  	int ret;
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
310
311
  
  	/* reset the codec, the DSP core, and disable all interrupts */
bc58184ec   Simon Glass   dm: sound: max980...
312
313
  	ret = max98095_reset(priv);
  	if (ret != 0) {
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
314
315
  		debug("Reset
  ");
bc58184ec   Simon Glass   dm: sound: max980...
316
  		return ret;
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
317
318
319
  	}
  
  	/* initialize private data */
a832a3e36   Simon Glass   dm: sound: max980...
320
321
322
  	priv->sysclk = -1U;
  	priv->rate = -1U;
  	priv->fmt = -1U;
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
323

bc58184ec   Simon Glass   dm: sound: max980...
324
325
  	ret = maxim_i2c_read(priv, M98095_0FF_REV_ID, &id);
  	if (ret < 0) {
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
326
327
  		debug("%s: Failure reading hardware revision: %d
  ",
6b40852da   Dani Krishna Mohan   Sound: MAX98095: ...
328
  		      __func__, id);
bc58184ec   Simon Glass   dm: sound: max980...
329
  		return ret;
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
330
331
332
  	}
  	debug("%s: Hardware revision: %c
  ", __func__, (id - 0x40) + 'A');
82a27d2c8   Simon Glass   dm: sound: max980...
333
334
  	return 0;
  }
0ab6f0b35   Simon Glass   dm: sound: Move c...
335
  static int max98095_setup_interface(struct maxim_priv *priv,
82a27d2c8   Simon Glass   dm: sound: max980...
336
337
338
  				    enum en_max_audio_interface aif_id)
  {
  	int error;
0ab6f0b35   Simon Glass   dm: sound: Move c...
339
  	error = maxim_i2c_write(priv, M98095_097_PWR_SYS, M98095_PWRSV);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
340
341
342
343
344
  
  	/*
  	 * initialize registers to hardware default configuring audio
  	 * interface2 to DAC
  	 */
6b40852da   Dani Krishna Mohan   Sound: MAX98095: ...
345
  	if (aif_id == AIF1)
0ab6f0b35   Simon Glass   dm: sound: Move c...
346
  		error |= maxim_i2c_write(priv, M98095_048_MIX_DAC_LR,
6b40852da   Dani Krishna Mohan   Sound: MAX98095: ...
347
348
349
  					    M98095_DAI1L_TO_DACL |
  					    M98095_DAI1R_TO_DACR);
  	else
0ab6f0b35   Simon Glass   dm: sound: Move c...
350
  		error |= maxim_i2c_write(priv, M98095_048_MIX_DAC_LR,
6b40852da   Dani Krishna Mohan   Sound: MAX98095: ...
351
352
  					    M98095_DAI2M_TO_DACL |
  					    M98095_DAI2M_TO_DACR);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
353

0ab6f0b35   Simon Glass   dm: sound: Move c...
354
  	error |= maxim_i2c_write(priv, M98095_092_PWR_EN_OUT,
6b40852da   Dani Krishna Mohan   Sound: MAX98095: ...
355
  				    M98095_SPK_SPREADSPECTRUM);
0ab6f0b35   Simon Glass   dm: sound: Move c...
356
  	error |= maxim_i2c_write(priv, M98095_04E_CFG_HP, M98095_HPNORMAL);
6b40852da   Dani Krishna Mohan   Sound: MAX98095: ...
357
  	if (aif_id == AIF1)
0ab6f0b35   Simon Glass   dm: sound: Move c...
358
  		error |= maxim_i2c_write(priv, M98095_02C_DAI1_IOCFG,
6b40852da   Dani Krishna Mohan   Sound: MAX98095: ...
359
360
  					    M98095_S1NORMAL | M98095_SDATA);
  	else
0ab6f0b35   Simon Glass   dm: sound: Move c...
361
  		error |= maxim_i2c_write(priv, M98095_036_DAI2_IOCFG,
6b40852da   Dani Krishna Mohan   Sound: MAX98095: ...
362
  					    M98095_S2NORMAL | M98095_SDATA);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
363
364
  
  	/* take the codec out of the shut down */
0ab6f0b35   Simon Glass   dm: sound: Move c...
365
  	error |= maxim_bic_or(priv, M98095_097_PWR_SYS, M98095_SHDNRUN,
a832a3e36   Simon Glass   dm: sound: max980...
366
367
368
369
370
  				 M98095_SHDNRUN);
  	/*
  	 * route DACL and DACR output to HO and Speakers
  	 * Ordering: DACL, DACR, DACL, DACR
  	 */
0ab6f0b35   Simon Glass   dm: sound: Move c...
371
372
373
374
  	error |= maxim_i2c_write(priv, M98095_050_MIX_SPK_LEFT, 0x01);
  	error |= maxim_i2c_write(priv, M98095_051_MIX_SPK_RIGHT, 0x01);
  	error |= maxim_i2c_write(priv, M98095_04C_MIX_HP_LEFT, 0x01);
  	error |= maxim_i2c_write(priv, M98095_04D_MIX_HP_RIGHT, 0x01);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
375
376
  
  	/* power Enable */
0ab6f0b35   Simon Glass   dm: sound: Move c...
377
  	error |= maxim_i2c_write(priv, M98095_091_PWR_EN_OUT, 0xF3);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
378
379
  
  	/* set Volume */
0ab6f0b35   Simon Glass   dm: sound: Move c...
380
381
382
383
  	error |= maxim_i2c_write(priv, M98095_064_LVL_HP_L, 15);
  	error |= maxim_i2c_write(priv, M98095_065_LVL_HP_R, 15);
  	error |= maxim_i2c_write(priv, M98095_067_LVL_SPK_L, 16);
  	error |= maxim_i2c_write(priv, M98095_068_LVL_SPK_R, 16);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
384
385
  
  	/* Enable DAIs */
0ab6f0b35   Simon Glass   dm: sound: Move c...
386
  	error |= maxim_i2c_write(priv, M98095_093_BIAS_CTRL, 0x30);
6b40852da   Dani Krishna Mohan   Sound: MAX98095: ...
387
  	if (aif_id == AIF1)
0ab6f0b35   Simon Glass   dm: sound: Move c...
388
  		error |= maxim_i2c_write(priv, M98095_096_PWR_DAC_CK, 0x01);
6b40852da   Dani Krishna Mohan   Sound: MAX98095: ...
389
  	else
0ab6f0b35   Simon Glass   dm: sound: Move c...
390
  		error |= maxim_i2c_write(priv, M98095_096_PWR_DAC_CK, 0x07);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
391

5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
392
  	if (error < 0)
bc58184ec   Simon Glass   dm: sound: max980...
393
  		return -EIO;
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
394
395
396
  
  	return 0;
  }
0ab6f0b35   Simon Glass   dm: sound: Move c...
397
  static int max98095_do_init(struct maxim_priv *priv,
6b40852da   Dani Krishna Mohan   Sound: MAX98095: ...
398
399
400
  			    enum en_max_audio_interface aif_id,
  			    int sampling_rate, int mclk_freq,
  			    int bits_per_sample)
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
401
402
  {
  	int ret = 0;
04660d642   Simon Glass   dm: sound: max980...
403
  	ret = max98095_setup_interface(priv, aif_id);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
404
  	if (ret < 0) {
d6cadd591   Simon Glass   dm: sound: Add co...
405
406
  		debug("%s: max98095 setup interface failed
  ", __func__);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
407
408
  		return ret;
  	}
04660d642   Simon Glass   dm: sound: max980...
409
  	ret = max98095_set_sysclk(priv, mclk_freq);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
410
411
412
413
414
  	if (ret < 0) {
  		debug("%s: max98095 codec set sys clock failed
  ", __func__);
  		return ret;
  	}
04660d642   Simon Glass   dm: sound: max980...
415
  	ret = max98095_hw_params(priv, aif_id, sampling_rate,
6b40852da   Dani Krishna Mohan   Sound: MAX98095: ...
416
  				 bits_per_sample);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
417
418
  
  	if (ret == 0) {
04660d642   Simon Glass   dm: sound: max980...
419
  		ret = max98095_set_fmt(priv, SND_SOC_DAIFMT_I2S |
6b40852da   Dani Krishna Mohan   Sound: MAX98095: ...
420
421
422
  				       SND_SOC_DAIFMT_NB_NF |
  				       SND_SOC_DAIFMT_CBS_CFS,
  				       aif_id);
5febe8db9   Rajeshwari Shinde   Sound: MAX98095: ...
423
424
425
426
  	}
  
  	return ret;
  }
d6cadd591   Simon Glass   dm: sound: Add co...
427
428
429
430
  static int max98095_set_params(struct udevice *dev, int interface, int rate,
  			       int mclk_freq, int bits_per_sample,
  			       uint channels)
  {
0ab6f0b35   Simon Glass   dm: sound: Move c...
431
  	struct maxim_priv *priv = dev_get_priv(dev);
d6cadd591   Simon Glass   dm: sound: Add co...
432
433
434
435
436
437
438
  
  	return max98095_do_init(priv, interface, rate, mclk_freq,
  				bits_per_sample);
  }
  
  static int max98095_probe(struct udevice *dev)
  {
0ab6f0b35   Simon Glass   dm: sound: Move c...
439
  	struct maxim_priv *priv = dev_get_priv(dev);
d6cadd591   Simon Glass   dm: sound: Add co...
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
  	int ret;
  
  	priv->dev = dev;
  	ret = max98095_device_init(priv);
  	if (ret < 0) {
  		debug("%s: max98095 codec chip init failed
  ", __func__);
  		return ret;
  	}
  
  	return 0;
  }
  
  static const struct audio_codec_ops max98095_ops = {
  	.set_params	= max98095_set_params,
  };
  
  static const struct udevice_id max98095_ids[] = {
  	{ .compatible = "maxim,max98095" },
  	{ }
  };
  
  U_BOOT_DRIVER(max98095) = {
  	.name		= "max98095",
  	.id		= UCLASS_AUDIO_CODEC,
  	.of_match	= max98095_ids,
  	.probe		= max98095_probe,
  	.ops		= &max98095_ops,
0ab6f0b35   Simon Glass   dm: sound: Move c...
468
  	.priv_auto_alloc_size	= sizeof(struct maxim_priv),
d6cadd591   Simon Glass   dm: sound: Add co...
469
  };