diff options
Diffstat (limited to 'sound/soc/sh/fsi.c')
-rw-r--r-- | sound/soc/sh/fsi.c | 582 |
1 files changed, 299 insertions, 283 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 4a9da6b5f4e..8e112ccffb1 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -118,10 +118,38 @@ typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int ena | |||
118 | /* | 118 | /* |
119 | * FSI driver use below type name for variable | 119 | * FSI driver use below type name for variable |
120 | * | 120 | * |
121 | * xxx_len : data length | ||
122 | * xxx_width : data width | ||
123 | * xxx_offset : data offset | ||
124 | * xxx_num : number of data | 121 | * xxx_num : number of data |
122 | * xxx_pos : position of data | ||
123 | * xxx_capa : capacity of data | ||
124 | */ | ||
125 | |||
126 | /* | ||
127 | * period/frame/sample image | ||
128 | * | ||
129 | * ex) PCM (2ch) | ||
130 | * | ||
131 | * period pos period pos | ||
132 | * [n] [n + 1] | ||
133 | * |<-------------------- period--------------------->| | ||
134 | * ==|============================================ ... =|== | ||
135 | * | | | ||
136 | * ||<----- frame ----->|<------ frame ----->| ... | | ||
137 | * |+--------------------+--------------------+- ... | | ||
138 | * ||[ sample ][ sample ]|[ sample ][ sample ]| ... | | ||
139 | * |+--------------------+--------------------+- ... | | ||
140 | * ==|============================================ ... =|== | ||
141 | */ | ||
142 | |||
143 | /* | ||
144 | * FSI FIFO image | ||
145 | * | ||
146 | * | | | ||
147 | * | | | ||
148 | * | [ sample ] | | ||
149 | * | [ sample ] | | ||
150 | * | [ sample ] | | ||
151 | * | [ sample ] | | ||
152 | * --> go to codecs | ||
125 | */ | 153 | */ |
126 | 154 | ||
127 | /* | 155 | /* |
@@ -131,12 +159,11 @@ typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int ena | |||
131 | struct fsi_stream { | 159 | struct fsi_stream { |
132 | struct snd_pcm_substream *substream; | 160 | struct snd_pcm_substream *substream; |
133 | 161 | ||
134 | int fifo_max_num; | 162 | int fifo_sample_capa; /* sample capacity of FSI FIFO */ |
135 | 163 | int buff_sample_capa; /* sample capacity of ALSA buffer */ | |
136 | int buff_offset; | 164 | int buff_sample_pos; /* sample position of ALSA buffer */ |
137 | int buff_len; | 165 | int period_samples; /* sample number / 1 period */ |
138 | int period_len; | 166 | int period_pos; /* current period position */ |
139 | int period_num; | ||
140 | 167 | ||
141 | int uerr_num; | 168 | int uerr_num; |
142 | int oerr_num; | 169 | int oerr_num; |
@@ -149,17 +176,14 @@ struct fsi_priv { | |||
149 | struct fsi_stream playback; | 176 | struct fsi_stream playback; |
150 | struct fsi_stream capture; | 177 | struct fsi_stream capture; |
151 | 178 | ||
179 | u32 do_fmt; | ||
180 | u32 di_fmt; | ||
181 | |||
152 | int chan_num:16; | 182 | int chan_num:16; |
153 | int clk_master:1; | 183 | int clk_master:1; |
184 | int spdif:1; | ||
154 | 185 | ||
155 | long rate; | 186 | long rate; |
156 | |||
157 | /* for suspend/resume */ | ||
158 | u32 saved_do_fmt; | ||
159 | u32 saved_di_fmt; | ||
160 | u32 saved_ckg1; | ||
161 | u32 saved_ckg2; | ||
162 | u32 saved_out_sel; | ||
163 | }; | 187 | }; |
164 | 188 | ||
165 | struct fsi_core { | 189 | struct fsi_core { |
@@ -180,14 +204,6 @@ struct fsi_master { | |||
180 | struct fsi_core *core; | 204 | struct fsi_core *core; |
181 | struct sh_fsi_platform_info *info; | 205 | struct sh_fsi_platform_info *info; |
182 | spinlock_t lock; | 206 | spinlock_t lock; |
183 | |||
184 | /* for suspend/resume */ | ||
185 | u32 saved_a_mclk; | ||
186 | u32 saved_b_mclk; | ||
187 | u32 saved_iemsk; | ||
188 | u32 saved_imsk; | ||
189 | u32 saved_clk_rst; | ||
190 | u32 saved_soft_rst; | ||
191 | }; | 207 | }; |
192 | 208 | ||
193 | /* | 209 | /* |
@@ -271,6 +287,11 @@ static int fsi_is_port_a(struct fsi_priv *fsi) | |||
271 | return fsi->master->base == fsi->base; | 287 | return fsi->master->base == fsi->base; |
272 | } | 288 | } |
273 | 289 | ||
290 | static int fsi_is_spdif(struct fsi_priv *fsi) | ||
291 | { | ||
292 | return fsi->spdif; | ||
293 | } | ||
294 | |||
274 | static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream) | 295 | static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream) |
275 | { | 296 | { |
276 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 297 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
@@ -342,28 +363,59 @@ static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play) | |||
342 | return shift; | 363 | return shift; |
343 | } | 364 | } |
344 | 365 | ||
366 | static int fsi_frame2sample(struct fsi_priv *fsi, int frames) | ||
367 | { | ||
368 | return frames * fsi->chan_num; | ||
369 | } | ||
370 | |||
371 | static int fsi_sample2frame(struct fsi_priv *fsi, int samples) | ||
372 | { | ||
373 | return samples / fsi->chan_num; | ||
374 | } | ||
375 | |||
376 | static int fsi_stream_is_working(struct fsi_priv *fsi, | ||
377 | int is_play) | ||
378 | { | ||
379 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); | ||
380 | struct fsi_master *master = fsi_get_master(fsi); | ||
381 | unsigned long flags; | ||
382 | int ret; | ||
383 | |||
384 | spin_lock_irqsave(&master->lock, flags); | ||
385 | ret = !!io->substream; | ||
386 | spin_unlock_irqrestore(&master->lock, flags); | ||
387 | |||
388 | return ret; | ||
389 | } | ||
390 | |||
345 | static void fsi_stream_push(struct fsi_priv *fsi, | 391 | static void fsi_stream_push(struct fsi_priv *fsi, |
346 | int is_play, | 392 | int is_play, |
347 | struct snd_pcm_substream *substream, | 393 | struct snd_pcm_substream *substream) |
348 | u32 buffer_len, | ||
349 | u32 period_len) | ||
350 | { | 394 | { |
351 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); | 395 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); |
396 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
397 | struct fsi_master *master = fsi_get_master(fsi); | ||
398 | unsigned long flags; | ||
352 | 399 | ||
400 | spin_lock_irqsave(&master->lock, flags); | ||
353 | io->substream = substream; | 401 | io->substream = substream; |
354 | io->buff_len = buffer_len; | 402 | io->buff_sample_capa = fsi_frame2sample(fsi, runtime->buffer_size); |
355 | io->buff_offset = 0; | 403 | io->buff_sample_pos = 0; |
356 | io->period_len = period_len; | 404 | io->period_samples = fsi_frame2sample(fsi, runtime->period_size); |
357 | io->period_num = 0; | 405 | io->period_pos = 0; |
358 | io->oerr_num = -1; /* ignore 1st err */ | 406 | io->oerr_num = -1; /* ignore 1st err */ |
359 | io->uerr_num = -1; /* ignore 1st err */ | 407 | io->uerr_num = -1; /* ignore 1st err */ |
408 | spin_unlock_irqrestore(&master->lock, flags); | ||
360 | } | 409 | } |
361 | 410 | ||
362 | static void fsi_stream_pop(struct fsi_priv *fsi, int is_play) | 411 | static void fsi_stream_pop(struct fsi_priv *fsi, int is_play) |
363 | { | 412 | { |
364 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); | 413 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); |
365 | struct snd_soc_dai *dai = fsi_get_dai(io->substream); | 414 | struct snd_soc_dai *dai = fsi_get_dai(io->substream); |
415 | struct fsi_master *master = fsi_get_master(fsi); | ||
416 | unsigned long flags; | ||
366 | 417 | ||
418 | spin_lock_irqsave(&master->lock, flags); | ||
367 | 419 | ||
368 | if (io->oerr_num > 0) | 420 | if (io->oerr_num > 0) |
369 | dev_err(dai->dev, "over_run = %d\n", io->oerr_num); | 421 | dev_err(dai->dev, "over_run = %d\n", io->oerr_num); |
@@ -372,47 +424,27 @@ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play) | |||
372 | dev_err(dai->dev, "under_run = %d\n", io->uerr_num); | 424 | dev_err(dai->dev, "under_run = %d\n", io->uerr_num); |
373 | 425 | ||
374 | io->substream = NULL; | 426 | io->substream = NULL; |
375 | io->buff_len = 0; | 427 | io->buff_sample_capa = 0; |
376 | io->buff_offset = 0; | 428 | io->buff_sample_pos = 0; |
377 | io->period_len = 0; | 429 | io->period_samples = 0; |
378 | io->period_num = 0; | 430 | io->period_pos = 0; |
379 | io->oerr_num = 0; | 431 | io->oerr_num = 0; |
380 | io->uerr_num = 0; | 432 | io->uerr_num = 0; |
433 | spin_unlock_irqrestore(&master->lock, flags); | ||
381 | } | 434 | } |
382 | 435 | ||
383 | static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play) | 436 | static int fsi_get_current_fifo_samples(struct fsi_priv *fsi, int is_play) |
384 | { | 437 | { |
385 | u32 status; | 438 | u32 status; |
386 | int data_num; | 439 | int frames; |
387 | 440 | ||
388 | status = is_play ? | 441 | status = is_play ? |
389 | fsi_reg_read(fsi, DOFF_ST) : | 442 | fsi_reg_read(fsi, DOFF_ST) : |
390 | fsi_reg_read(fsi, DIFF_ST); | 443 | fsi_reg_read(fsi, DIFF_ST); |
391 | 444 | ||
392 | data_num = 0x1ff & (status >> 8); | 445 | frames = 0x1ff & (status >> 8); |
393 | data_num *= fsi->chan_num; | ||
394 | |||
395 | return data_num; | ||
396 | } | ||
397 | |||
398 | static int fsi_len2num(int len, int width) | ||
399 | { | ||
400 | return len / width; | ||
401 | } | ||
402 | |||
403 | #define fsi_num2offset(a, b) fsi_num2len(a, b) | ||
404 | static int fsi_num2len(int num, int width) | ||
405 | { | ||
406 | return num * width; | ||
407 | } | ||
408 | |||
409 | static int fsi_get_frame_width(struct fsi_priv *fsi, int is_play) | ||
410 | { | ||
411 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); | ||
412 | struct snd_pcm_substream *substream = io->substream; | ||
413 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
414 | 446 | ||
415 | return frames_to_bytes(runtime, 1) / fsi->chan_num; | 447 | return fsi_frame2sample(fsi, frames); |
416 | } | 448 | } |
417 | 449 | ||
418 | static void fsi_count_fifo_err(struct fsi_priv *fsi) | 450 | static void fsi_count_fifo_err(struct fsi_priv *fsi) |
@@ -444,8 +476,10 @@ static u8 *fsi_dma_get_area(struct fsi_priv *fsi, int stream) | |||
444 | { | 476 | { |
445 | int is_play = fsi_stream_is_play(stream); | 477 | int is_play = fsi_stream_is_play(stream); |
446 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); | 478 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); |
479 | struct snd_pcm_runtime *runtime = io->substream->runtime; | ||
447 | 480 | ||
448 | return io->substream->runtime->dma_area + io->buff_offset; | 481 | return runtime->dma_area + |
482 | samples_to_bytes(runtime, io->buff_sample_pos); | ||
449 | } | 483 | } |
450 | 484 | ||
451 | static void fsi_dma_soft_push16(struct fsi_priv *fsi, int num) | 485 | static void fsi_dma_soft_push16(struct fsi_priv *fsi, int num) |
@@ -559,37 +593,94 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable) | |||
559 | /* | 593 | /* |
560 | * clock function | 594 | * clock function |
561 | */ | 595 | */ |
562 | #define fsi_module_init(m, d) __fsi_module_clk_ctrl(m, d, 1) | 596 | static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, |
563 | #define fsi_module_kill(m, d) __fsi_module_clk_ctrl(m, d, 0) | 597 | long rate, int enable) |
564 | static void __fsi_module_clk_ctrl(struct fsi_master *master, | ||
565 | struct device *dev, | ||
566 | int enable) | ||
567 | { | 598 | { |
568 | pm_runtime_get_sync(dev); | 599 | struct fsi_master *master = fsi_get_master(fsi); |
600 | set_rate_func set_rate = fsi_get_info_set_rate(master); | ||
601 | int fsi_ver = master->core->ver; | ||
602 | int ret; | ||
569 | 603 | ||
570 | if (enable) { | 604 | ret = set_rate(dev, fsi_is_port_a(fsi), rate, enable); |
571 | /* enable only SR */ | 605 | if (ret < 0) /* error */ |
572 | fsi_master_mask_set(master, SOFT_RST, FSISR, FSISR); | 606 | return ret; |
573 | fsi_master_mask_set(master, SOFT_RST, PASR | PBSR, 0); | 607 | |
574 | } else { | 608 | if (!enable) |
575 | /* clear all registers */ | 609 | return 0; |
576 | fsi_master_mask_set(master, SOFT_RST, FSISR, 0); | 610 | |
611 | if (ret > 0) { | ||
612 | u32 data = 0; | ||
613 | |||
614 | switch (ret & SH_FSI_ACKMD_MASK) { | ||
615 | default: | ||
616 | /* FALL THROUGH */ | ||
617 | case SH_FSI_ACKMD_512: | ||
618 | data |= (0x0 << 12); | ||
619 | break; | ||
620 | case SH_FSI_ACKMD_256: | ||
621 | data |= (0x1 << 12); | ||
622 | break; | ||
623 | case SH_FSI_ACKMD_128: | ||
624 | data |= (0x2 << 12); | ||
625 | break; | ||
626 | case SH_FSI_ACKMD_64: | ||
627 | data |= (0x3 << 12); | ||
628 | break; | ||
629 | case SH_FSI_ACKMD_32: | ||
630 | if (fsi_ver < 2) | ||
631 | dev_err(dev, "unsupported ACKMD\n"); | ||
632 | else | ||
633 | data |= (0x4 << 12); | ||
634 | break; | ||
635 | } | ||
636 | |||
637 | switch (ret & SH_FSI_BPFMD_MASK) { | ||
638 | default: | ||
639 | /* FALL THROUGH */ | ||
640 | case SH_FSI_BPFMD_32: | ||
641 | data |= (0x0 << 8); | ||
642 | break; | ||
643 | case SH_FSI_BPFMD_64: | ||
644 | data |= (0x1 << 8); | ||
645 | break; | ||
646 | case SH_FSI_BPFMD_128: | ||
647 | data |= (0x2 << 8); | ||
648 | break; | ||
649 | case SH_FSI_BPFMD_256: | ||
650 | data |= (0x3 << 8); | ||
651 | break; | ||
652 | case SH_FSI_BPFMD_512: | ||
653 | data |= (0x4 << 8); | ||
654 | break; | ||
655 | case SH_FSI_BPFMD_16: | ||
656 | if (fsi_ver < 2) | ||
657 | dev_err(dev, "unsupported ACKMD\n"); | ||
658 | else | ||
659 | data |= (0x7 << 8); | ||
660 | break; | ||
661 | } | ||
662 | |||
663 | fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data); | ||
664 | udelay(10); | ||
665 | ret = 0; | ||
577 | } | 666 | } |
578 | 667 | ||
579 | pm_runtime_put_sync(dev); | 668 | return ret; |
580 | } | 669 | } |
581 | 670 | ||
582 | #define fsi_port_start(f) __fsi_port_clk_ctrl(f, 1) | 671 | #define fsi_port_start(f, i) __fsi_port_clk_ctrl(f, i, 1) |
583 | #define fsi_port_stop(f) __fsi_port_clk_ctrl(f, 0) | 672 | #define fsi_port_stop(f, i) __fsi_port_clk_ctrl(f, i, 0) |
584 | static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int enable) | 673 | static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable) |
585 | { | 674 | { |
586 | struct fsi_master *master = fsi_get_master(fsi); | 675 | struct fsi_master *master = fsi_get_master(fsi); |
587 | u32 soft = fsi_is_port_a(fsi) ? PASR : PBSR; | ||
588 | u32 clk = fsi_is_port_a(fsi) ? CRA : CRB; | 676 | u32 clk = fsi_is_port_a(fsi) ? CRA : CRB; |
589 | int is_master = fsi_is_clk_master(fsi); | ||
590 | 677 | ||
591 | fsi_master_mask_set(master, SOFT_RST, soft, (enable) ? soft : 0); | 678 | if (enable) |
592 | if (is_master) | 679 | fsi_irq_enable(fsi, is_play); |
680 | else | ||
681 | fsi_irq_disable(fsi, is_play); | ||
682 | |||
683 | if (fsi_is_clk_master(fsi)) | ||
593 | fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); | 684 | fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); |
594 | } | 685 | } |
595 | 686 | ||
@@ -598,18 +689,19 @@ static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int enable) | |||
598 | */ | 689 | */ |
599 | static void fsi_fifo_init(struct fsi_priv *fsi, | 690 | static void fsi_fifo_init(struct fsi_priv *fsi, |
600 | int is_play, | 691 | int is_play, |
601 | struct snd_soc_dai *dai) | 692 | struct device *dev) |
602 | { | 693 | { |
603 | struct fsi_master *master = fsi_get_master(fsi); | 694 | struct fsi_master *master = fsi_get_master(fsi); |
604 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); | 695 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); |
605 | u32 shift, i; | 696 | u32 shift, i; |
697 | int frame_capa; | ||
606 | 698 | ||
607 | /* get on-chip RAM capacity */ | 699 | /* get on-chip RAM capacity */ |
608 | shift = fsi_master_read(master, FIFO_SZ); | 700 | shift = fsi_master_read(master, FIFO_SZ); |
609 | shift >>= fsi_get_port_shift(fsi, is_play); | 701 | shift >>= fsi_get_port_shift(fsi, is_play); |
610 | shift &= FIFO_SZ_MASK; | 702 | shift &= FIFO_SZ_MASK; |
611 | io->fifo_max_num = 256 << shift; | 703 | frame_capa = 256 << shift; |
612 | dev_dbg(dai->dev, "fifo = %d words\n", io->fifo_max_num); | 704 | dev_dbg(dev, "fifo = %d words\n", frame_capa); |
613 | 705 | ||
614 | /* | 706 | /* |
615 | * The maximum number of sample data varies depending | 707 | * The maximum number of sample data varies depending |
@@ -631,9 +723,11 @@ static void fsi_fifo_init(struct fsi_priv *fsi, | |||
631 | * 8 channels: 32 ( 32 x 8 = 256) | 723 | * 8 channels: 32 ( 32 x 8 = 256) |
632 | */ | 724 | */ |
633 | for (i = 1; i < fsi->chan_num; i <<= 1) | 725 | for (i = 1; i < fsi->chan_num; i <<= 1) |
634 | io->fifo_max_num >>= 1; | 726 | frame_capa >>= 1; |
635 | dev_dbg(dai->dev, "%d channel %d store\n", | 727 | dev_dbg(dev, "%d channel %d store\n", |
636 | fsi->chan_num, io->fifo_max_num); | 728 | fsi->chan_num, frame_capa); |
729 | |||
730 | io->fifo_sample_capa = fsi_frame2sample(fsi, frame_capa); | ||
637 | 731 | ||
638 | /* | 732 | /* |
639 | * set interrupt generation factor | 733 | * set interrupt generation factor |
@@ -654,10 +748,10 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream) | |||
654 | struct snd_pcm_substream *substream = NULL; | 748 | struct snd_pcm_substream *substream = NULL; |
655 | int is_play = fsi_stream_is_play(stream); | 749 | int is_play = fsi_stream_is_play(stream); |
656 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); | 750 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); |
657 | int data_residue_num; | 751 | int sample_residues; |
658 | int data_num; | 752 | int sample_width; |
659 | int data_num_max; | 753 | int samples; |
660 | int ch_width; | 754 | int samples_max; |
661 | int over_period; | 755 | int over_period; |
662 | void (*fn)(struct fsi_priv *fsi, int size); | 756 | void (*fn)(struct fsi_priv *fsi, int size); |
663 | 757 | ||
@@ -673,36 +767,35 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream) | |||
673 | /* FSI FIFO has limit. | 767 | /* FSI FIFO has limit. |
674 | * So, this driver can not send periods data at a time | 768 | * So, this driver can not send periods data at a time |
675 | */ | 769 | */ |
676 | if (io->buff_offset >= | 770 | if (io->buff_sample_pos >= |
677 | fsi_num2offset(io->period_num + 1, io->period_len)) { | 771 | io->period_samples * (io->period_pos + 1)) { |
678 | 772 | ||
679 | over_period = 1; | 773 | over_period = 1; |
680 | io->period_num = (io->period_num + 1) % runtime->periods; | 774 | io->period_pos = (io->period_pos + 1) % runtime->periods; |
681 | 775 | ||
682 | if (0 == io->period_num) | 776 | if (0 == io->period_pos) |
683 | io->buff_offset = 0; | 777 | io->buff_sample_pos = 0; |
684 | } | 778 | } |
685 | 779 | ||
686 | /* get 1 channel data width */ | 780 | /* get 1 sample data width */ |
687 | ch_width = fsi_get_frame_width(fsi, is_play); | 781 | sample_width = samples_to_bytes(runtime, 1); |
688 | 782 | ||
689 | /* get residue data number of alsa */ | 783 | /* get number of residue samples */ |
690 | data_residue_num = fsi_len2num(io->buff_len - io->buff_offset, | 784 | sample_residues = io->buff_sample_capa - io->buff_sample_pos; |
691 | ch_width); | ||
692 | 785 | ||
693 | if (is_play) { | 786 | if (is_play) { |
694 | /* | 787 | /* |
695 | * for play-back | 788 | * for play-back |
696 | * | 789 | * |
697 | * data_num_max : number of FSI fifo free space | 790 | * samples_max : number of FSI fifo free samples space |
698 | * data_num : number of ALSA residue data | 791 | * samples : number of ALSA residue samples |
699 | */ | 792 | */ |
700 | data_num_max = io->fifo_max_num * fsi->chan_num; | 793 | samples_max = io->fifo_sample_capa; |
701 | data_num_max -= fsi_get_fifo_data_num(fsi, is_play); | 794 | samples_max -= fsi_get_current_fifo_samples(fsi, is_play); |
702 | 795 | ||
703 | data_num = data_residue_num; | 796 | samples = sample_residues; |
704 | 797 | ||
705 | switch (ch_width) { | 798 | switch (sample_width) { |
706 | case 2: | 799 | case 2: |
707 | fn = fsi_dma_soft_push16; | 800 | fn = fsi_dma_soft_push16; |
708 | break; | 801 | break; |
@@ -716,13 +809,13 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream) | |||
716 | /* | 809 | /* |
717 | * for capture | 810 | * for capture |
718 | * | 811 | * |
719 | * data_num_max : number of ALSA free space | 812 | * samples_max : number of ALSA free samples space |
720 | * data_num : number of data in FSI fifo | 813 | * samples : number of samples in FSI fifo |
721 | */ | 814 | */ |
722 | data_num_max = data_residue_num; | 815 | samples_max = sample_residues; |
723 | data_num = fsi_get_fifo_data_num(fsi, is_play); | 816 | samples = fsi_get_current_fifo_samples(fsi, is_play); |
724 | 817 | ||
725 | switch (ch_width) { | 818 | switch (sample_width) { |
726 | case 2: | 819 | case 2: |
727 | fn = fsi_dma_soft_pop16; | 820 | fn = fsi_dma_soft_pop16; |
728 | break; | 821 | break; |
@@ -734,12 +827,12 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream) | |||
734 | } | 827 | } |
735 | } | 828 | } |
736 | 829 | ||
737 | data_num = min(data_num, data_num_max); | 830 | samples = min(samples, samples_max); |
738 | 831 | ||
739 | fn(fsi, data_num); | 832 | fn(fsi, samples); |
740 | 833 | ||
741 | /* update buff_offset */ | 834 | /* update buff_sample_pos */ |
742 | io->buff_offset += fsi_num2offset(data_num, ch_width); | 835 | io->buff_sample_pos += samples; |
743 | 836 | ||
744 | if (over_period) | 837 | if (over_period) |
745 | snd_pcm_period_elapsed(substream); | 838 | snd_pcm_period_elapsed(substream); |
@@ -788,16 +881,20 @@ static irqreturn_t fsi_interrupt(int irq, void *data) | |||
788 | * dai ops | 881 | * dai ops |
789 | */ | 882 | */ |
790 | 883 | ||
791 | static int fsi_dai_startup(struct snd_pcm_substream *substream, | 884 | static int fsi_hw_startup(struct fsi_priv *fsi, |
792 | struct snd_soc_dai *dai) | 885 | int is_play, |
886 | struct device *dev) | ||
793 | { | 887 | { |
794 | struct fsi_priv *fsi = fsi_get_priv(substream); | ||
795 | u32 flags = fsi_get_info_flags(fsi); | 888 | u32 flags = fsi_get_info_flags(fsi); |
796 | u32 data; | 889 | u32 data = 0; |
797 | int is_play = fsi_is_play(substream); | ||
798 | 890 | ||
799 | pm_runtime_get_sync(dai->dev); | 891 | pm_runtime_get_sync(dev); |
800 | 892 | ||
893 | /* clock setting */ | ||
894 | if (fsi_is_clk_master(fsi)) | ||
895 | data = DIMD | DOMD; | ||
896 | |||
897 | fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data); | ||
801 | 898 | ||
802 | /* clock inversion (CKG2) */ | 899 | /* clock inversion (CKG2) */ |
803 | data = 0; | 900 | data = 0; |
@@ -812,54 +909,70 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, | |||
812 | 909 | ||
813 | fsi_reg_write(fsi, CKG2, data); | 910 | fsi_reg_write(fsi, CKG2, data); |
814 | 911 | ||
912 | /* set format */ | ||
913 | fsi_reg_write(fsi, DO_FMT, fsi->do_fmt); | ||
914 | fsi_reg_write(fsi, DI_FMT, fsi->di_fmt); | ||
915 | |||
916 | /* spdif ? */ | ||
917 | if (fsi_is_spdif(fsi)) { | ||
918 | fsi_spdif_clk_ctrl(fsi, 1); | ||
919 | fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD); | ||
920 | } | ||
921 | |||
815 | /* irq clear */ | 922 | /* irq clear */ |
816 | fsi_irq_disable(fsi, is_play); | 923 | fsi_irq_disable(fsi, is_play); |
817 | fsi_irq_clear_status(fsi); | 924 | fsi_irq_clear_status(fsi); |
818 | 925 | ||
819 | /* fifo init */ | 926 | /* fifo init */ |
820 | fsi_fifo_init(fsi, is_play, dai); | 927 | fsi_fifo_init(fsi, is_play, dev); |
821 | 928 | ||
822 | return 0; | 929 | return 0; |
823 | } | 930 | } |
824 | 931 | ||
825 | static void fsi_dai_shutdown(struct snd_pcm_substream *substream, | 932 | static void fsi_hw_shutdown(struct fsi_priv *fsi, |
826 | struct snd_soc_dai *dai) | 933 | int is_play, |
934 | struct device *dev) | ||
935 | { | ||
936 | if (fsi_is_clk_master(fsi)) | ||
937 | fsi_set_master_clk(dev, fsi, fsi->rate, 0); | ||
938 | |||
939 | pm_runtime_put_sync(dev); | ||
940 | } | ||
941 | |||
942 | static int fsi_dai_startup(struct snd_pcm_substream *substream, | ||
943 | struct snd_soc_dai *dai) | ||
827 | { | 944 | { |
828 | struct fsi_priv *fsi = fsi_get_priv(substream); | 945 | struct fsi_priv *fsi = fsi_get_priv(substream); |
829 | int is_play = fsi_is_play(substream); | 946 | int is_play = fsi_is_play(substream); |
830 | struct fsi_master *master = fsi_get_master(fsi); | ||
831 | set_rate_func set_rate = fsi_get_info_set_rate(master); | ||
832 | 947 | ||
833 | fsi_irq_disable(fsi, is_play); | 948 | return fsi_hw_startup(fsi, is_play, dai->dev); |
949 | } | ||
834 | 950 | ||
835 | if (fsi_is_clk_master(fsi)) | 951 | static void fsi_dai_shutdown(struct snd_pcm_substream *substream, |
836 | set_rate(dai->dev, fsi_is_port_a(fsi), fsi->rate, 0); | 952 | struct snd_soc_dai *dai) |
953 | { | ||
954 | struct fsi_priv *fsi = fsi_get_priv(substream); | ||
955 | int is_play = fsi_is_play(substream); | ||
837 | 956 | ||
957 | fsi_hw_shutdown(fsi, is_play, dai->dev); | ||
838 | fsi->rate = 0; | 958 | fsi->rate = 0; |
839 | |||
840 | pm_runtime_put_sync(dai->dev); | ||
841 | } | 959 | } |
842 | 960 | ||
843 | static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, | 961 | static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, |
844 | struct snd_soc_dai *dai) | 962 | struct snd_soc_dai *dai) |
845 | { | 963 | { |
846 | struct fsi_priv *fsi = fsi_get_priv(substream); | 964 | struct fsi_priv *fsi = fsi_get_priv(substream); |
847 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
848 | int is_play = fsi_is_play(substream); | 965 | int is_play = fsi_is_play(substream); |
849 | int ret = 0; | 966 | int ret = 0; |
850 | 967 | ||
851 | switch (cmd) { | 968 | switch (cmd) { |
852 | case SNDRV_PCM_TRIGGER_START: | 969 | case SNDRV_PCM_TRIGGER_START: |
853 | fsi_stream_push(fsi, is_play, substream, | 970 | fsi_stream_push(fsi, is_play, substream); |
854 | frames_to_bytes(runtime, runtime->buffer_size), | ||
855 | frames_to_bytes(runtime, runtime->period_size)); | ||
856 | ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi); | 971 | ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi); |
857 | fsi_irq_enable(fsi, is_play); | 972 | fsi_port_start(fsi, is_play); |
858 | fsi_port_start(fsi); | ||
859 | break; | 973 | break; |
860 | case SNDRV_PCM_TRIGGER_STOP: | 974 | case SNDRV_PCM_TRIGGER_STOP: |
861 | fsi_port_stop(fsi); | 975 | fsi_port_stop(fsi, is_play); |
862 | fsi_irq_disable(fsi, is_play); | ||
863 | fsi_stream_pop(fsi, is_play); | 976 | fsi_stream_pop(fsi, is_play); |
864 | break; | 977 | break; |
865 | } | 978 | } |
@@ -884,8 +997,8 @@ static int fsi_set_fmt_dai(struct fsi_priv *fsi, unsigned int fmt) | |||
884 | return -EINVAL; | 997 | return -EINVAL; |
885 | } | 998 | } |
886 | 999 | ||
887 | fsi_reg_write(fsi, DO_FMT, data); | 1000 | fsi->do_fmt = data; |
888 | fsi_reg_write(fsi, DI_FMT, data); | 1001 | fsi->di_fmt = data; |
889 | 1002 | ||
890 | return 0; | 1003 | return 0; |
891 | } | 1004 | } |
@@ -900,11 +1013,10 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi) | |||
900 | 1013 | ||
901 | data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM; | 1014 | data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM; |
902 | fsi->chan_num = 2; | 1015 | fsi->chan_num = 2; |
903 | fsi_spdif_clk_ctrl(fsi, 1); | 1016 | fsi->spdif = 1; |
904 | fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD); | ||
905 | 1017 | ||
906 | fsi_reg_write(fsi, DO_FMT, data); | 1018 | fsi->do_fmt = data; |
907 | fsi_reg_write(fsi, DI_FMT, data); | 1019 | fsi->di_fmt = data; |
908 | 1020 | ||
909 | return 0; | 1021 | return 0; |
910 | } | 1022 | } |
@@ -915,32 +1027,24 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
915 | struct fsi_master *master = fsi_get_master(fsi); | 1027 | struct fsi_master *master = fsi_get_master(fsi); |
916 | set_rate_func set_rate = fsi_get_info_set_rate(master); | 1028 | set_rate_func set_rate = fsi_get_info_set_rate(master); |
917 | u32 flags = fsi_get_info_flags(fsi); | 1029 | u32 flags = fsi_get_info_flags(fsi); |
918 | u32 data = 0; | ||
919 | int ret; | 1030 | int ret; |
920 | 1031 | ||
921 | pm_runtime_get_sync(dai->dev); | ||
922 | |||
923 | /* set master/slave audio interface */ | 1032 | /* set master/slave audio interface */ |
924 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 1033 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
925 | case SND_SOC_DAIFMT_CBM_CFM: | 1034 | case SND_SOC_DAIFMT_CBM_CFM: |
926 | data = DIMD | DOMD; | ||
927 | fsi->clk_master = 1; | 1035 | fsi->clk_master = 1; |
928 | break; | 1036 | break; |
929 | case SND_SOC_DAIFMT_CBS_CFS: | 1037 | case SND_SOC_DAIFMT_CBS_CFS: |
930 | break; | 1038 | break; |
931 | default: | 1039 | default: |
932 | ret = -EINVAL; | 1040 | return -EINVAL; |
933 | goto set_fmt_exit; | ||
934 | } | 1041 | } |
935 | 1042 | ||
936 | if (fsi_is_clk_master(fsi) && !set_rate) { | 1043 | if (fsi_is_clk_master(fsi) && !set_rate) { |
937 | dev_err(dai->dev, "platform doesn't have set_rate\n"); | 1044 | dev_err(dai->dev, "platform doesn't have set_rate\n"); |
938 | ret = -EINVAL; | 1045 | return -EINVAL; |
939 | goto set_fmt_exit; | ||
940 | } | 1046 | } |
941 | 1047 | ||
942 | fsi_reg_mask_set(fsi, CKG1, (DIMD | DOMD), data); | ||
943 | |||
944 | /* set format */ | 1048 | /* set format */ |
945 | switch (flags & SH_FSI_FMT_MASK) { | 1049 | switch (flags & SH_FSI_FMT_MASK) { |
946 | case SH_FSI_FMT_DAI: | 1050 | case SH_FSI_FMT_DAI: |
@@ -953,9 +1057,6 @@ static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
953 | ret = -EINVAL; | 1057 | ret = -EINVAL; |
954 | } | 1058 | } |
955 | 1059 | ||
956 | set_fmt_exit: | ||
957 | pm_runtime_put_sync(dai->dev); | ||
958 | |||
959 | return ret; | 1060 | return ret; |
960 | } | 1061 | } |
961 | 1062 | ||
@@ -964,79 +1065,19 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream, | |||
964 | struct snd_soc_dai *dai) | 1065 | struct snd_soc_dai *dai) |
965 | { | 1066 | { |
966 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1067 | struct fsi_priv *fsi = fsi_get_priv(substream); |
967 | struct fsi_master *master = fsi_get_master(fsi); | ||
968 | set_rate_func set_rate = fsi_get_info_set_rate(master); | ||
969 | int fsi_ver = master->core->ver; | ||
970 | long rate = params_rate(params); | 1068 | long rate = params_rate(params); |
971 | int ret; | 1069 | int ret; |
972 | 1070 | ||
973 | if (!fsi_is_clk_master(fsi)) | 1071 | if (!fsi_is_clk_master(fsi)) |
974 | return 0; | 1072 | return 0; |
975 | 1073 | ||
976 | ret = set_rate(dai->dev, fsi_is_port_a(fsi), rate, 1); | 1074 | ret = fsi_set_master_clk(dai->dev, fsi, rate, 1); |
977 | if (ret < 0) /* error */ | 1075 | if (ret < 0) |
978 | return ret; | 1076 | return ret; |
979 | 1077 | ||
980 | fsi->rate = rate; | 1078 | fsi->rate = rate; |
981 | if (ret > 0) { | ||
982 | u32 data = 0; | ||
983 | |||
984 | switch (ret & SH_FSI_ACKMD_MASK) { | ||
985 | default: | ||
986 | /* FALL THROUGH */ | ||
987 | case SH_FSI_ACKMD_512: | ||
988 | data |= (0x0 << 12); | ||
989 | break; | ||
990 | case SH_FSI_ACKMD_256: | ||
991 | data |= (0x1 << 12); | ||
992 | break; | ||
993 | case SH_FSI_ACKMD_128: | ||
994 | data |= (0x2 << 12); | ||
995 | break; | ||
996 | case SH_FSI_ACKMD_64: | ||
997 | data |= (0x3 << 12); | ||
998 | break; | ||
999 | case SH_FSI_ACKMD_32: | ||
1000 | if (fsi_ver < 2) | ||
1001 | dev_err(dai->dev, "unsupported ACKMD\n"); | ||
1002 | else | ||
1003 | data |= (0x4 << 12); | ||
1004 | break; | ||
1005 | } | ||
1006 | |||
1007 | switch (ret & SH_FSI_BPFMD_MASK) { | ||
1008 | default: | ||
1009 | /* FALL THROUGH */ | ||
1010 | case SH_FSI_BPFMD_32: | ||
1011 | data |= (0x0 << 8); | ||
1012 | break; | ||
1013 | case SH_FSI_BPFMD_64: | ||
1014 | data |= (0x1 << 8); | ||
1015 | break; | ||
1016 | case SH_FSI_BPFMD_128: | ||
1017 | data |= (0x2 << 8); | ||
1018 | break; | ||
1019 | case SH_FSI_BPFMD_256: | ||
1020 | data |= (0x3 << 8); | ||
1021 | break; | ||
1022 | case SH_FSI_BPFMD_512: | ||
1023 | data |= (0x4 << 8); | ||
1024 | break; | ||
1025 | case SH_FSI_BPFMD_16: | ||
1026 | if (fsi_ver < 2) | ||
1027 | dev_err(dai->dev, "unsupported ACKMD\n"); | ||
1028 | else | ||
1029 | data |= (0x7 << 8); | ||
1030 | break; | ||
1031 | } | ||
1032 | |||
1033 | fsi_reg_mask_set(fsi, CKG1, (ACKMD_MASK | BPFMD_MASK) , data); | ||
1034 | udelay(10); | ||
1035 | ret = 0; | ||
1036 | } | ||
1037 | 1079 | ||
1038 | return ret; | 1080 | return ret; |
1039 | |||
1040 | } | 1081 | } |
1041 | 1082 | ||
1042 | static struct snd_soc_dai_ops fsi_dai_ops = { | 1083 | static struct snd_soc_dai_ops fsi_dai_ops = { |
@@ -1097,16 +1138,14 @@ static int fsi_hw_free(struct snd_pcm_substream *substream) | |||
1097 | 1138 | ||
1098 | static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) | 1139 | static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) |
1099 | { | 1140 | { |
1100 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
1101 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1141 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1102 | struct fsi_stream *io = fsi_get_stream(fsi, fsi_is_play(substream)); | 1142 | struct fsi_stream *io = fsi_get_stream(fsi, fsi_is_play(substream)); |
1103 | long location; | 1143 | int samples_pos = io->buff_sample_pos - 1; |
1104 | 1144 | ||
1105 | location = (io->buff_offset - 1); | 1145 | if (samples_pos < 0) |
1106 | if (location < 0) | 1146 | samples_pos = 0; |
1107 | location = 0; | ||
1108 | 1147 | ||
1109 | return bytes_to_frames(runtime, location); | 1148 | return fsi_sample2frame(fsi, samples_pos); |
1110 | } | 1149 | } |
1111 | 1150 | ||
1112 | static struct snd_pcm_ops fsi_pcm_ops = { | 1151 | static struct snd_pcm_ops fsi_pcm_ops = { |
@@ -1129,10 +1168,10 @@ static void fsi_pcm_free(struct snd_pcm *pcm) | |||
1129 | snd_pcm_lib_preallocate_free_for_all(pcm); | 1168 | snd_pcm_lib_preallocate_free_for_all(pcm); |
1130 | } | 1169 | } |
1131 | 1170 | ||
1132 | static int fsi_pcm_new(struct snd_card *card, | 1171 | static int fsi_pcm_new(struct snd_soc_pcm_runtime *rtd) |
1133 | struct snd_soc_dai *dai, | ||
1134 | struct snd_pcm *pcm) | ||
1135 | { | 1172 | { |
1173 | struct snd_pcm *pcm = rtd->pcm; | ||
1174 | |||
1136 | /* | 1175 | /* |
1137 | * dont use SNDRV_DMA_TYPE_DEV, since it will oops the SH kernel | 1176 | * dont use SNDRV_DMA_TYPE_DEV, since it will oops the SH kernel |
1138 | * in MMAP mode (i.e. aplay -M) | 1177 | * in MMAP mode (i.e. aplay -M) |
@@ -1246,8 +1285,6 @@ static int fsi_probe(struct platform_device *pdev) | |||
1246 | pm_runtime_enable(&pdev->dev); | 1285 | pm_runtime_enable(&pdev->dev); |
1247 | dev_set_drvdata(&pdev->dev, master); | 1286 | dev_set_drvdata(&pdev->dev, master); |
1248 | 1287 | ||
1249 | fsi_module_init(master, &pdev->dev); | ||
1250 | |||
1251 | ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, | 1288 | ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, |
1252 | id_entry->name, master); | 1289 | id_entry->name, master); |
1253 | if (ret) { | 1290 | if (ret) { |
@@ -1290,8 +1327,6 @@ static int fsi_remove(struct platform_device *pdev) | |||
1290 | 1327 | ||
1291 | master = dev_get_drvdata(&pdev->dev); | 1328 | master = dev_get_drvdata(&pdev->dev); |
1292 | 1329 | ||
1293 | fsi_module_kill(master, &pdev->dev); | ||
1294 | |||
1295 | free_irq(master->irq, master); | 1330 | free_irq(master->irq, master); |
1296 | pm_runtime_disable(&pdev->dev); | 1331 | pm_runtime_disable(&pdev->dev); |
1297 | 1332 | ||
@@ -1305,53 +1340,43 @@ static int fsi_remove(struct platform_device *pdev) | |||
1305 | } | 1340 | } |
1306 | 1341 | ||
1307 | static void __fsi_suspend(struct fsi_priv *fsi, | 1342 | static void __fsi_suspend(struct fsi_priv *fsi, |
1308 | struct device *dev, | 1343 | int is_play, |
1309 | set_rate_func set_rate) | 1344 | struct device *dev) |
1310 | { | 1345 | { |
1311 | fsi->saved_do_fmt = fsi_reg_read(fsi, DO_FMT); | 1346 | if (!fsi_stream_is_working(fsi, is_play)) |
1312 | fsi->saved_di_fmt = fsi_reg_read(fsi, DI_FMT); | 1347 | return; |
1313 | fsi->saved_ckg1 = fsi_reg_read(fsi, CKG1); | ||
1314 | fsi->saved_ckg2 = fsi_reg_read(fsi, CKG2); | ||
1315 | fsi->saved_out_sel = fsi_reg_read(fsi, OUT_SEL); | ||
1316 | 1348 | ||
1317 | if (fsi_is_clk_master(fsi)) | 1349 | fsi_port_stop(fsi, is_play); |
1318 | set_rate(dev, fsi_is_port_a(fsi), fsi->rate, 0); | 1350 | fsi_hw_shutdown(fsi, is_play, dev); |
1319 | } | 1351 | } |
1320 | 1352 | ||
1321 | static void __fsi_resume(struct fsi_priv *fsi, | 1353 | static void __fsi_resume(struct fsi_priv *fsi, |
1322 | struct device *dev, | 1354 | int is_play, |
1323 | set_rate_func set_rate) | 1355 | struct device *dev) |
1324 | { | 1356 | { |
1325 | fsi_reg_write(fsi, DO_FMT, fsi->saved_do_fmt); | 1357 | if (!fsi_stream_is_working(fsi, is_play)) |
1326 | fsi_reg_write(fsi, DI_FMT, fsi->saved_di_fmt); | 1358 | return; |
1327 | fsi_reg_write(fsi, CKG1, fsi->saved_ckg1); | 1359 | |
1328 | fsi_reg_write(fsi, CKG2, fsi->saved_ckg2); | 1360 | fsi_hw_startup(fsi, is_play, dev); |
1329 | fsi_reg_write(fsi, OUT_SEL, fsi->saved_out_sel); | 1361 | |
1362 | if (fsi_is_clk_master(fsi) && fsi->rate) | ||
1363 | fsi_set_master_clk(dev, fsi, fsi->rate, 1); | ||
1364 | |||
1365 | fsi_port_start(fsi, is_play); | ||
1330 | 1366 | ||
1331 | if (fsi_is_clk_master(fsi)) | ||
1332 | set_rate(dev, fsi_is_port_a(fsi), fsi->rate, 1); | ||
1333 | } | 1367 | } |
1334 | 1368 | ||
1335 | static int fsi_suspend(struct device *dev) | 1369 | static int fsi_suspend(struct device *dev) |
1336 | { | 1370 | { |
1337 | struct fsi_master *master = dev_get_drvdata(dev); | 1371 | struct fsi_master *master = dev_get_drvdata(dev); |
1338 | set_rate_func set_rate = fsi_get_info_set_rate(master); | 1372 | struct fsi_priv *fsia = &master->fsia; |
1339 | 1373 | struct fsi_priv *fsib = &master->fsib; | |
1340 | pm_runtime_get_sync(dev); | ||
1341 | |||
1342 | __fsi_suspend(&master->fsia, dev, set_rate); | ||
1343 | __fsi_suspend(&master->fsib, dev, set_rate); | ||
1344 | 1374 | ||
1345 | master->saved_a_mclk = fsi_core_read(master, a_mclk); | 1375 | __fsi_suspend(fsia, 1, dev); |
1346 | master->saved_b_mclk = fsi_core_read(master, b_mclk); | 1376 | __fsi_suspend(fsia, 0, dev); |
1347 | master->saved_iemsk = fsi_core_read(master, iemsk); | ||
1348 | master->saved_imsk = fsi_core_read(master, imsk); | ||
1349 | master->saved_clk_rst = fsi_master_read(master, CLK_RST); | ||
1350 | master->saved_soft_rst = fsi_master_read(master, SOFT_RST); | ||
1351 | 1377 | ||
1352 | fsi_module_kill(master, dev); | 1378 | __fsi_suspend(fsib, 1, dev); |
1353 | 1379 | __fsi_suspend(fsib, 0, dev); | |
1354 | pm_runtime_put_sync(dev); | ||
1355 | 1380 | ||
1356 | return 0; | 1381 | return 0; |
1357 | } | 1382 | } |
@@ -1359,23 +1384,14 @@ static int fsi_suspend(struct device *dev) | |||
1359 | static int fsi_resume(struct device *dev) | 1384 | static int fsi_resume(struct device *dev) |
1360 | { | 1385 | { |
1361 | struct fsi_master *master = dev_get_drvdata(dev); | 1386 | struct fsi_master *master = dev_get_drvdata(dev); |
1362 | set_rate_func set_rate = fsi_get_info_set_rate(master); | 1387 | struct fsi_priv *fsia = &master->fsia; |
1363 | 1388 | struct fsi_priv *fsib = &master->fsib; | |
1364 | pm_runtime_get_sync(dev); | ||
1365 | |||
1366 | fsi_module_init(master, dev); | ||
1367 | 1389 | ||
1368 | fsi_master_mask_set(master, SOFT_RST, 0xffff, master->saved_soft_rst); | 1390 | __fsi_resume(fsia, 1, dev); |
1369 | fsi_master_mask_set(master, CLK_RST, 0xffff, master->saved_clk_rst); | 1391 | __fsi_resume(fsia, 0, dev); |
1370 | fsi_core_mask_set(master, a_mclk, 0xffff, master->saved_a_mclk); | ||
1371 | fsi_core_mask_set(master, b_mclk, 0xffff, master->saved_b_mclk); | ||
1372 | fsi_core_mask_set(master, iemsk, 0xffff, master->saved_iemsk); | ||
1373 | fsi_core_mask_set(master, imsk, 0xffff, master->saved_imsk); | ||
1374 | 1392 | ||
1375 | __fsi_resume(&master->fsia, dev, set_rate); | 1393 | __fsi_resume(fsib, 1, dev); |
1376 | __fsi_resume(&master->fsib, dev, set_rate); | 1394 | __fsi_resume(fsib, 0, dev); |
1377 | |||
1378 | pm_runtime_put_sync(dev); | ||
1379 | 1395 | ||
1380 | return 0; | 1396 | return 0; |
1381 | } | 1397 | } |