]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - sound/soc/bcm/digidac1-soundcard.c
sound: Suppress error message about deferrals
[mirror_ubuntu-zesty-kernel.git] / sound / soc / bcm / digidac1-soundcard.c
CommitLineData
6c9ca7fa 1/*
2 * ASoC Driver for RRA DigiDAC1
3 * Copyright 2016
4 * Author: José M. Tasende <vintage@redrocksaudio.es>
5 * based on the HifiBerry DAC driver by Florian Meier <florian.meier@koalo.de>
6 * and the Wolfson card driver by Nikesh Oswal, <Nikesh.Oswal@wolfsonmicro.com>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 */
16
17#include <linux/module.h>
18#include <linux/platform_device.h>
19#include <linux/i2c.h>
20#include <sound/core.h>
21#include <sound/pcm.h>
22#include <sound/pcm_params.h>
23#include <sound/soc.h>
24#include <sound/jack.h>
25#include <sound/soc-dapm.h>
26#include <sound/tlv.h>
27#include <linux/regulator/consumer.h>
28
29#include "../codecs/wm8804.h"
30#include "../codecs/wm8741.h"
31
32#define WM8741_NUM_SUPPLIES 2
33
34/* codec private data */
35struct wm8741_priv {
36 struct wm8741_platform_data pdata;
37 struct regmap *regmap;
38 struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES];
39 unsigned int sysclk;
40 const struct snd_pcm_hw_constraint_list *sysclk_constraints;
41};
42
43static int samplerate = 44100;
44
45/* New Alsa Controls not exposed by original wm8741 codec driver */
46/* in actual driver the att. adjustment is wrong because */
47/* this DAC has a coarse attenuation register with 4dB steps */
48/* and a fine level register with 0.125dB steps */
49/* each register has 32 steps so combining both we have 1024 steps */
50/* of 0.125 dB. */
51/* The original level controls from driver are removed at startup */
52/* and replaced by the corrected ones. */
53/* The same wm8741 driver can be used for wm8741 and wm8742 devices */
54
55static const DECLARE_TLV_DB_SCALE(dac_tlv_fine, 0, 13, 0);
56static const DECLARE_TLV_DB_SCALE(dac_tlv_coarse, -12700, 400, 1);
57static const char *w8741_dither[4] = {"Off", "RPDF", "TPDF", "HPDF"};
58static const char *w8741_filter[5] = {
59 "Type 1", "Type 2", "Type 3", "Type 4", "Type 5"};
60static const char *w8741_switch[2] = {"Off", "On"};
61static const struct soc_enum w8741_enum[] = {
62SOC_ENUM_SINGLE(WM8741_MODE_CONTROL_2, 0, 4, w8741_dither),/* dithering type */
63SOC_ENUM_SINGLE(WM8741_FILTER_CONTROL, 0, 5, w8741_filter),/* filter type */
64SOC_ENUM_SINGLE(WM8741_FORMAT_CONTROL, 6, 2, w8741_switch),/* phase invert */
65SOC_ENUM_SINGLE(WM8741_VOLUME_CONTROL, 0, 2, w8741_switch),/* volume ramp */
66SOC_ENUM_SINGLE(WM8741_VOLUME_CONTROL, 3, 2, w8741_switch),/* soft mute */
67};
68
69static const struct snd_kcontrol_new w8741_snd_controls_stereo[] = {
70SOC_DOUBLE_R_TLV("DAC Fine Playback Volume", WM8741_DACLLSB_ATTENUATION,
71 WM8741_DACRLSB_ATTENUATION, 0, 31, 1, dac_tlv_fine),
72SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8741_DACLMSB_ATTENUATION,
73 WM8741_DACRMSB_ATTENUATION, 0, 31, 1, dac_tlv_coarse),
74SOC_ENUM("DAC Dither", w8741_enum[0]),
75SOC_ENUM("DAC Digital Filter", w8741_enum[1]),
76SOC_ENUM("DAC Phase Invert", w8741_enum[2]),
77SOC_ENUM("DAC Volume Ramp", w8741_enum[3]),
78SOC_ENUM("DAC Soft Mute", w8741_enum[4]),
79};
80
81static const struct snd_kcontrol_new w8741_snd_controls_mono_left[] = {
82SOC_SINGLE_TLV("DAC Fine Playback Volume", WM8741_DACLLSB_ATTENUATION,
83 0, 31, 0, dac_tlv_fine),
84SOC_SINGLE_TLV("Digital Playback Volume", WM8741_DACLMSB_ATTENUATION,
85 0, 31, 1, dac_tlv_coarse),
86SOC_ENUM("DAC Dither", w8741_enum[0]),
87SOC_ENUM("DAC Digital Filter", w8741_enum[1]),
88SOC_ENUM("DAC Phase Invert", w8741_enum[2]),
89SOC_ENUM("DAC Volume Ramp", w8741_enum[3]),
90SOC_ENUM("DAC Soft Mute", w8741_enum[4]),
91};
92
93static const struct snd_kcontrol_new w8741_snd_controls_mono_right[] = {
94SOC_SINGLE_TLV("DAC Fine Playback Volume", WM8741_DACRLSB_ATTENUATION,
95 0, 31, 0, dac_tlv_fine),
96SOC_SINGLE_TLV("Digital Playback Volume", WM8741_DACRMSB_ATTENUATION,
97 0, 31, 1, dac_tlv_coarse),
98SOC_ENUM("DAC Dither", w8741_enum[0]),
99SOC_ENUM("DAC Digital Filter", w8741_enum[1]),
100SOC_ENUM("DAC Phase Invert", w8741_enum[2]),
101SOC_ENUM("DAC Volume Ramp", w8741_enum[3]),
102SOC_ENUM("DAC Soft Mute", w8741_enum[4]),
103};
104
105static int w8741_add_controls(struct snd_soc_codec *codec)
106{
107 struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
108
109 switch (wm8741->pdata.diff_mode) {
110 case WM8741_DIFF_MODE_STEREO:
111 case WM8741_DIFF_MODE_STEREO_REVERSED:
112 snd_soc_add_codec_controls(codec,
113 w8741_snd_controls_stereo,
114 ARRAY_SIZE(w8741_snd_controls_stereo));
115 break;
116 case WM8741_DIFF_MODE_MONO_LEFT:
117 snd_soc_add_codec_controls(codec,
118 w8741_snd_controls_mono_left,
119 ARRAY_SIZE(w8741_snd_controls_mono_left));
120 break;
121 case WM8741_DIFF_MODE_MONO_RIGHT:
122 snd_soc_add_codec_controls(codec,
123 w8741_snd_controls_mono_right,
124 ARRAY_SIZE(w8741_snd_controls_mono_right));
125 break;
126 default:
127 return -EINVAL;
128 }
129
130 return 0;
131}
132
133static int digidac1_soundcard_init(struct snd_soc_pcm_runtime *rtd)
134{
135 struct snd_soc_codec *codec = rtd->codec;
136 struct snd_soc_card *card = rtd->card;
137 struct snd_soc_pcm_runtime *wm8741_rtd;
138 struct snd_soc_codec *wm8741_codec;
139 struct snd_card *sound_card = card->snd_card;
140 struct snd_kcontrol *kctl;
141 int ret;
142
143 wm8741_rtd = snd_soc_get_pcm_runtime(card, card->dai_link[1].name);
144 if (!wm8741_rtd) {
145 dev_warn(card->dev, "digidac1_soundcard_init: couldn't get wm8741 rtd\n");
146 return -EFAULT;
147 }
148 wm8741_codec = wm8741_rtd->codec;
149 ret = w8741_add_controls(wm8741_codec);
150 if (ret < 0)
151 dev_warn(card->dev, "Failed to add new wm8741 controls: %d\n",
152 ret);
153
154 /* enable TX output */
155 snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0);
156
157 kctl = snd_soc_card_get_kcontrol(card,
158 "Playback Volume");
159 if (kctl) {
160 kctl->vd[0].access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
161 snd_ctl_remove(sound_card, kctl);
162 }
163 kctl = snd_soc_card_get_kcontrol(card,
164 "Fine Playback Volume");
165 if (kctl) {
166 kctl->vd[0].access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
167 snd_ctl_remove(sound_card, kctl);
168 }
169 return 0;
170}
171
172static int digidac1_soundcard_startup(struct snd_pcm_substream *substream)
173{
174 /* turn on wm8804 digital output */
175 struct snd_soc_pcm_runtime *rtd = substream->private_data;
176 struct snd_soc_codec *codec = rtd->codec;
177 struct snd_soc_card *card = rtd->card;
178 struct snd_soc_pcm_runtime *wm8741_rtd;
179 struct snd_soc_codec *wm8741_codec;
180
181 snd_soc_update_bits(codec, WM8804_PWRDN, 0x3c, 0x00);
182 wm8741_rtd = snd_soc_get_pcm_runtime(card, card->dai_link[1].name);
183 if (!wm8741_rtd) {
184 dev_warn(card->dev, "digidac1_soundcard_startup: couldn't get WM8741 rtd\n");
185 return -EFAULT;
186 }
187 wm8741_codec = wm8741_rtd->codec;
188
189 /* latch wm8741 level */
190 snd_soc_update_bits(wm8741_codec, WM8741_DACLLSB_ATTENUATION,
191 WM8741_UPDATELL, WM8741_UPDATELL);
192 snd_soc_update_bits(wm8741_codec, WM8741_DACLMSB_ATTENUATION,
193 WM8741_UPDATELM, WM8741_UPDATELM);
194 snd_soc_update_bits(wm8741_codec, WM8741_DACRLSB_ATTENUATION,
195 WM8741_UPDATERL, WM8741_UPDATERL);
196 snd_soc_update_bits(wm8741_codec, WM8741_DACRMSB_ATTENUATION,
197 WM8741_UPDATERM, WM8741_UPDATERM);
198
199 return 0;
200}
201
202static void digidac1_soundcard_shutdown(struct snd_pcm_substream *substream)
203{
204 /* turn off wm8804 digital output */
205 struct snd_soc_pcm_runtime *rtd = substream->private_data;
206 struct snd_soc_codec *codec = rtd->codec;
207
208 snd_soc_update_bits(codec, WM8804_PWRDN, 0x3c, 0x3c);
209}
210
211static int digidac1_soundcard_hw_params(struct snd_pcm_substream *substream,
212 struct snd_pcm_hw_params *params)
213{
214 struct snd_soc_pcm_runtime *rtd = substream->private_data;
215 struct snd_soc_dai *codec_dai = rtd->codec_dai;
216 struct snd_soc_codec *codec = rtd->codec;
217 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
218 struct snd_soc_card *card = rtd->card;
219 struct snd_soc_pcm_runtime *wm8741_rtd;
220 struct snd_soc_codec *wm8741_codec;
221
222 int sysclk = 27000000;
223 long mclk_freq = 0;
224 int mclk_div = 1;
225 int sampling_freq = 1;
226 int ret;
227
228 wm8741_rtd = snd_soc_get_pcm_runtime(card, card->dai_link[1].name);
229 if (!wm8741_rtd) {
230 dev_warn(card->dev, "digidac1_soundcard_hw_params: couldn't get WM8741 rtd\n");
231 return -EFAULT;
232 }
233 wm8741_codec = wm8741_rtd->codec;
234 samplerate = params_rate(params);
235
236 if (samplerate <= 96000) {
237 mclk_freq = samplerate*256;
238 mclk_div = WM8804_MCLKDIV_256FS;
239 } else {
240 mclk_freq = samplerate*128;
241 mclk_div = WM8804_MCLKDIV_128FS;
242 }
243
244 switch (samplerate) {
245 case 32000:
246 sampling_freq = 0x03;
247 break;
248 case 44100:
249 sampling_freq = 0x00;
250 break;
251 case 48000:
252 sampling_freq = 0x02;
253 break;
254 case 88200:
255 sampling_freq = 0x08;
256 break;
257 case 96000:
258 sampling_freq = 0x0a;
259 break;
260 case 176400:
261 sampling_freq = 0x0c;
262 break;
263 case 192000:
264 sampling_freq = 0x0e;
265 break;
266 default:
267 dev_err(codec->dev,
268 "Failed to set WM8804 SYSCLK, unsupported samplerate %d\n",
269 samplerate);
270 }
271
272 snd_soc_dai_set_clkdiv(codec_dai, WM8804_MCLK_DIV, mclk_div);
273 snd_soc_dai_set_pll(codec_dai, 0, 0, sysclk, mclk_freq);
274
275 ret = snd_soc_dai_set_sysclk(codec_dai, WM8804_TX_CLKSRC_PLL,
276 sysclk, SND_SOC_CLOCK_OUT);
277 if (ret < 0) {
278 dev_err(codec->dev,
279 "Failed to set WM8804 SYSCLK: %d\n", ret);
280 return ret;
281 }
282 /* Enable wm8804 TX output */
283 snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0);
284
285 /* wm8804 Power on */
286 snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0);
287
288 /* wm8804 set sampling frequency status bits */
289 snd_soc_update_bits(codec, WM8804_SPDTX4, 0x0f, sampling_freq);
290
291 /* Now update wm8741 registers for the correct oversampling */
292 if (samplerate <= 48000)
293 snd_soc_update_bits(wm8741_codec, WM8741_MODE_CONTROL_1,
294 WM8741_OSR_MASK, 0x00);
295 else if (samplerate <= 96000)
296 snd_soc_update_bits(wm8741_codec, WM8741_MODE_CONTROL_1,
297 WM8741_OSR_MASK, 0x20);
298 else
299 snd_soc_update_bits(wm8741_codec, WM8741_MODE_CONTROL_1,
300 WM8741_OSR_MASK, 0x40);
301
302 /* wm8741 bit size */
303 switch (params_width(params)) {
304 case 16:
305 snd_soc_update_bits(wm8741_codec, WM8741_FORMAT_CONTROL,
306 WM8741_IWL_MASK, 0x00);
307 break;
308 case 20:
309 snd_soc_update_bits(wm8741_codec, WM8741_FORMAT_CONTROL,
310 WM8741_IWL_MASK, 0x01);
311 break;
312 case 24:
313 snd_soc_update_bits(wm8741_codec, WM8741_FORMAT_CONTROL,
314 WM8741_IWL_MASK, 0x02);
315 break;
316 case 32:
317 snd_soc_update_bits(wm8741_codec, WM8741_FORMAT_CONTROL,
318 WM8741_IWL_MASK, 0x03);
319 break;
320 default:
321 dev_dbg(codec->dev, "wm8741_hw_params: Unsupported bit size param = %d",
322 params_width(params));
323 return -EINVAL;
324 }
325
326 return snd_soc_dai_set_bclk_ratio(cpu_dai, 64);
327}
328/* machine stream operations */
329static struct snd_soc_ops digidac1_soundcard_ops = {
330 .hw_params = digidac1_soundcard_hw_params,
331 .startup = digidac1_soundcard_startup,
332 .shutdown = digidac1_soundcard_shutdown,
333};
334
335static struct snd_soc_dai_link digidac1_soundcard_dai[] = {
336 {
337 .name = "RRA DigiDAC1",
338 .stream_name = "RRA DigiDAC1 HiFi",
339 .cpu_dai_name = "bcm2708-i2s.0",
340 .codec_dai_name = "wm8804-spdif",
341 .platform_name = "bcm2708-i2s.0",
342 .codec_name = "wm8804.1-003b",
343 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
344 SND_SOC_DAIFMT_CBM_CFM,
345 .ops = &digidac1_soundcard_ops,
346 .init = digidac1_soundcard_init,
347 },
348 {
349 .name = "RRA DigiDAC11",
350 .stream_name = "RRA DigiDAC11 HiFi",
351 .cpu_dai_name = "wm8804-spdif",
352 .codec_dai_name = "wm8741",
353 .codec_name = "wm8741.1-001a",
354 .dai_fmt = SND_SOC_DAIFMT_I2S
355 | SND_SOC_DAIFMT_NB_NF
356 | SND_SOC_DAIFMT_CBS_CFS,
357 },
358};
359
360/* audio machine driver */
361static struct snd_soc_card digidac1_soundcard = {
362 .name = "digidac1-soundcard",
363 .owner = THIS_MODULE,
364 .dai_link = digidac1_soundcard_dai,
365 .num_links = ARRAY_SIZE(digidac1_soundcard_dai),
366};
367
368static int digidac1_soundcard_probe(struct platform_device *pdev)
369{
370 int ret = 0;
371
372 digidac1_soundcard.dev = &pdev->dev;
373
374 if (pdev->dev.of_node) {
375 struct device_node *i2s_node;
376 struct snd_soc_dai_link *dai = &digidac1_soundcard_dai[0];
377
378 i2s_node = of_parse_phandle(pdev->dev.of_node,
379 "i2s-controller", 0);
380
381 if (i2s_node) {
382 dai->cpu_dai_name = NULL;
383 dai->cpu_of_node = i2s_node;
384 dai->platform_name = NULL;
385 dai->platform_of_node = i2s_node;
386 }
387 }
388
389 ret = snd_soc_register_card(&digidac1_soundcard);
49dbf1af 390 if (ret && ret != -EPROBE_DEFER)
6c9ca7fa 391 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
49dbf1af 392 ret);
6c9ca7fa 393
394 return ret;
395}
396
397static int digidac1_soundcard_remove(struct platform_device *pdev)
398{
399 return snd_soc_unregister_card(&digidac1_soundcard);
400}
401
402static const struct of_device_id digidac1_soundcard_of_match[] = {
403 { .compatible = "rra,digidac1-soundcard", },
404 {},
405};
406MODULE_DEVICE_TABLE(of, digidac1_soundcard_of_match);
407
408static struct platform_driver digidac1_soundcard_driver = {
409 .driver = {
410 .name = "digidac1-audio",
411 .owner = THIS_MODULE,
412 .of_match_table = digidac1_soundcard_of_match,
413 },
414 .probe = digidac1_soundcard_probe,
415 .remove = digidac1_soundcard_remove,
416};
417
418module_platform_driver(digidac1_soundcard_driver);
419
420MODULE_AUTHOR("José M. Tasende <vintage@redrocksaudio.es>");
421MODULE_DESCRIPTION("ASoC Driver for RRA DigiDAC1");
422MODULE_LICENSE("GPL v2");