@@ -160,9 +160,11 @@ static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream,
160160 case SNDRV_PCM_FORMAT_S16_LE :
161161 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_16 ;
162162 ctl_play = KIRKWOOD_PLAYCTL_SIZE_16_C |
163- KIRKWOOD_PLAYCTL_I2S_EN ;
163+ KIRKWOOD_PLAYCTL_I2S_EN |
164+ KIRKWOOD_PLAYCTL_SPDIF_EN ;
164165 ctl_rec = KIRKWOOD_RECCTL_SIZE_16_C |
165- KIRKWOOD_RECCTL_I2S_EN ;
166+ KIRKWOOD_RECCTL_I2S_EN |
167+ KIRKWOOD_RECCTL_SPDIF_EN ;
166168 break ;
167169 /*
168170 * doesn't work... S20_3LE != kirkwood 20bit format ?
@@ -178,9 +180,11 @@ static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream,
178180 case SNDRV_PCM_FORMAT_S24_LE :
179181 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_24 ;
180182 ctl_play = KIRKWOOD_PLAYCTL_SIZE_24 |
181- KIRKWOOD_PLAYCTL_I2S_EN ;
183+ KIRKWOOD_PLAYCTL_I2S_EN |
184+ KIRKWOOD_PLAYCTL_SPDIF_EN ;
182185 ctl_rec = KIRKWOOD_RECCTL_SIZE_24 |
183- KIRKWOOD_RECCTL_I2S_EN ;
186+ KIRKWOOD_RECCTL_I2S_EN |
187+ KIRKWOOD_RECCTL_SPDIF_EN ;
184188 break ;
185189 case SNDRV_PCM_FORMAT_S32_LE :
186190 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_32 ;
@@ -240,6 +244,11 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
240244 ctl );
241245 }
242246
247+ if (dai -> id == 0 )
248+ ctl &= ~KIRKWOOD_PLAYCTL_SPDIF_EN ; /* i2s */
249+ else
250+ ctl &= ~KIRKWOOD_PLAYCTL_I2S_EN ; /* spdif */
251+
243252 switch (cmd ) {
244253 case SNDRV_PCM_TRIGGER_START :
245254 /* configure */
@@ -258,7 +267,8 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
258267
259268 case SNDRV_PCM_TRIGGER_STOP :
260269 /* stop audio, disable interrupts */
261- ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE ;
270+ ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE |
271+ KIRKWOOD_PLAYCTL_SPDIF_MUTE ;
262272 writel (ctl , priv -> io + KIRKWOOD_PLAYCTL );
263273
264274 value = readl (priv -> io + KIRKWOOD_INT_MASK );
@@ -272,13 +282,15 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
272282
273283 case SNDRV_PCM_TRIGGER_PAUSE_PUSH :
274284 case SNDRV_PCM_TRIGGER_SUSPEND :
275- ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE ;
285+ ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE |
286+ KIRKWOOD_PLAYCTL_SPDIF_MUTE ;
276287 writel (ctl , priv -> io + KIRKWOOD_PLAYCTL );
277288 break ;
278289
279290 case SNDRV_PCM_TRIGGER_RESUME :
280291 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE :
281- ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE );
292+ ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE |
293+ KIRKWOOD_PLAYCTL_SPDIF_MUTE );
282294 writel (ctl , priv -> io + KIRKWOOD_PLAYCTL );
283295 break ;
284296
@@ -301,7 +313,13 @@ static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream,
301313 case SNDRV_PCM_TRIGGER_START :
302314 /* configure */
303315 ctl = priv -> ctl_rec ;
304- value = ctl & ~KIRKWOOD_RECCTL_I2S_EN ;
316+ if (dai -> id == 0 )
317+ ctl &= ~KIRKWOOD_RECCTL_SPDIF_EN ; /* i2s */
318+ else
319+ ctl &= ~KIRKWOOD_RECCTL_I2S_EN ; /* spdif */
320+
321+ value = ctl & ~(KIRKWOOD_RECCTL_I2S_EN |
322+ KIRKWOOD_RECCTL_SPDIF_EN );
305323 writel (value , priv -> io + KIRKWOOD_RECCTL );
306324
307325 /* enable interrupts */
@@ -361,9 +379,8 @@ static int kirkwood_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
361379 return 0 ;
362380}
363381
364- static int kirkwood_i2s_probe (struct snd_soc_dai * dai )
382+ static int kirkwood_i2s_init (struct kirkwood_dma_data * priv )
365383{
366- struct kirkwood_dma_data * priv = snd_soc_dai_get_drvdata (dai );
367384 unsigned long value ;
368385 unsigned int reg_data ;
369386
@@ -404,9 +421,29 @@ static const struct snd_soc_dai_ops kirkwood_i2s_dai_ops = {
404421 .set_fmt = kirkwood_i2s_set_fmt ,
405422};
406423
407-
408- static struct snd_soc_dai_driver kirkwood_i2s_dai = {
409- .probe = kirkwood_i2s_probe ,
424+ static struct snd_soc_dai_driver kirkwood_i2s_dai [2 ] = {
425+ {
426+ .name = "i2s" ,
427+ .id = 0 ,
428+ .playback = {
429+ .channels_min = 1 ,
430+ .channels_max = 2 ,
431+ .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
432+ SNDRV_PCM_RATE_96000 ,
433+ .formats = KIRKWOOD_I2S_FORMATS ,
434+ },
435+ .capture = {
436+ .channels_min = 1 ,
437+ .channels_max = 2 ,
438+ .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
439+ SNDRV_PCM_RATE_96000 ,
440+ .formats = KIRKWOOD_I2S_FORMATS ,
441+ },
442+ .ops = & kirkwood_i2s_dai_ops ,
443+ },
444+ {
445+ .name = "spdif" ,
446+ .id = 1 ,
410447 .playback = {
411448 .channels_min = 1 ,
412449 .channels_max = 2 ,
@@ -422,10 +459,34 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai = {
422459 .formats = KIRKWOOD_I2S_FORMATS ,
423460 },
424461 .ops = & kirkwood_i2s_dai_ops ,
462+ },
425463};
426464
427- static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk = {
428- .probe = kirkwood_i2s_probe ,
465+ static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk [2 ] = {
466+ {
467+ .name = "i2s" ,
468+ .id = 0 ,
469+ .playback = {
470+ .channels_min = 1 ,
471+ .channels_max = 2 ,
472+ .rates = SNDRV_PCM_RATE_8000_192000 |
473+ SNDRV_PCM_RATE_CONTINUOUS |
474+ SNDRV_PCM_RATE_KNOT ,
475+ .formats = KIRKWOOD_I2S_FORMATS ,
476+ },
477+ .capture = {
478+ .channels_min = 1 ,
479+ .channels_max = 2 ,
480+ .rates = SNDRV_PCM_RATE_8000_192000 |
481+ SNDRV_PCM_RATE_CONTINUOUS |
482+ SNDRV_PCM_RATE_KNOT ,
483+ .formats = KIRKWOOD_I2S_FORMATS ,
484+ },
485+ .ops = & kirkwood_i2s_dai_ops ,
486+ },
487+ {
488+ .name = "spdif" ,
489+ .id = 1 ,
429490 .playback = {
430491 .channels_min = 1 ,
431492 .channels_max = 2 ,
@@ -443,6 +504,7 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk = {
443504 .formats = KIRKWOOD_I2S_FORMATS ,
444505 },
445506 .ops = & kirkwood_i2s_dai_ops ,
507+ },
446508};
447509
448510static const struct snd_soc_component_driver kirkwood_i2s_component = {
@@ -452,7 +514,7 @@ static const struct snd_soc_component_driver kirkwood_i2s_component = {
452514static int kirkwood_i2s_dev_probe (struct platform_device * pdev )
453515{
454516 struct kirkwood_asoc_platform_data * data = pdev -> dev .platform_data ;
455- struct snd_soc_dai_driver * soc_dai = & kirkwood_i2s_dai ;
517+ struct snd_soc_dai_driver * soc_dai = kirkwood_i2s_dai ;
456518 struct kirkwood_dma_data * priv ;
457519 struct resource * mem ;
458520 struct device_node * np = pdev -> dev .of_node ;
@@ -524,7 +586,7 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
524586 }
525587
526588 err = snd_soc_register_component (& pdev -> dev , & kirkwood_i2s_component ,
527- soc_dai , 1 );
589+ soc_dai , 2 );
528590 if (err ) {
529591 dev_err (& pdev -> dev , "snd_soc_register_component failed\n" );
530592 goto err_component ;
@@ -535,6 +597,9 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
535597 dev_err (& pdev -> dev , "snd_soc_register_platform failed\n" );
536598 goto err_platform ;
537599 }
600+
601+ kirkwood_i2s_init (priv );
602+
538603 return 0 ;
539604 err_platform :
540605 snd_soc_unregister_component (& pdev -> dev );
0 commit comments