Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
kirkwood-i2s.c
Go to the documentation of this file.
1 /*
2  * kirkwood-i2s.c
3  *
4  * (c) 2010 Arnaud Patard <[email protected]>
5  * (c) 2010 Arnaud Patard <[email protected]>
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation; either version 2 of the License, or (at your
10  * option) any later version.
11  */
12 
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/platform_device.h>
16 #include <linux/io.h>
17 #include <linux/slab.h>
18 #include <linux/mbus.h>
19 #include <linux/delay.h>
20 #include <linux/clk.h>
21 #include <sound/pcm.h>
22 #include <sound/pcm_params.h>
23 #include <sound/soc.h>
25 #include "kirkwood.h"
26 
27 #define DRV_NAME "kirkwood-i2s"
28 
29 #define KIRKWOOD_I2S_RATES \
30  (SNDRV_PCM_RATE_44100 | \
31  SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)
32 #define KIRKWOOD_I2S_FORMATS \
33  (SNDRV_PCM_FMTBIT_S16_LE | \
34  SNDRV_PCM_FMTBIT_S24_LE | \
35  SNDRV_PCM_FMTBIT_S32_LE)
36 
37 static int kirkwood_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
38  unsigned int fmt)
39 {
40  struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(cpu_dai);
41  unsigned long mask;
42  unsigned long value;
43 
44  switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
46  mask = KIRKWOOD_I2S_CTL_RJ;
47  break;
49  mask = KIRKWOOD_I2S_CTL_LJ;
50  break;
51  case SND_SOC_DAIFMT_I2S:
52  mask = KIRKWOOD_I2S_CTL_I2S;
53  break;
54  default:
55  return -EINVAL;
56  }
57 
58  /*
59  * Set same format for playback and record
60  * This avoids some troubles.
61  */
62  value = readl(priv->io+KIRKWOOD_I2S_PLAYCTL);
64  value |= mask;
65  writel(value, priv->io+KIRKWOOD_I2S_PLAYCTL);
66 
67  value = readl(priv->io+KIRKWOOD_I2S_RECCTL);
69  value |= mask;
70  writel(value, priv->io+KIRKWOOD_I2S_RECCTL);
71 
72  return 0;
73 }
74 
75 static inline void kirkwood_set_dco(void __iomem *io, unsigned long rate)
76 {
77  unsigned long value;
78 
80  switch (rate) {
81  default:
82  case 44100:
83  value |= KIRKWOOD_DCO_CTL_FREQ_11;
84  break;
85  case 48000:
86  value |= KIRKWOOD_DCO_CTL_FREQ_12;
87  break;
88  case 96000:
89  value |= KIRKWOOD_DCO_CTL_FREQ_24;
90  break;
91  }
92  writel(value, io + KIRKWOOD_DCO_CTL);
93 
94  /* wait for dco locked */
95  do {
96  cpu_relax();
97  value = readl(io + KIRKWOOD_DCO_SPCR_STATUS);
99  } while (value == 0);
100 }
101 
102 static int kirkwood_i2s_startup(struct snd_pcm_substream *substream,
103  struct snd_soc_dai *dai)
104 {
105  struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
106 
107  snd_soc_dai_set_dma_data(dai, substream, priv);
108  return 0;
109 }
110 
111 static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream,
112  struct snd_pcm_hw_params *params,
113  struct snd_soc_dai *dai)
114 {
115  struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
116  unsigned int i2s_reg, reg;
117  unsigned long i2s_value, value;
118 
119  if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
120  i2s_reg = KIRKWOOD_I2S_PLAYCTL;
121  reg = KIRKWOOD_PLAYCTL;
122  } else {
123  i2s_reg = KIRKWOOD_I2S_RECCTL;
124  reg = KIRKWOOD_RECCTL;
125  }
126 
127  /* set dco conf */
128  kirkwood_set_dco(priv->io, params_rate(params));
129 
130  i2s_value = readl(priv->io+i2s_reg);
131  i2s_value &= ~KIRKWOOD_I2S_CTL_SIZE_MASK;
132 
133  value = readl(priv->io+reg);
134  value &= ~KIRKWOOD_PLAYCTL_SIZE_MASK;
135 
136  /*
137  * Size settings in play/rec i2s control regs and play/rec control
138  * regs must be the same.
139  */
140  switch (params_format(params)) {
142  i2s_value |= KIRKWOOD_I2S_CTL_SIZE_16;
144  break;
145  /*
146  * doesn't work... S20_3LE != kirkwood 20bit format ?
147  *
148  case SNDRV_PCM_FORMAT_S20_3LE:
149  i2s_value |= KIRKWOOD_I2S_CTL_SIZE_20;
150  value |= KIRKWOOD_PLAYCTL_SIZE_20;
151  break;
152  */
154  i2s_value |= KIRKWOOD_I2S_CTL_SIZE_24;
155  value |= KIRKWOOD_PLAYCTL_SIZE_24;
156  break;
158  i2s_value |= KIRKWOOD_I2S_CTL_SIZE_32;
159  value |= KIRKWOOD_PLAYCTL_SIZE_32;
160  break;
161  default:
162  return -EINVAL;
163  }
164 
165  if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
166  value &= ~KIRKWOOD_PLAYCTL_MONO_MASK;
167  if (params_channels(params) == 1)
169  else
170  value |= KIRKWOOD_PLAYCTL_MONO_OFF;
171  }
172 
173  writel(i2s_value, priv->io+i2s_reg);
174  writel(value, priv->io+reg);
175 
176  return 0;
177 }
178 
179 static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
180  int cmd, struct snd_soc_dai *dai)
181 {
182  struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
183  uint32_t ctl, value;
184 
185  ctl = readl(priv->io + KIRKWOOD_PLAYCTL);
186  if (ctl & KIRKWOOD_PLAYCTL_PAUSE) {
187  unsigned timeout = 5000;
188  /*
189  * The Armada510 spec says that if we enter pause mode, the
190  * busy bit must be read back as clear _twice_. Make sure
191  * we respect that otherwise we get DMA underruns.
192  */
193  do {
194  value = ctl;
195  ctl = readl(priv->io + KIRKWOOD_PLAYCTL);
196  if (!((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY))
197  break;
198  udelay(1);
199  } while (timeout--);
200 
201  if ((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY)
202  dev_notice(dai->dev, "timed out waiting for busy to deassert: %08x\n",
203  ctl);
204  }
205 
206  switch (cmd) {
208  value = readl(priv->io + KIRKWOOD_INT_MASK);
210  writel(value, priv->io + KIRKWOOD_INT_MASK);
211 
212  /* configure audio & enable i2s playback */
214  ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE
216 
217  if (priv->burst == 32)
219  else
222  writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
223  break;
224 
226  /* stop audio, disable interrupts */
227  ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE;
228  writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
229 
230  value = readl(priv->io + KIRKWOOD_INT_MASK);
232  writel(value, priv->io + KIRKWOOD_INT_MASK);
233 
234  /* disable all playbacks */
236  writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
237  break;
238 
241  ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE;
242  writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
243  break;
244 
247  ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE);
248  writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
249  break;
250 
251  default:
252  return -EINVAL;
253  }
254 
255  return 0;
256 }
257 
258 static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream,
259  int cmd, struct snd_soc_dai *dai)
260 {
261  struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
262  unsigned long value;
263 
264  value = readl(priv->io + KIRKWOOD_RECCTL);
265 
266  switch (cmd) {
268  value = readl(priv->io + KIRKWOOD_INT_MASK);
270  writel(value, priv->io + KIRKWOOD_INT_MASK);
271 
272  /* configure audio & enable i2s record */
273  value = readl(priv->io + KIRKWOOD_RECCTL);
274  value &= ~KIRKWOOD_RECCTL_BURST_MASK;
275  value &= ~KIRKWOOD_RECCTL_MONO;
278 
279  if (priv->burst == 32)
280  value |= KIRKWOOD_RECCTL_BURST_32;
281  else
282  value |= KIRKWOOD_RECCTL_BURST_128;
283  value |= KIRKWOOD_RECCTL_I2S_EN;
284 
285  writel(value, priv->io + KIRKWOOD_RECCTL);
286  break;
287 
289  /* stop audio, disable interrupts */
290  value = readl(priv->io + KIRKWOOD_RECCTL);
292  writel(value, priv->io + KIRKWOOD_RECCTL);
293 
294  value = readl(priv->io + KIRKWOOD_INT_MASK);
296  writel(value, priv->io + KIRKWOOD_INT_MASK);
297 
298  /* disable all records */
299  value = readl(priv->io + KIRKWOOD_RECCTL);
301  writel(value, priv->io + KIRKWOOD_RECCTL);
302  break;
303 
306  value = readl(priv->io + KIRKWOOD_RECCTL);
308  writel(value, priv->io + KIRKWOOD_RECCTL);
309  break;
310 
313  value = readl(priv->io + KIRKWOOD_RECCTL);
315  writel(value, priv->io + KIRKWOOD_RECCTL);
316  break;
317 
318  default:
319  return -EINVAL;
320  }
321 
322  return 0;
323 }
324 
325 static int kirkwood_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
326  struct snd_soc_dai *dai)
327 {
328  if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
329  return kirkwood_i2s_play_trigger(substream, cmd, dai);
330  else
331  return kirkwood_i2s_rec_trigger(substream, cmd, dai);
332 
333  return 0;
334 }
335 
336 static int kirkwood_i2s_probe(struct snd_soc_dai *dai)
337 {
338  struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
339  unsigned long value;
340  unsigned int reg_data;
341 
342  /* put system in a "safe" state : */
343  /* disable audio interrupts */
344  writel(0xffffffff, priv->io + KIRKWOOD_INT_CAUSE);
345  writel(0, priv->io + KIRKWOOD_INT_MASK);
346 
347  reg_data = readl(priv->io + 0x1200);
348  reg_data &= (~(0x333FF8));
349  reg_data |= 0x111D18;
350  writel(reg_data, priv->io + 0x1200);
351 
352  msleep(500);
353 
354  reg_data = readl(priv->io + 0x1200);
355  reg_data &= (~(0x333FF8));
356  reg_data |= 0x111D18;
357  writel(reg_data, priv->io + 0x1200);
358 
359  /* disable playback/record */
360  value = readl(priv->io + KIRKWOOD_PLAYCTL);
362  writel(value, priv->io + KIRKWOOD_PLAYCTL);
363 
364  value = readl(priv->io + KIRKWOOD_RECCTL);
366  writel(value, priv->io + KIRKWOOD_RECCTL);
367 
368  return 0;
369 
370 }
371 
372 static int kirkwood_i2s_remove(struct snd_soc_dai *dai)
373 {
374  return 0;
375 }
376 
377 static const struct snd_soc_dai_ops kirkwood_i2s_dai_ops = {
378  .startup = kirkwood_i2s_startup,
379  .trigger = kirkwood_i2s_trigger,
380  .hw_params = kirkwood_i2s_hw_params,
381  .set_fmt = kirkwood_i2s_set_fmt,
382 };
383 
384 
385 static struct snd_soc_dai_driver kirkwood_i2s_dai = {
386  .probe = kirkwood_i2s_probe,
387  .remove = kirkwood_i2s_remove,
388  .playback = {
389  .channels_min = 1,
390  .channels_max = 2,
391  .rates = KIRKWOOD_I2S_RATES,
392  .formats = KIRKWOOD_I2S_FORMATS,},
393  .capture = {
394  .channels_min = 1,
395  .channels_max = 2,
396  .rates = KIRKWOOD_I2S_RATES,
397  .formats = KIRKWOOD_I2S_FORMATS,},
398  .ops = &kirkwood_i2s_dai_ops,
399 };
400 
401 static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev)
402 {
403  struct resource *mem;
405  pdev->dev.platform_data;
406  struct kirkwood_dma_data *priv;
407  int err;
408 
409  priv = kzalloc(sizeof(struct kirkwood_dma_data), GFP_KERNEL);
410  if (!priv) {
411  dev_err(&pdev->dev, "allocation failed\n");
412  err = -ENOMEM;
413  goto error;
414  }
415  dev_set_drvdata(&pdev->dev, priv);
416 
417  mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
418  if (!mem) {
419  dev_err(&pdev->dev, "platform_get_resource failed\n");
420  err = -ENXIO;
421  goto err_alloc;
422  }
423 
424  priv->mem = request_mem_region(mem->start, SZ_16K, DRV_NAME);
425  if (!priv->mem) {
426  dev_err(&pdev->dev, "request_mem_region failed\n");
427  err = -EBUSY;
428  goto err_alloc;
429  }
430 
431  priv->io = ioremap(priv->mem->start, SZ_16K);
432  if (!priv->io) {
433  dev_err(&pdev->dev, "ioremap failed\n");
434  err = -ENOMEM;
435  goto err_iomem;
436  }
437 
438  priv->irq = platform_get_irq(pdev, 0);
439  if (priv->irq <= 0) {
440  dev_err(&pdev->dev, "platform_get_irq failed\n");
441  err = -ENXIO;
442  goto err_ioremap;
443  }
444 
445  if (!data) {
446  dev_err(&pdev->dev, "no platform data ?!\n");
447  err = -EINVAL;
448  goto err_ioremap;
449  }
450 
451  priv->burst = data->burst;
452 
453  priv->clk = clk_get(&pdev->dev, NULL);
454  if (IS_ERR(priv->clk)) {
455  dev_err(&pdev->dev, "no clock\n");
456  err = PTR_ERR(priv->clk);
457  goto err_ioremap;
458  }
459  clk_prepare_enable(priv->clk);
460 
461  err = snd_soc_register_dai(&pdev->dev, &kirkwood_i2s_dai);
462  if (!err)
463  return 0;
464  dev_err(&pdev->dev, "snd_soc_register_dai failed\n");
465 
466  clk_disable_unprepare(priv->clk);
467  clk_put(priv->clk);
468 
469 err_ioremap:
470  iounmap(priv->io);
471 err_iomem:
472  release_mem_region(priv->mem->start, SZ_16K);
473 err_alloc:
474  kfree(priv);
475 error:
476  return err;
477 }
478 
479 static __devexit int kirkwood_i2s_dev_remove(struct platform_device *pdev)
480 {
481  struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev);
482 
483  snd_soc_unregister_dai(&pdev->dev);
484 
485  clk_disable_unprepare(priv->clk);
486  clk_put(priv->clk);
487 
488  iounmap(priv->io);
489  release_mem_region(priv->mem->start, SZ_16K);
490  kfree(priv);
491 
492  return 0;
493 }
494 
495 static struct platform_driver kirkwood_i2s_driver = {
496  .probe = kirkwood_i2s_dev_probe,
497  .remove = __devexit_p(kirkwood_i2s_dev_remove),
498  .driver = {
499  .name = DRV_NAME,
500  .owner = THIS_MODULE,
501  },
502 };
503 
504 module_platform_driver(kirkwood_i2s_driver);
505 
506 /* Module information */
507 MODULE_AUTHOR("Arnaud Patard, <[email protected]>");
508 MODULE_DESCRIPTION("Kirkwood I2S SoC Interface");
509 MODULE_LICENSE("GPL");
510 MODULE_ALIAS("platform:kirkwood-i2s");