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