ASoC: rockchip: add support for rk3328 spdif
[firefly-linux-kernel-4.4.55.git] / sound / soc / rockchip / rockchip_spdif.c
1 /* sound/soc/rockchip/rk_spdif.c
2  *
3  * ALSA SoC Audio Layer - Rockchip I2S Controller driver
4  *
5  * Copyright (c) 2014 Rockchip Electronics Co. Ltd.
6  * Author: Jianqun <jay.xu@rock-chips.com>
7  * Copyright (c) 2015 Collabora Ltd.
8  * Author: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  */
14
15 #include <linux/module.h>
16 #include <linux/delay.h>
17 #include <linux/of_gpio.h>
18 #include <linux/clk.h>
19 #include <linux/pm_runtime.h>
20 #include <linux/mfd/syscon.h>
21 #include <linux/regmap.h>
22 #include <sound/pcm_params.h>
23 #include <sound/dmaengine_pcm.h>
24
25 #include "rockchip_spdif.h"
26
27 enum rk_spdif_type {
28         RK_SPDIF_RK3066,
29         RK_SPDIF_RK3188,
30         RK_SPDIF_RK3288,
31         RK_SPDIF_RK3366,
32 };
33
34 #define RK3288_GRF_SOC_CON2 0x24c
35
36 struct rk_spdif_dev {
37         struct device *dev;
38
39         struct clk *mclk;
40         struct clk *hclk;
41
42         struct snd_dmaengine_dai_dma_data playback_dma_data;
43
44         struct regmap *regmap;
45 };
46
47 static const struct of_device_id rk_spdif_match[] = {
48         { .compatible = "rockchip,rk3066-spdif",
49           .data = (void *)RK_SPDIF_RK3066 },
50         { .compatible = "rockchip,rk3188-spdif",
51           .data = (void *)RK_SPDIF_RK3188 },
52         { .compatible = "rockchip,rk3288-spdif",
53           .data = (void *)RK_SPDIF_RK3288 },
54         { .compatible = "rockchip,rk3328-spdif",
55           .data = (void *)RK_SPDIF_RK3366 },
56         { .compatible = "rockchip,rk3366-spdif",
57           .data = (void *)RK_SPDIF_RK3366 },
58         { .compatible = "rockchip,rk3368-spdif",
59           .data = (void *)RK_SPDIF_RK3366 },
60         { .compatible = "rockchip,rk3399-spdif",
61           .data = (void *)RK_SPDIF_RK3366 },
62         {},
63 };
64 MODULE_DEVICE_TABLE(of, rk_spdif_match);
65
66 static int rk_spdif_runtime_suspend(struct device *dev)
67 {
68         struct rk_spdif_dev *spdif = dev_get_drvdata(dev);
69
70         clk_disable_unprepare(spdif->mclk);
71         clk_disable_unprepare(spdif->hclk);
72
73         return 0;
74 }
75
76 static int rk_spdif_runtime_resume(struct device *dev)
77 {
78         struct rk_spdif_dev *spdif = dev_get_drvdata(dev);
79         int ret;
80
81         ret = clk_prepare_enable(spdif->mclk);
82         if (ret) {
83                 dev_err(spdif->dev, "mclk clock enable failed %d\n", ret);
84                 return ret;
85         }
86
87         ret = clk_prepare_enable(spdif->hclk);
88         if (ret) {
89                 dev_err(spdif->dev, "hclk clock enable failed %d\n", ret);
90                 return ret;
91         }
92
93         return 0;
94 }
95
96 static int rk_spdif_hw_params(struct snd_pcm_substream *substream,
97                                   struct snd_pcm_hw_params *params,
98                                   struct snd_soc_dai *dai)
99 {
100         struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
101         unsigned int val = SPDIF_CFGR_HALFWORD_ENABLE;
102         int srate, mclk;
103         int ret;
104
105         srate = params_rate(params);
106         switch (srate) {
107         case 32000:
108         case 48000:
109         case 96000:
110                 mclk = 96000 * 128; /* 12288000 hz */
111                 break;
112         case 44100:
113                 mclk = 44100 * 256; /* 11289600 hz */
114                 break;
115         case 192000:
116                 mclk = 192000 * 128; /* 24576000 hz */
117                 break;
118         default:
119                 return -EINVAL;
120         }
121
122         switch (params_format(params)) {
123         case SNDRV_PCM_FORMAT_S16_LE:
124                 val |= SPDIF_CFGR_VDW_16;
125                 break;
126         case SNDRV_PCM_FORMAT_S20_3LE:
127                 val |= SPDIF_CFGR_VDW_20;
128                 break;
129         case SNDRV_PCM_FORMAT_S24_LE:
130                 val |= SPDIF_CFGR_VDW_24;
131                 break;
132         default:
133                 return -EINVAL;
134         }
135
136         /* Set clock and calculate divider */
137         ret = clk_set_rate(spdif->mclk, mclk);
138         if (ret != 0) {
139                 dev_err(spdif->dev, "Failed to set module clock rate: %d\n",
140                         ret);
141                 return ret;
142         }
143
144         val |= SPDIF_CFGR_CLK_DIV(mclk/(srate * 256));
145         ret = regmap_update_bits(spdif->regmap, SPDIF_CFGR,
146                 SPDIF_CFGR_CLK_DIV_MASK | SPDIF_CFGR_HALFWORD_ENABLE |
147                 SDPIF_CFGR_VDW_MASK,
148                 val);
149
150         return ret;
151 }
152
153 static int rk_spdif_trigger(struct snd_pcm_substream *substream,
154                                 int cmd, struct snd_soc_dai *dai)
155 {
156         struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
157         int ret;
158
159         switch (cmd) {
160         case SNDRV_PCM_TRIGGER_START:
161         case SNDRV_PCM_TRIGGER_RESUME:
162         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
163                 ret = regmap_update_bits(spdif->regmap, SPDIF_DMACR,
164                                    SPDIF_DMACR_TDE_ENABLE |
165                                    SPDIF_DMACR_TDL_MASK,
166                                    SPDIF_DMACR_TDE_ENABLE |
167                                    SPDIF_DMACR_TDL(16));
168
169                 if (ret != 0)
170                         return ret;
171
172                 ret = regmap_update_bits(spdif->regmap, SPDIF_XFER,
173                                    SPDIF_XFER_TXS_START,
174                                    SPDIF_XFER_TXS_START);
175                 break;
176         case SNDRV_PCM_TRIGGER_SUSPEND:
177         case SNDRV_PCM_TRIGGER_STOP:
178         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
179                 ret = regmap_update_bits(spdif->regmap, SPDIF_DMACR,
180                                    SPDIF_DMACR_TDE_ENABLE,
181                                    SPDIF_DMACR_TDE_DISABLE);
182
183                 if (ret != 0)
184                         return ret;
185
186                 ret = regmap_update_bits(spdif->regmap, SPDIF_XFER,
187                                    SPDIF_XFER_TXS_START,
188                                    SPDIF_XFER_TXS_STOP);
189                 break;
190         default:
191                 ret = -EINVAL;
192                 break;
193         }
194
195         return ret;
196 }
197
198 static int rk_spdif_dai_probe(struct snd_soc_dai *dai)
199 {
200         struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
201
202         dai->playback_dma_data = &spdif->playback_dma_data;
203
204         return 0;
205 }
206
207 static const struct snd_soc_dai_ops rk_spdif_dai_ops = {
208         .hw_params = rk_spdif_hw_params,
209         .trigger = rk_spdif_trigger,
210 };
211
212 static struct snd_soc_dai_driver rk_spdif_dai = {
213         .probe = rk_spdif_dai_probe,
214         .playback = {
215                 .stream_name = "Playback",
216                 .channels_min = 2,
217                 .channels_max = 2,
218                 .rates = (SNDRV_PCM_RATE_32000 |
219                           SNDRV_PCM_RATE_44100 |
220                           SNDRV_PCM_RATE_48000 |
221                           SNDRV_PCM_RATE_96000 |
222                           SNDRV_PCM_RATE_192000),
223                 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
224                             SNDRV_PCM_FMTBIT_S20_3LE |
225                             SNDRV_PCM_FMTBIT_S24_LE),
226         },
227         .ops = &rk_spdif_dai_ops,
228 };
229
230 static const struct snd_soc_component_driver rk_spdif_component = {
231         .name = "rockchip-spdif",
232 };
233
234 static bool rk_spdif_wr_reg(struct device *dev, unsigned int reg)
235 {
236         switch (reg) {
237         case SPDIF_CFGR:
238         case SPDIF_DMACR:
239         case SPDIF_INTCR:
240         case SPDIF_XFER:
241         case SPDIF_SMPDR:
242                 return true;
243         default:
244                 return false;
245         }
246 }
247
248 static bool rk_spdif_rd_reg(struct device *dev, unsigned int reg)
249 {
250         switch (reg) {
251         case SPDIF_CFGR:
252         case SPDIF_SDBLR:
253         case SPDIF_INTCR:
254         case SPDIF_INTSR:
255         case SPDIF_XFER:
256                 return true;
257         default:
258                 return false;
259         }
260 }
261
262 static bool rk_spdif_volatile_reg(struct device *dev, unsigned int reg)
263 {
264         switch (reg) {
265         case SPDIF_INTSR:
266         case SPDIF_SDBLR:
267                 return true;
268         default:
269                 return false;
270         }
271 }
272
273 static const struct regmap_config rk_spdif_regmap_config = {
274         .reg_bits = 32,
275         .reg_stride = 4,
276         .val_bits = 32,
277         .max_register = SPDIF_SMPDR,
278         .writeable_reg = rk_spdif_wr_reg,
279         .readable_reg = rk_spdif_rd_reg,
280         .volatile_reg = rk_spdif_volatile_reg,
281         .cache_type = REGCACHE_FLAT,
282 };
283
284 static int rk_spdif_probe(struct platform_device *pdev)
285 {
286         struct device_node *np = pdev->dev.of_node;
287         struct rk_spdif_dev *spdif;
288         const struct of_device_id *match;
289         struct resource *res;
290         void __iomem *regs;
291         int ret;
292
293         match = of_match_node(rk_spdif_match, np);
294         if (match->data == (void *)RK_SPDIF_RK3288) {
295                 struct regmap *grf;
296
297                 grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
298                 if (IS_ERR(grf)) {
299                         dev_err(&pdev->dev,
300                                 "rockchip_spdif missing 'rockchip,grf' \n");
301                         return PTR_ERR(grf);
302                 }
303
304                 /* Select the 8 channel SPDIF solution on RK3288 as
305                  * the 2 channel one does not appear to work
306                  */
307                 regmap_write(grf, RK3288_GRF_SOC_CON2, BIT(1) << 16);
308         }
309
310         spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
311         if (!spdif)
312                 return -ENOMEM;
313
314         spdif->hclk = devm_clk_get(&pdev->dev, "hclk");
315         if (IS_ERR(spdif->hclk)) {
316                 dev_err(&pdev->dev, "Can't retrieve rk_spdif bus clock\n");
317                 return PTR_ERR(spdif->hclk);
318         }
319         ret = clk_prepare_enable(spdif->hclk);
320         if (ret) {
321                 dev_err(spdif->dev, "hclock enable failed %d\n", ret);
322                 return ret;
323         }
324
325         spdif->mclk = devm_clk_get(&pdev->dev, "mclk");
326         if (IS_ERR(spdif->mclk)) {
327                 dev_err(&pdev->dev, "Can't retrieve rk_spdif master clock\n");
328                 return PTR_ERR(spdif->mclk);
329         }
330
331         ret = clk_prepare_enable(spdif->mclk);
332         if (ret) {
333                 dev_err(spdif->dev, "clock enable failed %d\n", ret);
334                 return ret;
335         }
336
337         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
338         regs = devm_ioremap_resource(&pdev->dev, res);
339         if (IS_ERR(regs))
340                 return PTR_ERR(regs);
341
342         spdif->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "hclk", regs,
343                                                   &rk_spdif_regmap_config);
344         if (IS_ERR(spdif->regmap)) {
345                 dev_err(&pdev->dev,
346                         "Failed to initialise managed register map\n");
347                 return PTR_ERR(spdif->regmap);
348         }
349
350         spdif->playback_dma_data.addr = res->start + SPDIF_SMPDR;
351         spdif->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
352         spdif->playback_dma_data.maxburst = 4;
353
354         spdif->dev = &pdev->dev;
355         dev_set_drvdata(&pdev->dev, spdif);
356
357         pm_runtime_set_active(&pdev->dev);
358         pm_runtime_enable(&pdev->dev);
359         pm_request_idle(&pdev->dev);
360
361         ret = devm_snd_soc_register_component(&pdev->dev,
362                                               &rk_spdif_component,
363                                               &rk_spdif_dai, 1);
364         if (ret) {
365                 dev_err(&pdev->dev, "Could not register DAI\n");
366                 goto err_pm_runtime;
367         }
368
369         ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
370         if (ret) {
371                 dev_err(&pdev->dev, "Could not register PCM\n");
372                 goto err_pm_runtime;
373         }
374
375         return 0;
376
377 err_pm_runtime:
378         pm_runtime_disable(&pdev->dev);
379
380         return ret;
381 }
382
383 static int rk_spdif_remove(struct platform_device *pdev)
384 {
385         struct rk_spdif_dev *spdif = dev_get_drvdata(&pdev->dev);
386
387         pm_runtime_disable(&pdev->dev);
388         if (!pm_runtime_status_suspended(&pdev->dev))
389                 rk_spdif_runtime_suspend(&pdev->dev);
390
391         clk_disable_unprepare(spdif->mclk);
392         clk_disable_unprepare(spdif->hclk);
393
394         return 0;
395 }
396
397 #ifdef CONFIG_PM_SLEEP
398 static int rockchip_spdif_suspend(struct device *dev)
399 {
400         struct rk_spdif_dev *spdif = dev_get_drvdata(dev);
401
402         regcache_mark_dirty(spdif->regmap);
403
404         return 0;
405 }
406
407 static int rockchip_spdif_resume(struct device *dev)
408 {
409         struct rk_spdif_dev *spdif = dev_get_drvdata(dev);
410         int ret;
411
412         ret = pm_runtime_get_sync(dev);
413         if (ret < 0)
414                 return ret;
415         ret = regcache_sync(spdif->regmap);
416         pm_runtime_put(dev);
417
418         return ret;
419 }
420 #endif
421
422 static const struct dev_pm_ops rk_spdif_pm_ops = {
423         SET_RUNTIME_PM_OPS(rk_spdif_runtime_suspend, rk_spdif_runtime_resume,
424                            NULL)
425         SET_SYSTEM_SLEEP_PM_OPS(rockchip_spdif_suspend, rockchip_spdif_resume)
426 };
427
428 static struct platform_driver rk_spdif_driver = {
429         .probe = rk_spdif_probe,
430         .remove = rk_spdif_remove,
431         .driver = {
432                 .name = "rockchip-spdif",
433                 .of_match_table = of_match_ptr(rk_spdif_match),
434                 .pm = &rk_spdif_pm_ops,
435         },
436 };
437 module_platform_driver(rk_spdif_driver);
438
439 MODULE_ALIAS("platform:rockchip-spdif");
440 MODULE_DESCRIPTION("ROCKCHIP SPDIF transceiver Interface");
441 MODULE_AUTHOR("Sjoerd Simons <sjoerd.simons@collabora.co.uk>");
442 MODULE_LICENSE("GPL v2");