Merge tag 'v5.15.57' into rpi-5.15.y
[platform/kernel/linux-rpi.git] / sound / soc / bcm / hifiberry_dacplusadc.c
1 /*
2  * ASoC Driver for HiFiBerry DAC+ / DAC Pro with ADC
3  *
4  * Author:      Daniel Matuschek, Stuart MacLean <stuart@hifiberry.com>
5  *              Copyright 2014-2015
6  *              based on code by Florian Meier <florian.meier@koalo.de>
7  *              ADC added by Joerg Schambacher <joscha@schambacher.com>
8  *              Copyright 2018
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * version 2 as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * General Public License for more details.
18  */
19
20 #include <linux/module.h>
21 #include <linux/platform_device.h>
22 #include <linux/kernel.h>
23 #include <linux/clk.h>
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/of.h>
27 #include <linux/slab.h>
28 #include <linux/delay.h>
29
30 #include <sound/core.h>
31 #include <sound/pcm.h>
32 #include <sound/pcm_params.h>
33 #include <sound/soc.h>
34 #include <sound/jack.h>
35
36 #include "../codecs/pcm512x.h"
37
38 #define HIFIBERRY_DACPRO_NOCLOCK 0
39 #define HIFIBERRY_DACPRO_CLK44EN 1
40 #define HIFIBERRY_DACPRO_CLK48EN 2
41
42 struct platform_device *dmic_codec_dev;
43
44 struct pcm512x_priv {
45         struct regmap *regmap;
46         struct clk *sclk;
47 };
48
49 /* Clock rate of CLK44EN attached to GPIO6 pin */
50 #define CLK_44EN_RATE 22579200UL
51 /* Clock rate of CLK48EN attached to GPIO3 pin */
52 #define CLK_48EN_RATE 24576000UL
53
54 static bool slave;
55 static bool snd_rpi_hifiberry_is_dacpro;
56 static bool digital_gain_0db_limit = true;
57 static bool leds_off;
58
59 static void snd_rpi_hifiberry_dacplusadc_select_clk(struct snd_soc_component *component,
60         int clk_id)
61 {
62         switch (clk_id) {
63         case HIFIBERRY_DACPRO_NOCLOCK:
64                 snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x24, 0x00);
65                 break;
66         case HIFIBERRY_DACPRO_CLK44EN:
67                 snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x24, 0x20);
68                 break;
69         case HIFIBERRY_DACPRO_CLK48EN:
70                 snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x24, 0x04);
71                 break;
72         }
73 }
74
75 static void snd_rpi_hifiberry_dacplusadc_clk_gpio(struct snd_soc_component *component)
76 {
77         snd_soc_component_update_bits(component, PCM512x_GPIO_EN, 0x24, 0x24);
78         snd_soc_component_update_bits(component, PCM512x_GPIO_OUTPUT_3, 0x0f, 0x02);
79         snd_soc_component_update_bits(component, PCM512x_GPIO_OUTPUT_6, 0x0f, 0x02);
80 }
81
82 static bool snd_rpi_hifiberry_dacplusadc_is_sclk(struct snd_soc_component *component)
83 {
84         unsigned int sck;
85
86         sck = snd_soc_component_read(component, PCM512x_RATE_DET_4);
87         return (!(sck & 0x40));
88 }
89
90 static bool snd_rpi_hifiberry_dacplusadc_is_sclk_sleep(
91         struct snd_soc_component *component)
92 {
93         msleep(2);
94         return snd_rpi_hifiberry_dacplusadc_is_sclk(component);
95 }
96
97 static bool snd_rpi_hifiberry_dacplusadc_is_pro_card(struct snd_soc_component *component)
98 {
99         bool isClk44EN, isClk48En, isNoClk;
100
101         snd_rpi_hifiberry_dacplusadc_clk_gpio(component);
102
103         snd_rpi_hifiberry_dacplusadc_select_clk(component, HIFIBERRY_DACPRO_CLK44EN);
104         isClk44EN = snd_rpi_hifiberry_dacplusadc_is_sclk_sleep(component);
105
106         snd_rpi_hifiberry_dacplusadc_select_clk(component, HIFIBERRY_DACPRO_NOCLOCK);
107         isNoClk = snd_rpi_hifiberry_dacplusadc_is_sclk_sleep(component);
108
109         snd_rpi_hifiberry_dacplusadc_select_clk(component, HIFIBERRY_DACPRO_CLK48EN);
110         isClk48En = snd_rpi_hifiberry_dacplusadc_is_sclk_sleep(component);
111
112         return (isClk44EN && isClk48En && !isNoClk);
113 }
114
115 static int snd_rpi_hifiberry_dacplusadc_clk_for_rate(int sample_rate)
116 {
117         int type;
118
119         switch (sample_rate) {
120         case 11025:
121         case 22050:
122         case 44100:
123         case 88200:
124         case 176400:
125         case 352800:
126                 type = HIFIBERRY_DACPRO_CLK44EN;
127                 break;
128         default:
129                 type = HIFIBERRY_DACPRO_CLK48EN;
130                 break;
131         }
132         return type;
133 }
134
135 static void snd_rpi_hifiberry_dacplusadc_set_sclk(struct snd_soc_component *component,
136         int sample_rate)
137 {
138         struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
139
140         if (!IS_ERR(pcm512x->sclk)) {
141                 int ctype;
142
143                 ctype = snd_rpi_hifiberry_dacplusadc_clk_for_rate(sample_rate);
144                 clk_set_rate(pcm512x->sclk, (ctype == HIFIBERRY_DACPRO_CLK44EN)
145                         ? CLK_44EN_RATE : CLK_48EN_RATE);
146                 snd_rpi_hifiberry_dacplusadc_select_clk(component, ctype);
147         }
148 }
149
150 static int snd_rpi_hifiberry_dacplusadc_init(struct snd_soc_pcm_runtime *rtd)
151 {
152         struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
153         struct pcm512x_priv *priv;
154
155         if (slave)
156                 snd_rpi_hifiberry_is_dacpro = false;
157         else
158                 snd_rpi_hifiberry_is_dacpro =
159                                 snd_rpi_hifiberry_dacplusadc_is_pro_card(component);
160
161         if (snd_rpi_hifiberry_is_dacpro) {
162                 struct snd_soc_dai_link *dai = rtd->dai_link;
163
164                 dai->name = "HiFiBerry ADCDAC+ Pro";
165                 dai->stream_name = "HiFiBerry ADCDAC+ Pro HiFi";
166                 dai->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
167                         | SND_SOC_DAIFMT_CBM_CFM;
168
169                 snd_soc_component_update_bits(component, PCM512x_BCLK_LRCLK_CFG, 0x31, 0x11);
170                 snd_soc_component_update_bits(component, PCM512x_MASTER_MODE, 0x03, 0x03);
171                 snd_soc_component_update_bits(component, PCM512x_MASTER_CLKDIV_2, 0x7f, 63);
172         } else {
173                 priv = snd_soc_component_get_drvdata(component);
174                 priv->sclk = ERR_PTR(-ENOENT);
175         }
176
177         snd_soc_component_update_bits(component, PCM512x_GPIO_EN, 0x08, 0x08);
178         snd_soc_component_update_bits(component, PCM512x_GPIO_OUTPUT_4, 0x0f, 0x02);
179         if (leds_off)
180                 snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x08, 0x00);
181         else
182                 snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1, 0x08, 0x08);
183
184         if (digital_gain_0db_limit) {
185                 int ret;
186                 struct snd_soc_card *card = rtd->card;
187
188                 ret = snd_soc_limit_volume(card, "Digital Playback Volume", 207);
189                 if (ret < 0)
190                         dev_warn(card->dev, "Failed to set volume limit: %d\n", ret);
191         }
192
193         return 0;
194 }
195
196 static int snd_rpi_hifiberry_dacplusadc_update_rate_den(
197         struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params)
198 {
199         struct snd_soc_pcm_runtime *rtd = substream->private_data;
200         struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
201         struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
202         struct snd_ratnum *rats_no_pll;
203         unsigned int num = 0, den = 0;
204         int err;
205
206         rats_no_pll = devm_kzalloc(rtd->dev, sizeof(*rats_no_pll), GFP_KERNEL);
207         if (!rats_no_pll)
208                 return -ENOMEM;
209
210         rats_no_pll->num = clk_get_rate(pcm512x->sclk) / 64;
211         rats_no_pll->den_min = 1;
212         rats_no_pll->den_max = 128;
213         rats_no_pll->den_step = 1;
214
215         err = snd_interval_ratnum(hw_param_interval(params,
216                 SNDRV_PCM_HW_PARAM_RATE), 1, rats_no_pll, &num, &den);
217         if (err >= 0 && den) {
218                 params->rate_num = num;
219                 params->rate_den = den;
220         }
221
222         devm_kfree(rtd->dev, rats_no_pll);
223         return 0;
224 }
225
226 static int snd_rpi_hifiberry_dacplusadc_hw_params(
227         struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params)
228 {
229         int ret = 0;
230         struct snd_soc_pcm_runtime *rtd = substream->private_data;
231         int channels = params_channels(params);
232         int width = 32;
233
234         if (snd_rpi_hifiberry_is_dacpro) {
235                 struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
236
237                 width = snd_pcm_format_physical_width(params_format(params));
238
239                 snd_rpi_hifiberry_dacplusadc_set_sclk(component,
240                         params_rate(params));
241
242                 ret = snd_rpi_hifiberry_dacplusadc_update_rate_den(
243                         substream, params);
244         }
245
246         ret = snd_soc_dai_set_bclk_ratio(asoc_rtd_to_cpu(rtd, 0), channels * width);
247         if (ret)
248                 return ret;
249         ret = snd_soc_dai_set_bclk_ratio(asoc_rtd_to_codec(rtd, 0), channels * width);
250         return ret;
251 }
252
253 static int hifiberry_dacplusadc_LED_cnt;
254
255 static int snd_rpi_hifiberry_dacplusadc_startup(
256         struct snd_pcm_substream *substream)
257 {
258         struct snd_soc_pcm_runtime *rtd = substream->private_data;
259         struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
260
261         if (leds_off)
262                 return 0;
263         snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1,
264                                          0x08, 0x08);
265         hifiberry_dacplusadc_LED_cnt++;
266         return 0;
267 }
268
269 static void snd_rpi_hifiberry_dacplusadc_shutdown(
270         struct snd_pcm_substream *substream)
271 {
272         struct snd_soc_pcm_runtime *rtd = substream->private_data;
273         struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
274
275         hifiberry_dacplusadc_LED_cnt--;
276         if (!hifiberry_dacplusadc_LED_cnt)
277                 snd_soc_component_update_bits(component, PCM512x_GPIO_CONTROL_1,
278                                                  0x08, 0x00);
279 }
280
281 /* machine stream operations */
282 static struct snd_soc_ops snd_rpi_hifiberry_dacplusadc_ops = {
283         .hw_params = snd_rpi_hifiberry_dacplusadc_hw_params,
284         .startup = snd_rpi_hifiberry_dacplusadc_startup,
285         .shutdown = snd_rpi_hifiberry_dacplusadc_shutdown,
286 };
287
288 SND_SOC_DAILINK_DEFS(hifi,
289         DAILINK_COMP_ARRAY(COMP_CPU("bcm2708-i2s.0")),
290         DAILINK_COMP_ARRAY(COMP_CODEC("pcm512x.1-004d", "pcm512x-hifi"),
291                            COMP_CODEC("dmic-codec", "dmic-hifi")),
292         DAILINK_COMP_ARRAY(COMP_PLATFORM("bcm2708-i2s.0")));
293
294 static struct snd_soc_dai_link snd_rpi_hifiberry_dacplusadc_dai[] = {
295 {
296         .name           = "HiFiBerry DAC+ADC",
297         .stream_name    = "HiFiBerry DAC+ADC HiFi",
298         .dai_fmt        = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
299                                 SND_SOC_DAIFMT_CBS_CFS,
300         .ops            = &snd_rpi_hifiberry_dacplusadc_ops,
301         .init           = snd_rpi_hifiberry_dacplusadc_init,
302         SND_SOC_DAILINK_REG(hifi),
303 },
304 };
305
306 /* audio machine driver */
307 static struct snd_soc_card snd_rpi_hifiberry_dacplusadc = {
308         .name         = "snd_rpi_hifiberry_dacplusadc",
309         .driver_name  = "HifiberryDacpAdc",
310         .owner        = THIS_MODULE,
311         .dai_link     = snd_rpi_hifiberry_dacplusadc_dai,
312         .num_links    = ARRAY_SIZE(snd_rpi_hifiberry_dacplusadc_dai),
313 };
314
315
316 static int snd_rpi_hifiberry_dacplusadc_probe(struct platform_device *pdev)
317 {
318         int ret = 0;
319
320         snd_rpi_hifiberry_dacplusadc.dev = &pdev->dev;
321         if (pdev->dev.of_node) {
322                 struct device_node *i2s_node;
323                 struct snd_soc_dai_link *dai;
324
325                 dai = &snd_rpi_hifiberry_dacplusadc_dai[0];
326                 i2s_node = of_parse_phandle(pdev->dev.of_node,
327                         "i2s-controller", 0);
328                 if (i2s_node) {
329                         dai->cpus->of_node = i2s_node;
330                         dai->platforms->of_node = i2s_node;
331                         dai->cpus->dai_name = NULL;
332                         dai->platforms->name = NULL;
333                 }
334         }
335         digital_gain_0db_limit = !of_property_read_bool(
336                 pdev->dev.of_node, "hifiberry,24db_digital_gain");
337         slave = of_property_read_bool(pdev->dev.of_node,
338                                         "hifiberry-dacplusadc,slave");
339         leds_off = of_property_read_bool(pdev->dev.of_node,
340                                         "hifiberry-dacplusadc,leds_off");
341
342         ret = devm_snd_soc_register_card(&pdev->dev,
343                                                  &snd_rpi_hifiberry_dacplusadc);
344         if (ret && ret != -EPROBE_DEFER)
345                 dev_err(&pdev->dev,
346                         "snd_soc_register_card() failed: %d\n", ret);
347
348         return ret;
349 }
350
351 static const struct of_device_id snd_rpi_hifiberry_dacplusadc_of_match[] = {
352         { .compatible = "hifiberry,hifiberry-dacplusadc", },
353         {},
354 };
355
356 MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_dacplusadc_of_match);
357
358 static struct platform_driver snd_rpi_hifiberry_dacplusadc_driver = {
359         .driver = {
360                 .name   = "snd-rpi-hifiberry-dacplusadc",
361                 .owner  = THIS_MODULE,
362                 .of_match_table = snd_rpi_hifiberry_dacplusadc_of_match,
363         },
364         .probe          = snd_rpi_hifiberry_dacplusadc_probe,
365 };
366
367 static int __init hifiberry_dacplusadc_init(void)
368 {
369         int ret;
370
371         dmic_codec_dev = platform_device_register_simple("dmic-codec", -1, NULL,
372                                                          0);
373         if (IS_ERR(dmic_codec_dev)) {
374                 pr_err("%s: dmic-codec device registration failed\n", __func__);
375                 return PTR_ERR(dmic_codec_dev);
376         }
377
378         ret = platform_driver_register(&snd_rpi_hifiberry_dacplusadc_driver);
379         if (ret) {
380                 pr_err("%s: platform driver registration failed\n", __func__);
381                 platform_device_unregister(dmic_codec_dev);
382         }
383
384         return ret;
385 }
386 module_init(hifiberry_dacplusadc_init);
387
388 static void __exit hifiberry_dacplusadc_exit(void)
389 {
390         platform_driver_unregister(&snd_rpi_hifiberry_dacplusadc_driver);
391         platform_device_unregister(dmic_codec_dev);
392 }
393 module_exit(hifiberry_dacplusadc_exit);
394
395 MODULE_AUTHOR("Joerg Schambacher <joscha@schambacher.com>");
396 MODULE_AUTHOR("Daniel Matuschek <daniel@hifiberry.com>");
397 MODULE_DESCRIPTION("ASoC Driver for HiFiBerry DAC+ADC");
398 MODULE_LICENSE("GPL v2");