1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Texas Instruments TLV320AIC26 low power audio CODEC |
4 | * ALSA SoC CODEC driver |
5 | * |
6 | * Copyright (C) 2008 Secret Lab Technologies Ltd. |
7 | */ |
8 | |
9 | #include <linux/module.h> |
10 | #include <linux/moduleparam.h> |
11 | #include <linux/init.h> |
12 | #include <linux/delay.h> |
13 | #include <linux/pm.h> |
14 | #include <linux/device.h> |
15 | #include <linux/sysfs.h> |
16 | #include <linux/spi/spi.h> |
17 | #include <linux/slab.h> |
18 | #include <sound/core.h> |
19 | #include <sound/pcm.h> |
20 | #include <sound/pcm_params.h> |
21 | #include <sound/soc.h> |
22 | #include <sound/initval.h> |
23 | |
24 | #include "tlv320aic26.h" |
25 | |
26 | MODULE_DESCRIPTION("ASoC TLV320AIC26 codec driver" ); |
27 | MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>" ); |
28 | MODULE_LICENSE("GPL" ); |
29 | |
30 | /* AIC26 driver private data */ |
31 | struct aic26 { |
32 | struct spi_device *spi; |
33 | struct regmap *regmap; |
34 | struct snd_soc_component *component; |
35 | int clock_provider; |
36 | int datfm; |
37 | int mclk; |
38 | |
39 | /* Keyclick parameters */ |
40 | int keyclick_amplitude; |
41 | int keyclick_freq; |
42 | int keyclick_len; |
43 | }; |
44 | |
45 | static const struct snd_soc_dapm_widget tlv320aic26_dapm_widgets[] = { |
46 | SND_SOC_DAPM_INPUT("MICIN" ), |
47 | SND_SOC_DAPM_INPUT("AUX" ), |
48 | |
49 | SND_SOC_DAPM_OUTPUT("HPL" ), |
50 | SND_SOC_DAPM_OUTPUT("HPR" ), |
51 | }; |
52 | |
53 | static const struct snd_soc_dapm_route tlv320aic26_dapm_routes[] = { |
54 | { "Capture" , NULL, "MICIN" }, |
55 | { "Capture" , NULL, "AUX" }, |
56 | |
57 | { "HPL" , NULL, "Playback" }, |
58 | { "HPR" , NULL, "Playback" }, |
59 | }; |
60 | |
61 | /* --------------------------------------------------------------------- |
62 | * Digital Audio Interface Operations |
63 | */ |
64 | static int aic26_hw_params(struct snd_pcm_substream *substream, |
65 | struct snd_pcm_hw_params *params, |
66 | struct snd_soc_dai *dai) |
67 | { |
68 | struct snd_soc_component *component = dai->component; |
69 | struct aic26 *aic26 = snd_soc_component_get_drvdata(c: component); |
70 | int fsref, divisor, wlen, pval, jval, dval, qval; |
71 | u16 reg; |
72 | |
73 | dev_dbg(&aic26->spi->dev, "aic26_hw_params(substream=%p, params=%p)\n" , |
74 | substream, params); |
75 | dev_dbg(&aic26->spi->dev, "rate=%i width=%d\n" , params_rate(params), |
76 | params_width(params)); |
77 | |
78 | switch (params_rate(p: params)) { |
79 | case 8000: fsref = 48000; divisor = AIC26_DIV_6; break; |
80 | case 11025: fsref = 44100; divisor = AIC26_DIV_4; break; |
81 | case 12000: fsref = 48000; divisor = AIC26_DIV_4; break; |
82 | case 16000: fsref = 48000; divisor = AIC26_DIV_3; break; |
83 | case 22050: fsref = 44100; divisor = AIC26_DIV_2; break; |
84 | case 24000: fsref = 48000; divisor = AIC26_DIV_2; break; |
85 | case 32000: fsref = 48000; divisor = AIC26_DIV_1_5; break; |
86 | case 44100: fsref = 44100; divisor = AIC26_DIV_1; break; |
87 | case 48000: fsref = 48000; divisor = AIC26_DIV_1; break; |
88 | default: |
89 | dev_dbg(&aic26->spi->dev, "bad rate\n" ); return -EINVAL; |
90 | } |
91 | |
92 | /* select data word length */ |
93 | switch (params_width(p: params)) { |
94 | case 8: wlen = AIC26_WLEN_16; break; |
95 | case 16: wlen = AIC26_WLEN_16; break; |
96 | case 24: wlen = AIC26_WLEN_24; break; |
97 | case 32: wlen = AIC26_WLEN_32; break; |
98 | default: |
99 | dev_dbg(&aic26->spi->dev, "bad format\n" ); return -EINVAL; |
100 | } |
101 | |
102 | /** |
103 | * Configure PLL |
104 | * fsref = (mclk * PLLM) / 2048 |
105 | * where PLLM = J.DDDD (DDDD register ranges from 0 to 9999, decimal) |
106 | */ |
107 | pval = 1; |
108 | /* compute J portion of multiplier */ |
109 | jval = fsref / (aic26->mclk / 2048); |
110 | /* compute fractional DDDD component of multiplier */ |
111 | dval = fsref - (jval * (aic26->mclk / 2048)); |
112 | dval = (10000 * dval) / (aic26->mclk / 2048); |
113 | dev_dbg(&aic26->spi->dev, "Setting PLLM to %d.%04d\n" , jval, dval); |
114 | qval = 0; |
115 | reg = 0x8000 | qval << 11 | pval << 8 | jval << 2; |
116 | snd_soc_component_write(component, AIC26_REG_PLL_PROG1, val: reg); |
117 | reg = dval << 2; |
118 | snd_soc_component_write(component, AIC26_REG_PLL_PROG2, val: reg); |
119 | |
120 | /* Audio Control 3 (clock provider mode, fsref rate) */ |
121 | if (aic26->clock_provider) |
122 | reg = 0x0800; |
123 | if (fsref == 48000) |
124 | reg = 0x2000; |
125 | snd_soc_component_update_bits(component, AIC26_REG_AUDIO_CTRL3, mask: 0xf800, val: reg); |
126 | |
127 | /* Audio Control 1 (FSref divisor) */ |
128 | reg = wlen | aic26->datfm | (divisor << 3) | divisor; |
129 | snd_soc_component_update_bits(component, AIC26_REG_AUDIO_CTRL1, mask: 0xfff, val: reg); |
130 | |
131 | return 0; |
132 | } |
133 | |
134 | /* |
135 | * aic26_mute - Mute control to reduce noise when changing audio format |
136 | */ |
137 | static int aic26_mute(struct snd_soc_dai *dai, int mute, int direction) |
138 | { |
139 | struct snd_soc_component *component = dai->component; |
140 | struct aic26 *aic26 = snd_soc_component_get_drvdata(c: component); |
141 | u16 reg; |
142 | |
143 | dev_dbg(&aic26->spi->dev, "aic26_mute(dai=%p, mute=%i)\n" , |
144 | dai, mute); |
145 | |
146 | if (mute) |
147 | reg = 0x8080; |
148 | else |
149 | reg = 0; |
150 | snd_soc_component_update_bits(component, AIC26_REG_DAC_GAIN, mask: 0x8000, val: reg); |
151 | |
152 | return 0; |
153 | } |
154 | |
155 | static int aic26_set_sysclk(struct snd_soc_dai *codec_dai, |
156 | int clk_id, unsigned int freq, int dir) |
157 | { |
158 | struct snd_soc_component *component = codec_dai->component; |
159 | struct aic26 *aic26 = snd_soc_component_get_drvdata(c: component); |
160 | |
161 | dev_dbg(&aic26->spi->dev, "aic26_set_sysclk(dai=%p, clk_id==%i," |
162 | " freq=%i, dir=%i)\n" , |
163 | codec_dai, clk_id, freq, dir); |
164 | |
165 | /* MCLK needs to fall between 2MHz and 50 MHz */ |
166 | if ((freq < 2000000) || (freq > 50000000)) |
167 | return -EINVAL; |
168 | |
169 | aic26->mclk = freq; |
170 | return 0; |
171 | } |
172 | |
173 | static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) |
174 | { |
175 | struct snd_soc_component *component = codec_dai->component; |
176 | struct aic26 *aic26 = snd_soc_component_get_drvdata(c: component); |
177 | |
178 | dev_dbg(&aic26->spi->dev, "aic26_set_fmt(dai=%p, fmt==%i)\n" , |
179 | codec_dai, fmt); |
180 | |
181 | switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { |
182 | case SND_SOC_DAIFMT_CBP_CFP: aic26->clock_provider = 1; break; |
183 | case SND_SOC_DAIFMT_CBC_CFC: aic26->clock_provider = 0; break; |
184 | default: |
185 | dev_dbg(&aic26->spi->dev, "bad master\n" ); return -EINVAL; |
186 | } |
187 | |
188 | /* interface format */ |
189 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
190 | case SND_SOC_DAIFMT_I2S: aic26->datfm = AIC26_DATFM_I2S; break; |
191 | case SND_SOC_DAIFMT_DSP_A: aic26->datfm = AIC26_DATFM_DSP; break; |
192 | case SND_SOC_DAIFMT_RIGHT_J: aic26->datfm = AIC26_DATFM_RIGHTJ; break; |
193 | case SND_SOC_DAIFMT_LEFT_J: aic26->datfm = AIC26_DATFM_LEFTJ; break; |
194 | default: |
195 | dev_dbg(&aic26->spi->dev, "bad format\n" ); return -EINVAL; |
196 | } |
197 | |
198 | return 0; |
199 | } |
200 | |
201 | /* --------------------------------------------------------------------- |
202 | * Digital Audio Interface Definition |
203 | */ |
204 | #define AIC26_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ |
205 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ |
206 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ |
207 | SNDRV_PCM_RATE_48000) |
208 | #define AIC26_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE |\ |
209 | SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE) |
210 | |
211 | static const struct snd_soc_dai_ops aic26_dai_ops = { |
212 | .hw_params = aic26_hw_params, |
213 | .mute_stream = aic26_mute, |
214 | .set_sysclk = aic26_set_sysclk, |
215 | .set_fmt = aic26_set_fmt, |
216 | .no_capture_mute = 1, |
217 | }; |
218 | |
219 | static struct snd_soc_dai_driver aic26_dai = { |
220 | .name = "tlv320aic26-hifi" , |
221 | .playback = { |
222 | .stream_name = "Playback" , |
223 | .channels_min = 2, |
224 | .channels_max = 2, |
225 | .rates = AIC26_RATES, |
226 | .formats = AIC26_FORMATS, |
227 | }, |
228 | .capture = { |
229 | .stream_name = "Capture" , |
230 | .channels_min = 2, |
231 | .channels_max = 2, |
232 | .rates = AIC26_RATES, |
233 | .formats = AIC26_FORMATS, |
234 | }, |
235 | .ops = &aic26_dai_ops, |
236 | }; |
237 | |
238 | /* --------------------------------------------------------------------- |
239 | * ALSA controls |
240 | */ |
241 | static const char *aic26_capture_src_text[] = {"Mic" , "Aux" }; |
242 | static SOC_ENUM_SINGLE_DECL(aic26_capture_src_enum, |
243 | AIC26_REG_AUDIO_CTRL1, 12, |
244 | aic26_capture_src_text); |
245 | |
246 | static const struct snd_kcontrol_new aic26_snd_controls[] = { |
247 | /* Output */ |
248 | SOC_DOUBLE("PCM Playback Volume" , AIC26_REG_DAC_GAIN, 8, 0, 0x7f, 1), |
249 | SOC_DOUBLE("PCM Playback Switch" , AIC26_REG_DAC_GAIN, 15, 7, 1, 1), |
250 | SOC_SINGLE("PCM Capture Volume" , AIC26_REG_ADC_GAIN, 8, 0x7f, 0), |
251 | SOC_SINGLE("PCM Capture Mute" , AIC26_REG_ADC_GAIN, 15, 1, 1), |
252 | SOC_SINGLE("Keyclick activate" , AIC26_REG_AUDIO_CTRL2, 15, 0x1, 0), |
253 | SOC_SINGLE("Keyclick amplitude" , AIC26_REG_AUDIO_CTRL2, 12, 0x7, 0), |
254 | SOC_SINGLE("Keyclick frequency" , AIC26_REG_AUDIO_CTRL2, 8, 0x7, 0), |
255 | SOC_SINGLE("Keyclick period" , AIC26_REG_AUDIO_CTRL2, 4, 0xf, 0), |
256 | SOC_ENUM("Capture Source" , aic26_capture_src_enum), |
257 | }; |
258 | |
259 | /* --------------------------------------------------------------------- |
260 | * SPI device portion of driver: sysfs files for debugging |
261 | */ |
262 | |
263 | static ssize_t keyclick_show(struct device *dev, |
264 | struct device_attribute *attr, char *buf) |
265 | { |
266 | struct aic26 *aic26 = dev_get_drvdata(dev); |
267 | int val, amp, freq, len; |
268 | |
269 | val = snd_soc_component_read(component: aic26->component, AIC26_REG_AUDIO_CTRL2); |
270 | amp = (val >> 12) & 0x7; |
271 | freq = (125 << ((val >> 8) & 0x7)) >> 1; |
272 | len = 2 * (1 + ((val >> 4) & 0xf)); |
273 | |
274 | return sysfs_emit(buf, fmt: "amp=%x freq=%iHz len=%iclks\n" , amp, freq, len); |
275 | } |
276 | |
277 | /* Any write to the keyclick attribute will trigger the keyclick event */ |
278 | static ssize_t keyclick_store(struct device *dev, |
279 | struct device_attribute *attr, |
280 | const char *buf, size_t count) |
281 | { |
282 | struct aic26 *aic26 = dev_get_drvdata(dev); |
283 | |
284 | snd_soc_component_update_bits(component: aic26->component, AIC26_REG_AUDIO_CTRL2, |
285 | mask: 0x8000, val: 0x800); |
286 | |
287 | return count; |
288 | } |
289 | |
290 | static DEVICE_ATTR_RW(keyclick); |
291 | |
292 | /* --------------------------------------------------------------------- |
293 | * SoC CODEC portion of driver: probe and release routines |
294 | */ |
295 | static int aic26_probe(struct snd_soc_component *component) |
296 | { |
297 | struct aic26 *aic26 = dev_get_drvdata(dev: component->dev); |
298 | int ret, reg; |
299 | |
300 | aic26->component = component; |
301 | |
302 | /* Reset the codec to power on defaults */ |
303 | snd_soc_component_write(component, AIC26_REG_RESET, val: 0xBB00); |
304 | |
305 | /* Power up CODEC */ |
306 | snd_soc_component_write(component, AIC26_REG_POWER_CTRL, val: 0); |
307 | |
308 | /* Audio Control 3 (master mode, fsref rate) */ |
309 | reg = snd_soc_component_read(component, AIC26_REG_AUDIO_CTRL3); |
310 | reg &= ~0xf800; |
311 | reg |= 0x0800; /* set master mode */ |
312 | snd_soc_component_write(component, AIC26_REG_AUDIO_CTRL3, val: reg); |
313 | |
314 | /* Register the sysfs files for debugging */ |
315 | /* Create SysFS files */ |
316 | ret = device_create_file(device: component->dev, entry: &dev_attr_keyclick); |
317 | if (ret) |
318 | dev_info(component->dev, "error creating sysfs files\n" ); |
319 | |
320 | return 0; |
321 | } |
322 | |
323 | static const struct snd_soc_component_driver aic26_soc_component_dev = { |
324 | .probe = aic26_probe, |
325 | .controls = aic26_snd_controls, |
326 | .num_controls = ARRAY_SIZE(aic26_snd_controls), |
327 | .dapm_widgets = tlv320aic26_dapm_widgets, |
328 | .num_dapm_widgets = ARRAY_SIZE(tlv320aic26_dapm_widgets), |
329 | .dapm_routes = tlv320aic26_dapm_routes, |
330 | .num_dapm_routes = ARRAY_SIZE(tlv320aic26_dapm_routes), |
331 | .idle_bias_on = 1, |
332 | .use_pmdown_time = 1, |
333 | .endianness = 1, |
334 | }; |
335 | |
336 | static const struct regmap_config aic26_regmap = { |
337 | .reg_bits = 16, |
338 | .val_bits = 16, |
339 | }; |
340 | |
341 | /* --------------------------------------------------------------------- |
342 | * SPI device portion of driver: probe and release routines and SPI |
343 | * driver registration. |
344 | */ |
345 | static int aic26_spi_probe(struct spi_device *spi) |
346 | { |
347 | struct aic26 *aic26; |
348 | int ret; |
349 | |
350 | dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n" ); |
351 | |
352 | /* Allocate driver data */ |
353 | aic26 = devm_kzalloc(dev: &spi->dev, size: sizeof *aic26, GFP_KERNEL); |
354 | if (!aic26) |
355 | return -ENOMEM; |
356 | |
357 | aic26->regmap = devm_regmap_init_spi(spi, &aic26_regmap); |
358 | if (IS_ERR(ptr: aic26->regmap)) |
359 | return PTR_ERR(ptr: aic26->regmap); |
360 | |
361 | /* Initialize the driver data */ |
362 | aic26->spi = spi; |
363 | dev_set_drvdata(dev: &spi->dev, data: aic26); |
364 | aic26->clock_provider = 1; |
365 | |
366 | ret = devm_snd_soc_register_component(dev: &spi->dev, |
367 | component_driver: &aic26_soc_component_dev, dai_drv: &aic26_dai, num_dai: 1); |
368 | return ret; |
369 | } |
370 | |
371 | static struct spi_driver aic26_spi = { |
372 | .driver = { |
373 | .name = "tlv320aic26-codec" , |
374 | }, |
375 | .probe = aic26_spi_probe, |
376 | }; |
377 | |
378 | module_spi_driver(aic26_spi); |
379 | |