ASoC: SOC: Add support jh7110 audio driver
[platform/kernel/linux-starfive.git] / sound / soc / starfive / starfive_spdif.c
1 /**
2   ******************************************************************************
3   * @file  sf_spdif.c
4   * @author  StarFive Technology
5   * @version  V1.0
6   * @date  05/27/2021
7   * @brief
8   ******************************************************************************
9   * @copy
10   *
11   * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
12   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
13   * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
14   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
15   * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
16   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
17   *
18   * <h2><center>&copy; COPYRIGHT 20120 Shanghai StarFive Technology Co., Ltd. </center></h2>
19   */
20
21 #include <linux/init.h>
22 #include <linux/kernel.h>
23 #include <linux/module.h>
24 #include <linux/platform_device.h>
25 #include <linux/slab.h>
26 #include <linux/of.h>
27 #include <linux/clk.h>
28 #include <linux/regmap.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/initval.h>
35 #include <sound/dmaengine_pcm.h>
36 #include "starfive_spdif.h"
37
38 static irqreturn_t spdif_irq_handler(int irq, void *dev_id)
39 {
40         struct sf_spdif_dev *dev = dev_id;
41         bool irq_valid = false;
42         unsigned int intr;
43         unsigned int stat;
44
45         regmap_read(dev->regmap, SPDIF_INT_REG, &intr);
46         regmap_read(dev->regmap, SPDIF_STAT_REG, &stat);
47         regmap_update_bits(dev->regmap, SPDIF_CTRL,
48                 SPDIF_MASK_ENABLE, 0);
49         regmap_update_bits(dev->regmap, SPDIF_INT_REG,
50                 SPDIF_INT_REG_BIT, 0);
51
52         if ((stat & SPDIF_EMPTY_FLAG) || (stat & SPDIF_AEMPTY_FLAG)) {
53                 sf_spdif_pcm_push_tx(dev);
54                 irq_valid = true;
55         }
56
57         if ((stat & SPDIF_FULL_FLAG) || (stat & SPDIF_AFULL_FLAG)) {
58                 sf_spdif_pcm_pop_rx(dev);
59                 irq_valid = true;
60         }
61
62         if (stat & SPDIF_PARITY_FLAG) {
63                 irq_valid = true;
64         }
65
66         if (stat & SPDIF_UNDERR_FLAG) {
67                 irq_valid = true;
68         }
69
70         if (stat & SPDIF_OVRERR_FLAG) {
71                 irq_valid = true;
72         }
73
74         if (stat & SPDIF_SYNCERR_FLAG) {
75                 irq_valid = true;
76         }
77
78         if (stat & SPDIF_LOCK_FLAG) {
79                 irq_valid = true;
80         }
81
82         if (stat & SPDIF_BEGIN_FLAG) {
83                 irq_valid = true;
84         }
85
86         if (stat & SPDIF_RIGHT_LEFT) {
87                 irq_valid = true;
88         }
89
90         regmap_update_bits(dev->regmap, SPDIF_CTRL,
91                 SPDIF_MASK_ENABLE, SPDIF_MASK_ENABLE);
92
93         if (irq_valid)
94                 return IRQ_HANDLED;
95         else
96                 return IRQ_NONE;
97 }
98
99 static int sf_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
100         struct snd_soc_dai *dai)
101 {
102         struct sf_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
103         bool tx;
104
105         tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
106         if (tx) {
107                 /* tx mode */
108                 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
109                         SPDIF_TR_MODE, SPDIF_TR_MODE);
110
111                 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
112                         SPDIF_MASK_FIFO, SPDIF_EMPTY_MASK | SPDIF_AEMPTY_MASK);
113         } else {
114                 /* rx mode */
115                 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
116                         SPDIF_TR_MODE, 0);
117
118                 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
119                         SPDIF_MASK_FIFO, SPDIF_FULL_MASK | SPDIF_AFULL_MASK);
120         }
121
122         switch (cmd) {
123         case SNDRV_PCM_TRIGGER_START:
124         case SNDRV_PCM_TRIGGER_RESUME:
125         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
126                 /* clock recovery form the SPDIF data stream  0:clk_enable */
127                 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
128                         SPDIF_CLK_ENABLE, 0);
129
130                 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
131                         SPDIF_ENABLE, SPDIF_ENABLE);
132                 break;
133         case SNDRV_PCM_TRIGGER_STOP:
134         case SNDRV_PCM_TRIGGER_SUSPEND:
135         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
136                 /* clock recovery form the SPDIF data stream  1:power save mode */
137                 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
138                         SPDIF_CLK_ENABLE, SPDIF_CLK_ENABLE);
139
140                 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
141                         SPDIF_ENABLE, 0);
142                 break;
143         default:
144                 printk(KERN_ERR "%s L.%d cmd:%d\n", __func__, __LINE__, cmd);
145                 return -EINVAL;
146         }
147
148         return 0;
149 }
150
151 static int sf_spdif_hw_params(struct snd_pcm_substream *substream,
152         struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
153 {
154         struct sf_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
155         unsigned int channels;
156         unsigned int rate;
157         unsigned int format;
158         unsigned int tsamplerate;
159
160         channels = params_channels(params);
161         rate = params_rate(params);
162         format = params_format(params);
163
164         switch (channels) {
165         case 2:
166                 break;
167         default:
168                 dev_err(dai->dev, "invalid channels number\n");
169                 return -EINVAL;
170         }
171
172         switch (format) {
173         case SNDRV_PCM_FORMAT_S16_LE:
174         case SNDRV_PCM_FORMAT_S24_LE:
175         case SNDRV_PCM_FORMAT_S32_LE:
176                 break;
177         default:
178                 dev_err(spdif->dev, "invalid format\n");
179                 return -EINVAL;
180         }
181
182         switch (rate) {
183         case 8000:
184         case 11025:
185         case 16000:
186         case 22050:
187                 break;
188         default:
189                 printk(KERN_ERR "channel:%d sample rate:%d\n", channels, rate);
190                 return -EINVAL;
191         }
192
193         /* 4096000/128=32000 */
194         tsamplerate = (32000 + rate/2)/rate - 1;
195
196         if (rate < 3) {
197                 return -EINVAL;
198         }
199
200         /* transmission sample rate */
201         regmap_update_bits(spdif->regmap, SPDIF_CTRL, 0xFF, tsamplerate);
202
203         return 0;
204 }
205
206 static int sf_spdif_dai_probe(struct snd_soc_dai *dai)
207 {
208         struct sf_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
209
210         #if 0
211         spdif->play_dma_data.addr = (dma_addr_t)spdif->spdif_base + SPDIF_FIFO_ADDR;
212         spdif->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
213         spdif->play_dma_data.fifo_size = 16;
214         spdif->play_dma_data.maxburst = 16;
215         spdif->capture_dma_data.addr = (dma_addr_t)spdif->spdif_base + SPDIF_FIFO_ADDR;
216         spdif->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
217         spdif->capture_dma_data.fifo_size = 16;
218         spdif->capture_dma_data.maxburst = 16;
219         snd_soc_dai_init_dma_data(dai, &spdif->play_dma_data, &spdif->capture_dma_data);
220         snd_soc_dai_set_drvdata(dai, spdif);
221         #endif
222
223         /* reset */
224         regmap_update_bits(spdif->regmap, SPDIF_CTRL,
225                 SPDIF_ENABLE | SPDIF_SFR_ENABLE | SPDIF_FIFO_ENABLE, 0);
226
227         /* clear irq */
228         regmap_update_bits(spdif->regmap, SPDIF_INT_REG,
229                 SPDIF_INT_REG_BIT, 0);
230
231         /* power save mode */
232         regmap_update_bits(spdif->regmap, SPDIF_CTRL,
233                 SPDIF_CLK_ENABLE, SPDIF_CLK_ENABLE);
234
235         /* power save mode */
236         regmap_update_bits(spdif->regmap, SPDIF_CTRL,
237                 SPDIF_CLK_ENABLE, SPDIF_CLK_ENABLE);
238
239         regmap_update_bits(spdif->regmap, SPDIF_CTRL,
240                 SPDIF_PARITCHECK|SPDIF_VALIDITYCHECK|SPDIF_DUPLICATE,
241                 SPDIF_PARITCHECK|SPDIF_VALIDITYCHECK|SPDIF_DUPLICATE);
242
243         regmap_update_bits(spdif->regmap, SPDIF_CTRL,
244                 SPDIF_SETPREAMBB, SPDIF_SETPREAMBB);
245
246         regmap_update_bits(spdif->regmap, SPDIF_INT_REG,
247                 0x1FFF<<SPDIF_PREAMBLEDEL, 0x3<<SPDIF_PREAMBLEDEL);
248
249         regmap_update_bits(spdif->regmap, SPDIF_FIFO_CTRL,
250                 0xFFFFFFFF, 0x20|(0x20<<SPDIF_AFULL_THRESHOLD));
251
252         regmap_update_bits(spdif->regmap, SPDIF_CTRL,
253                 SPDIF_PARITYGEN, SPDIF_PARITYGEN);
254
255         regmap_update_bits(spdif->regmap, SPDIF_CTRL,
256                 SPDIF_MASK_ENABLE, SPDIF_MASK_ENABLE);
257
258         /* APB access to FIFO enable, disable if use DMA/FIFO */
259         regmap_update_bits(spdif->regmap, SPDIF_CTRL,
260                 SPDIF_USE_FIFO_IF, 0);
261
262         /* two channel */
263         regmap_update_bits(spdif->regmap, SPDIF_CTRL,
264                 SPDIF_CHANNEL_MODE, 0);
265
266         return 0;
267 }
268
269 static const struct snd_soc_dai_ops sf_spdif_dai_ops = {
270         .trigger = sf_spdif_trigger,
271         .hw_params = sf_spdif_hw_params,
272 };
273
274 #define SF_PCM_RATE_44100_192000  (SNDRV_PCM_RATE_44100 | \
275                                                                         SNDRV_PCM_RATE_48000 | \
276                                                                         SNDRV_PCM_RATE_96000 | \
277                                                                         SNDRV_PCM_RATE_192000)
278
279 #define SF_PCM_RATE_8000_22050  (SNDRV_PCM_RATE_8000 | \
280                                                                         SNDRV_PCM_RATE_11025 | \
281                                                                         SNDRV_PCM_RATE_16000 | \
282                                                                         SNDRV_PCM_RATE_22050)
283
284 static struct snd_soc_dai_driver sf_spdif_dai = {
285         .name = "spdif",
286         .id = 0,
287         .probe = sf_spdif_dai_probe,
288         .playback = {
289                 .stream_name = "Playback",
290                 .channels_min = 2,
291                 .channels_max = 2,
292                 .rates = SF_PCM_RATE_8000_22050,
293                 .formats = SNDRV_PCM_FMTBIT_S16_LE \
294                                         |SNDRV_PCM_FMTBIT_S24_LE \
295                                         |SNDRV_PCM_FMTBIT_S32_LE,
296         },
297         .capture =  {
298                 .stream_name = "Capture",
299                 .channels_min = 2,
300                 .channels_max = 2,
301                 .rates = SF_PCM_RATE_8000_22050,
302                 .formats = SNDRV_PCM_FMTBIT_S16_LE \
303                                         |SNDRV_PCM_FMTBIT_S24_LE \
304                                         |SNDRV_PCM_FMTBIT_S32_LE,
305         },
306         .ops = &sf_spdif_dai_ops,
307         .symmetric_rate = 1,
308 };
309
310 static const struct snd_soc_component_driver sf_spdif_component = {
311         .name = "sf-spdif",
312 };
313
314 static const struct regmap_config sf_spdif_regmap_config = {
315         .reg_bits = 32,
316         .reg_stride = 4,
317         .val_bits = 32,
318         .max_register = 0x200,
319 };
320
321 static int sf_spdif_probe(struct platform_device *pdev)
322 {
323         struct sf_spdif_dev *spdif;
324         struct resource *res;
325         void __iomem *base;
326         int ret;
327         int irq;
328
329         spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
330         if (!spdif)
331                 return -ENOMEM;
332
333         platform_set_drvdata(pdev, spdif);
334
335         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
336         base = devm_ioremap_resource(&pdev->dev, res);
337         if (IS_ERR(base))
338                 return PTR_ERR(base);
339
340         spdif->spdif_base = base;
341         spdif->regmap = devm_regmap_init_mmio(&pdev->dev, spdif->spdif_base,
342                                             &sf_spdif_regmap_config);
343         if (IS_ERR(spdif->regmap))
344                 return PTR_ERR(spdif->regmap);
345
346         spdif->dev = &pdev->dev;
347         spdif->fifo_th = 16;
348
349         irq = platform_get_irq(pdev, 0);
350         if (irq >= 0) {
351                 ret = devm_request_irq(&pdev->dev, irq, spdif_irq_handler, 0,
352                                 pdev->name, spdif);
353                 if (ret < 0) {
354                         dev_err(&pdev->dev, "failed to request irq\n");
355                         return ret;
356                 }
357         }
358
359         ret = devm_snd_soc_register_component(&pdev->dev, &sf_spdif_component,
360                                          &sf_spdif_dai, 1);
361         if (ret)
362                 goto err_clk_disable;
363
364         if (irq >= 0) {
365                 ret = sf_spdif_pcm_register(pdev);
366                 spdif->use_pio = true;
367         } else {
368                 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
369                                         0);
370                 spdif->use_pio = false;
371         }
372
373         if (ret)
374                 goto err_clk_disable;
375
376         return 0;
377
378 err_clk_disable:
379         return ret;
380 }
381
382 static const struct of_device_id sf_spdif_of_match[] = {
383         { .compatible = "starfive,sf-spdif", },
384         {},
385 };
386 MODULE_DEVICE_TABLE(of, sf_spdif_of_match);
387
388 static struct platform_driver sf_spdif_driver = {
389         .driver = {
390                 .name = "sf-spdif",
391                 .of_match_table = sf_spdif_of_match,
392         },
393         .probe = sf_spdif_probe,
394 };
395 module_platform_driver(sf_spdif_driver);
396
397 MODULE_AUTHOR("michael.yan <michael.yan@starfive.com>");
398 MODULE_DESCRIPTION("starfive SPDIF driver");
399 MODULE_LICENSE("GPL v2");