aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh/fsi.c
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2010-10-12 06:19:28 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-10-15 06:41:25 -0400
commit93193c2bbcd83bf8bf43433cfb1868d4ca0ac351 (patch)
treecff90ecf21d26cd2c59cf42f083d1af640a22a59 /sound/soc/sh/fsi.c
parentb67089e4c258a3a4ea8e23ceea4a5b7f8c3099d7 (diff)
ASoC: fsi: simultaneous playback/recorde support
Current FSI driver had not cared about simultaneous playback/capture on same port. This patch add new fsi_stream struct to care it, Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/sh/fsi.c')
-rw-r--r--sound/soc/sh/fsi.c152
1 files changed, 94 insertions, 58 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index dfc04bc2809e..507e709f2807 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -113,10 +113,8 @@
113 * struct 113 * struct
114 */ 114 */
115 115
116struct fsi_priv { 116struct fsi_stream {
117 void __iomem *base;
118 struct snd_pcm_substream *substream; 117 struct snd_pcm_substream *substream;
119 struct fsi_master *master;
120 118
121 int fifo_max_num; 119 int fifo_max_num;
122 int chan_num; 120 int chan_num;
@@ -125,6 +123,14 @@ struct fsi_priv {
125 int buff_len; 123 int buff_len;
126 int period_len; 124 int period_len;
127 int period_num; 125 int period_num;
126};
127
128struct fsi_priv {
129 void __iomem *base;
130 struct fsi_master *master;
131
132 struct fsi_stream playback;
133 struct fsi_stream capture;
128 134
129 u32 mst_ctrl; 135 u32 mst_ctrl;
130}; 136};
@@ -294,9 +300,20 @@ static u32 fsi_get_info_flags(struct fsi_priv *fsi)
294 master->info->portb_flags; 300 master->info->portb_flags;
295} 301}
296 302
303static inline int fsi_stream_is_play(int stream)
304{
305 return stream == SNDRV_PCM_STREAM_PLAYBACK;
306}
307
297static inline int fsi_is_play(struct snd_pcm_substream *substream) 308static inline int fsi_is_play(struct snd_pcm_substream *substream)
298{ 309{
299 return substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 310 return fsi_stream_is_play(substream->stream);
311}
312
313static inline struct fsi_stream *fsi_get_stream(struct fsi_priv *fsi,
314 int is_play)
315{
316 return is_play ? &fsi->playback : &fsi->capture;
300} 317}
301 318
302static int fsi_is_master_mode(struct fsi_priv *fsi, int is_play) 319static int fsi_is_master_mode(struct fsi_priv *fsi, int is_play)
@@ -328,35 +345,41 @@ static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play)
328} 345}
329 346
330static void fsi_stream_push(struct fsi_priv *fsi, 347static void fsi_stream_push(struct fsi_priv *fsi,
348 int is_play,
331 struct snd_pcm_substream *substream, 349 struct snd_pcm_substream *substream,
332 u32 buffer_len, 350 u32 buffer_len,
333 u32 period_len) 351 u32 period_len)
334{ 352{
335 fsi->substream = substream; 353 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
336 fsi->buff_len = buffer_len; 354
337 fsi->buff_offset = 0; 355 io->substream = substream;
338 fsi->period_len = period_len; 356 io->buff_len = buffer_len;
339 fsi->period_num = 0; 357 io->buff_offset = 0;
358 io->period_len = period_len;
359 io->period_num = 0;
340} 360}
341 361
342static void fsi_stream_pop(struct fsi_priv *fsi) 362static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
343{ 363{
344 fsi->substream = NULL; 364 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
345 fsi->buff_len = 0; 365
346 fsi->buff_offset = 0; 366 io->substream = NULL;
347 fsi->period_len = 0; 367 io->buff_len = 0;
348 fsi->period_num = 0; 368 io->buff_offset = 0;
369 io->period_len = 0;
370 io->period_num = 0;
349} 371}
350 372
351static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play) 373static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play)
352{ 374{
353 u32 status; 375 u32 status;
354 u32 reg = is_play ? DOFF_ST : DIFF_ST; 376 u32 reg = is_play ? DOFF_ST : DIFF_ST;
377 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
355 int data_num; 378 int data_num;
356 379
357 status = fsi_reg_read(fsi, reg); 380 status = fsi_reg_read(fsi, reg);
358 data_num = 0x1ff & (status >> 8); 381 data_num = 0x1ff & (status >> 8);
359 data_num *= fsi->chan_num; 382 data_num *= io->chan_num;
360 383
361 return data_num; 384 return data_num;
362} 385}
@@ -372,21 +395,25 @@ static int fsi_num2len(int num, int width)
372 return num * width; 395 return num * width;
373} 396}
374 397
375static int fsi_get_frame_width(struct fsi_priv *fsi) 398static int fsi_get_frame_width(struct fsi_priv *fsi, int is_play)
376{ 399{
377 struct snd_pcm_substream *substream = fsi->substream; 400 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
401 struct snd_pcm_substream *substream = io->substream;
378 struct snd_pcm_runtime *runtime = substream->runtime; 402 struct snd_pcm_runtime *runtime = substream->runtime;
379 403
380 return frames_to_bytes(runtime, 1) / fsi->chan_num; 404 return frames_to_bytes(runtime, 1) / io->chan_num;
381} 405}
382 406
383/* 407/*
384 * dma function 408 * dma function
385 */ 409 */
386 410
387static u8 *fsi_dma_get_area(struct fsi_priv *fsi) 411static u8 *fsi_dma_get_area(struct fsi_priv *fsi, int stream)
388{ 412{
389 return fsi->substream->runtime->dma_area + fsi->buff_offset; 413 int is_play = fsi_stream_is_play(stream);
414 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
415
416 return io->substream->runtime->dma_area + io->buff_offset;
390} 417}
391 418
392static void fsi_dma_soft_push16(struct fsi_priv *fsi, int num) 419static void fsi_dma_soft_push16(struct fsi_priv *fsi, int num)
@@ -394,7 +421,7 @@ static void fsi_dma_soft_push16(struct fsi_priv *fsi, int num)
394 u16 *start; 421 u16 *start;
395 int i; 422 int i;
396 423
397 start = (u16 *)fsi_dma_get_area(fsi); 424 start = (u16 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_PLAYBACK);
398 425
399 for (i = 0; i < num; i++) 426 for (i = 0; i < num; i++)
400 fsi_reg_write(fsi, DODT, ((u32)*(start + i) << 8)); 427 fsi_reg_write(fsi, DODT, ((u32)*(start + i) << 8));
@@ -405,7 +432,8 @@ static void fsi_dma_soft_pop16(struct fsi_priv *fsi, int num)
405 u16 *start; 432 u16 *start;
406 int i; 433 int i;
407 434
408 start = (u16 *)fsi_dma_get_area(fsi); 435 start = (u16 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_CAPTURE);
436
409 437
410 for (i = 0; i < num; i++) 438 for (i = 0; i < num; i++)
411 *(start + i) = (u16)(fsi_reg_read(fsi, DIDT) >> 8); 439 *(start + i) = (u16)(fsi_reg_read(fsi, DIDT) >> 8);
@@ -416,7 +444,8 @@ static void fsi_dma_soft_push32(struct fsi_priv *fsi, int num)
416 u32 *start; 444 u32 *start;
417 int i; 445 int i;
418 446
419 start = (u32 *)fsi_dma_get_area(fsi); 447 start = (u32 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_PLAYBACK);
448
420 449
421 for (i = 0; i < num; i++) 450 for (i = 0; i < num; i++)
422 fsi_reg_write(fsi, DODT, *(start + i)); 451 fsi_reg_write(fsi, DODT, *(start + i));
@@ -427,7 +456,7 @@ static void fsi_dma_soft_pop32(struct fsi_priv *fsi, int num)
427 u32 *start; 456 u32 *start;
428 int i; 457 int i;
429 458
430 start = (u32 *)fsi_dma_get_area(fsi); 459 start = (u32 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_CAPTURE);
431 460
432 for (i = 0; i < num; i++) 461 for (i = 0; i < num; i++)
433 *(start + i) = fsi_reg_read(fsi, DIDT); 462 *(start + i) = fsi_reg_read(fsi, DIDT);
@@ -518,14 +547,15 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
518 struct snd_soc_dai *dai) 547 struct snd_soc_dai *dai)
519{ 548{
520 struct fsi_master *master = fsi_get_master(fsi); 549 struct fsi_master *master = fsi_get_master(fsi);
550 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
521 u32 ctrl, shift, i; 551 u32 ctrl, shift, i;
522 552
523 /* get on-chip RAM capacity */ 553 /* get on-chip RAM capacity */
524 shift = fsi_master_read(master, FIFO_SZ); 554 shift = fsi_master_read(master, FIFO_SZ);
525 shift >>= fsi_get_port_shift(fsi, is_play); 555 shift >>= fsi_get_port_shift(fsi, is_play);
526 shift &= FIFO_SZ_MASK; 556 shift &= FIFO_SZ_MASK;
527 fsi->fifo_max_num = 256 << shift; 557 io->fifo_max_num = 256 << shift;
528 dev_dbg(dai->dev, "fifo = %d words\n", fsi->fifo_max_num); 558 dev_dbg(dai->dev, "fifo = %d words\n", io->fifo_max_num);
529 559
530 /* 560 /*
531 * The maximum number of sample data varies depending 561 * The maximum number of sample data varies depending
@@ -546,10 +576,10 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
546 * 7 channels: 32 ( 32 x 7 = 224) 576 * 7 channels: 32 ( 32 x 7 = 224)
547 * 8 channels: 32 ( 32 x 8 = 256) 577 * 8 channels: 32 ( 32 x 8 = 256)
548 */ 578 */
549 for (i = 1; i < fsi->chan_num; i <<= 1) 579 for (i = 1; i < io->chan_num; i <<= 1)
550 fsi->fifo_max_num >>= 1; 580 io->fifo_max_num >>= 1;
551 dev_dbg(dai->dev, "%d channel %d store\n", 581 dev_dbg(dai->dev, "%d channel %d store\n",
552 fsi->chan_num, fsi->fifo_max_num); 582 io->chan_num, io->fifo_max_num);
553 583
554 ctrl = is_play ? DOFF_CTL : DIFF_CTL; 584 ctrl = is_play ? DOFF_CTL : DIFF_CTL;
555 585
@@ -572,10 +602,12 @@ static void fsi_soft_all_reset(struct fsi_master *master)
572 mdelay(10); 602 mdelay(10);
573} 603}
574 604
575static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int is_play) 605static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int stream)
576{ 606{
577 struct snd_pcm_runtime *runtime; 607 struct snd_pcm_runtime *runtime;
578 struct snd_pcm_substream *substream = NULL; 608 struct snd_pcm_substream *substream = NULL;
609 int is_play = fsi_stream_is_play(stream);
610 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
579 u32 status_reg = is_play ? DOFF_ST : DIFF_ST; 611 u32 status_reg = is_play ? DOFF_ST : DIFF_ST;
580 int data_residue_num; 612 int data_residue_num;
581 int data_num; 613 int data_num;
@@ -585,32 +617,32 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int is_play)
585 void (*fn)(struct fsi_priv *fsi, int size); 617 void (*fn)(struct fsi_priv *fsi, int size);
586 618
587 if (!fsi || 619 if (!fsi ||
588 !fsi->substream || 620 !io->substream ||
589 !fsi->substream->runtime) 621 !io->substream->runtime)
590 return -EINVAL; 622 return -EINVAL;
591 623
592 over_period = 0; 624 over_period = 0;
593 substream = fsi->substream; 625 substream = io->substream;
594 runtime = substream->runtime; 626 runtime = substream->runtime;
595 627
596 /* FSI FIFO has limit. 628 /* FSI FIFO has limit.
597 * So, this driver can not send periods data at a time 629 * So, this driver can not send periods data at a time
598 */ 630 */
599 if (fsi->buff_offset >= 631 if (io->buff_offset >=
600 fsi_num2offset(fsi->period_num + 1, fsi->period_len)) { 632 fsi_num2offset(io->period_num + 1, io->period_len)) {
601 633
602 over_period = 1; 634 over_period = 1;
603 fsi->period_num = (fsi->period_num + 1) % runtime->periods; 635 io->period_num = (io->period_num + 1) % runtime->periods;
604 636
605 if (0 == fsi->period_num) 637 if (0 == io->period_num)
606 fsi->buff_offset = 0; 638 io->buff_offset = 0;
607 } 639 }
608 640
609 /* get 1 channel data width */ 641 /* get 1 channel data width */
610 ch_width = fsi_get_frame_width(fsi); 642 ch_width = fsi_get_frame_width(fsi, is_play);
611 643
612 /* get residue data number of alsa */ 644 /* get residue data number of alsa */
613 data_residue_num = fsi_len2num(fsi->buff_len - fsi->buff_offset, 645 data_residue_num = fsi_len2num(io->buff_len - io->buff_offset,
614 ch_width); 646 ch_width);
615 647
616 if (is_play) { 648 if (is_play) {
@@ -620,7 +652,7 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int is_play)
620 * data_num_max : number of FSI fifo free space 652 * data_num_max : number of FSI fifo free space
621 * data_num : number of ALSA residue data 653 * data_num : number of ALSA residue data
622 */ 654 */
623 data_num_max = fsi->fifo_max_num * fsi->chan_num; 655 data_num_max = io->fifo_max_num * io->chan_num;
624 data_num_max -= fsi_get_fifo_data_num(fsi, is_play); 656 data_num_max -= fsi_get_fifo_data_num(fsi, is_play);
625 657
626 data_num = data_residue_num; 658 data_num = data_residue_num;
@@ -662,7 +694,7 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int is_play)
662 fn(fsi, data_num); 694 fn(fsi, data_num);
663 695
664 /* update buff_offset */ 696 /* update buff_offset */
665 fsi->buff_offset += fsi_num2offset(data_num, ch_width); 697 io->buff_offset += fsi_num2offset(data_num, ch_width);
666 698
667 /* check fifo status */ 699 /* check fifo status */
668 if (!startup) { 700 if (!startup) {
@@ -687,12 +719,12 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int is_play)
687 719
688static int fsi_data_pop(struct fsi_priv *fsi, int startup) 720static int fsi_data_pop(struct fsi_priv *fsi, int startup)
689{ 721{
690 return fsi_fifo_data_ctrl(fsi, startup, 0); 722 return fsi_fifo_data_ctrl(fsi, startup, SNDRV_PCM_STREAM_CAPTURE);
691} 723}
692 724
693static int fsi_data_push(struct fsi_priv *fsi, int startup) 725static int fsi_data_push(struct fsi_priv *fsi, int startup)
694{ 726{
695 return fsi_fifo_data_ctrl(fsi, startup, 1); 727 return fsi_fifo_data_ctrl(fsi, startup, SNDRV_PCM_STREAM_PLAYBACK);
696} 728}
697 729
698static irqreturn_t fsi_interrupt(int irq, void *data) 730static irqreturn_t fsi_interrupt(int irq, void *data)
@@ -726,14 +758,17 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
726 struct snd_soc_dai *dai) 758 struct snd_soc_dai *dai)
727{ 759{
728 struct fsi_priv *fsi = fsi_get_priv(substream); 760 struct fsi_priv *fsi = fsi_get_priv(substream);
729 u32 flags = fsi_get_info_flags(fsi);
730 struct fsi_master *master = fsi_get_master(fsi); 761 struct fsi_master *master = fsi_get_master(fsi);
762 struct fsi_stream *io;
763 u32 flags = fsi_get_info_flags(fsi);
731 u32 fmt; 764 u32 fmt;
732 u32 reg; 765 u32 reg;
733 u32 data; 766 u32 data;
734 int is_play = fsi_is_play(substream); 767 int is_play = fsi_is_play(substream);
735 int is_master; 768 int is_master;
736 769
770 io = fsi_get_stream(fsi, is_play);
771
737 pm_runtime_get_sync(dai->dev); 772 pm_runtime_get_sync(dai->dev);
738 773
739 /* CKG1 */ 774 /* CKG1 */
@@ -764,29 +799,29 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
764 switch (fmt) { 799 switch (fmt) {
765 case SH_FSI_FMT_MONO: 800 case SH_FSI_FMT_MONO:
766 data = CR_MONO; 801 data = CR_MONO;
767 fsi->chan_num = 1; 802 io->chan_num = 1;
768 break; 803 break;
769 case SH_FSI_FMT_MONO_DELAY: 804 case SH_FSI_FMT_MONO_DELAY:
770 data = CR_MONO_D; 805 data = CR_MONO_D;
771 fsi->chan_num = 1; 806 io->chan_num = 1;
772 break; 807 break;
773 case SH_FSI_FMT_PCM: 808 case SH_FSI_FMT_PCM:
774 data = CR_PCM; 809 data = CR_PCM;
775 fsi->chan_num = 2; 810 io->chan_num = 2;
776 break; 811 break;
777 case SH_FSI_FMT_I2S: 812 case SH_FSI_FMT_I2S:
778 data = CR_I2S; 813 data = CR_I2S;
779 fsi->chan_num = 2; 814 io->chan_num = 2;
780 break; 815 break;
781 case SH_FSI_FMT_TDM: 816 case SH_FSI_FMT_TDM:
782 fsi->chan_num = is_play ? 817 io->chan_num = is_play ?
783 SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags); 818 SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
784 data = CR_TDM | (fsi->chan_num - 1); 819 data = CR_TDM | (io->chan_num - 1);
785 break; 820 break;
786 case SH_FSI_FMT_TDM_DELAY: 821 case SH_FSI_FMT_TDM_DELAY:
787 fsi->chan_num = is_play ? 822 io->chan_num = is_play ?
788 SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags); 823 SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
789 data = CR_TDM_D | (fsi->chan_num - 1); 824 data = CR_TDM_D | (io->chan_num - 1);
790 break; 825 break;
791 case SH_FSI_FMT_SPDIF: 826 case SH_FSI_FMT_SPDIF:
792 if (master->core->ver < 2) { 827 if (master->core->ver < 2) {
@@ -794,7 +829,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
794 return -EINVAL; 829 return -EINVAL;
795 } 830 }
796 data = CR_SPDIF; 831 data = CR_SPDIF;
797 fsi->chan_num = 2; 832 io->chan_num = 2;
798 fsi_spdif_clk_ctrl(fsi, 1); 833 fsi_spdif_clk_ctrl(fsi, 1);
799 fsi_reg_mask_set(fsi, OUT_SEL, 0x0010, 0x0010); 834 fsi_reg_mask_set(fsi, OUT_SEL, 0x0010, 0x0010);
800 break; 835 break;
@@ -836,14 +871,14 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
836 871
837 switch (cmd) { 872 switch (cmd) {
838 case SNDRV_PCM_TRIGGER_START: 873 case SNDRV_PCM_TRIGGER_START:
839 fsi_stream_push(fsi, substream, 874 fsi_stream_push(fsi, is_play, substream,
840 frames_to_bytes(runtime, runtime->buffer_size), 875 frames_to_bytes(runtime, runtime->buffer_size),
841 frames_to_bytes(runtime, runtime->period_size)); 876 frames_to_bytes(runtime, runtime->period_size));
842 ret = is_play ? fsi_data_push(fsi, 1) : fsi_data_pop(fsi, 1); 877 ret = is_play ? fsi_data_push(fsi, 1) : fsi_data_pop(fsi, 1);
843 break; 878 break;
844 case SNDRV_PCM_TRIGGER_STOP: 879 case SNDRV_PCM_TRIGGER_STOP:
845 fsi_irq_disable(fsi, is_play); 880 fsi_irq_disable(fsi, is_play);
846 fsi_stream_pop(fsi); 881 fsi_stream_pop(fsi, is_play);
847 break; 882 break;
848 } 883 }
849 884
@@ -991,9 +1026,10 @@ static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
991{ 1026{
992 struct snd_pcm_runtime *runtime = substream->runtime; 1027 struct snd_pcm_runtime *runtime = substream->runtime;
993 struct fsi_priv *fsi = fsi_get_priv(substream); 1028 struct fsi_priv *fsi = fsi_get_priv(substream);
1029 struct fsi_stream *io = fsi_get_stream(fsi, fsi_is_play(substream));
994 long location; 1030 long location;
995 1031
996 location = (fsi->buff_offset - 1); 1032 location = (io->buff_offset - 1);
997 if (location < 0) 1033 if (location < 0)
998 location = 0; 1034 location = 0;
999 1035