2 ******************************************************************************
4 * @author StarFive Technology
8 ******************************************************************************
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.
18 * <h2><center>© COPYRIGHT 20120 Shanghai StarFive Technology Co., Ltd. </center></h2>
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>
27 #include <linux/clk.h>
28 #include <linux/regmap.h>
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"
38 static irqreturn_t spdif_irq_handler(int irq, void *dev_id)
40 struct sf_spdif_dev *dev = dev_id;
41 bool irq_valid = false;
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);
52 if ((stat & SPDIF_EMPTY_FLAG) || (stat & SPDIF_AEMPTY_FLAG)) {
53 sf_spdif_pcm_push_tx(dev);
57 if ((stat & SPDIF_FULL_FLAG) || (stat & SPDIF_AFULL_FLAG)) {
58 sf_spdif_pcm_pop_rx(dev);
62 if (stat & SPDIF_PARITY_FLAG) {
66 if (stat & SPDIF_UNDERR_FLAG) {
70 if (stat & SPDIF_OVRERR_FLAG) {
74 if (stat & SPDIF_SYNCERR_FLAG) {
78 if (stat & SPDIF_LOCK_FLAG) {
82 if (stat & SPDIF_BEGIN_FLAG) {
86 if (stat & SPDIF_RIGHT_LEFT) {
90 regmap_update_bits(dev->regmap, SPDIF_CTRL,
91 SPDIF_MASK_ENABLE, SPDIF_MASK_ENABLE);
99 static int sf_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
100 struct snd_soc_dai *dai)
102 struct sf_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
105 tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
108 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
109 SPDIF_TR_MODE, SPDIF_TR_MODE);
111 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
112 SPDIF_MASK_FIFO, SPDIF_EMPTY_MASK | SPDIF_AEMPTY_MASK);
115 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
118 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
119 SPDIF_MASK_FIFO, SPDIF_FULL_MASK | SPDIF_AFULL_MASK);
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);
130 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
131 SPDIF_ENABLE, SPDIF_ENABLE);
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);
140 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
144 printk(KERN_ERR "%s L.%d cmd:%d\n", __func__, __LINE__, cmd);
151 static int sf_spdif_hw_params(struct snd_pcm_substream *substream,
152 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
154 struct sf_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
155 unsigned int channels;
158 unsigned int tsamplerate;
160 channels = params_channels(params);
161 rate = params_rate(params);
162 format = params_format(params);
168 dev_err(dai->dev, "invalid channels number\n");
173 case SNDRV_PCM_FORMAT_S16_LE:
174 case SNDRV_PCM_FORMAT_S24_LE:
175 case SNDRV_PCM_FORMAT_S32_LE:
178 dev_err(spdif->dev, "invalid format\n");
189 printk(KERN_ERR "channel:%d sample rate:%d\n", channels, rate);
193 /* 4096000/128=32000 */
194 tsamplerate = (32000 + rate/2)/rate - 1;
200 /* transmission sample rate */
201 regmap_update_bits(spdif->regmap, SPDIF_CTRL, 0xFF, tsamplerate);
206 static int sf_spdif_dai_probe(struct snd_soc_dai *dai)
208 struct sf_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
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);
224 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
225 SPDIF_ENABLE | SPDIF_SFR_ENABLE | SPDIF_FIFO_ENABLE, 0);
228 regmap_update_bits(spdif->regmap, SPDIF_INT_REG,
229 SPDIF_INT_REG_BIT, 0);
231 /* power save mode */
232 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
233 SPDIF_CLK_ENABLE, SPDIF_CLK_ENABLE);
235 /* power save mode */
236 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
237 SPDIF_CLK_ENABLE, SPDIF_CLK_ENABLE);
239 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
240 SPDIF_PARITCHECK|SPDIF_VALIDITYCHECK|SPDIF_DUPLICATE,
241 SPDIF_PARITCHECK|SPDIF_VALIDITYCHECK|SPDIF_DUPLICATE);
243 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
244 SPDIF_SETPREAMBB, SPDIF_SETPREAMBB);
246 regmap_update_bits(spdif->regmap, SPDIF_INT_REG,
247 0x1FFF<<SPDIF_PREAMBLEDEL, 0x3<<SPDIF_PREAMBLEDEL);
249 regmap_update_bits(spdif->regmap, SPDIF_FIFO_CTRL,
250 0xFFFFFFFF, 0x20|(0x20<<SPDIF_AFULL_THRESHOLD));
252 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
253 SPDIF_PARITYGEN, SPDIF_PARITYGEN);
255 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
256 SPDIF_MASK_ENABLE, SPDIF_MASK_ENABLE);
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);
263 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
264 SPDIF_CHANNEL_MODE, 0);
269 static const struct snd_soc_dai_ops sf_spdif_dai_ops = {
270 .trigger = sf_spdif_trigger,
271 .hw_params = sf_spdif_hw_params,
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)
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)
284 static struct snd_soc_dai_driver sf_spdif_dai = {
287 .probe = sf_spdif_dai_probe,
289 .stream_name = "Playback",
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,
298 .stream_name = "Capture",
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,
306 .ops = &sf_spdif_dai_ops,
310 static const struct snd_soc_component_driver sf_spdif_component = {
314 static const struct regmap_config sf_spdif_regmap_config = {
318 .max_register = 0x200,
321 static int sf_spdif_probe(struct platform_device *pdev)
323 struct sf_spdif_dev *spdif;
324 struct resource *res;
329 spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
333 platform_set_drvdata(pdev, spdif);
335 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
336 base = devm_ioremap_resource(&pdev->dev, res);
338 return PTR_ERR(base);
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);
346 spdif->dev = &pdev->dev;
349 irq = platform_get_irq(pdev, 0);
351 ret = devm_request_irq(&pdev->dev, irq, spdif_irq_handler, 0,
354 dev_err(&pdev->dev, "failed to request irq\n");
359 ret = devm_snd_soc_register_component(&pdev->dev, &sf_spdif_component,
362 goto err_clk_disable;
365 ret = sf_spdif_pcm_register(pdev);
366 spdif->use_pio = true;
368 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
370 spdif->use_pio = false;
374 goto err_clk_disable;
382 static const struct of_device_id sf_spdif_of_match[] = {
383 { .compatible = "starfive,sf-spdif", },
386 MODULE_DEVICE_TABLE(of, sf_spdif_of_match);
388 static struct platform_driver sf_spdif_driver = {
391 .of_match_table = sf_spdif_of_match,
393 .probe = sf_spdif_probe,
395 module_platform_driver(sf_spdif_driver);
397 MODULE_AUTHOR("michael.yan <michael.yan@starfive.com>");
398 MODULE_DESCRIPTION("starfive SPDIF driver");
399 MODULE_LICENSE("GPL v2");