|
90 | 90 | #define MCHP_PDMC_DS_NO 2 |
91 | 91 | #define MCHP_PDMC_EDGE_NO 2 |
92 | 92 |
|
| 93 | +/* |
| 94 | + * ---- DMA chunk size allowed ---- |
| 95 | + */ |
| 96 | +#define MCHP_PDMC_DMA_8_WORD_CHUNK 8 |
| 97 | +#define MCHP_PDMC_DMA_4_WORD_CHUNK 4 |
| 98 | +#define MCHP_PDMC_DMA_2_WORD_CHUNK 2 |
| 99 | +#define MCHP_PDMC_DMA_1_WORD_CHUNK 1 |
| 100 | +#define DMA_BURST_ALIGNED(_p, _s, _w) !(_p % (_s * _w)) |
| 101 | + |
93 | 102 | struct mic_map { |
94 | 103 | int ds_pos; |
95 | 104 | int clk_edge; |
@@ -511,15 +520,18 @@ static u32 mchp_pdmc_mr_set_osr(int audio_filter_en, unsigned int osr) |
511 | 520 | return 0; |
512 | 521 | } |
513 | 522 |
|
514 | | -static inline int mchp_pdmc_period_to_maxburst(int period_size) |
| 523 | +static inline int mchp_pdmc_period_to_maxburst(int period_size, int sample_size) |
515 | 524 | { |
516 | | - if (!(period_size % 8)) |
517 | | - return 8; |
518 | | - if (!(period_size % 4)) |
519 | | - return 4; |
520 | | - if (!(period_size % 2)) |
521 | | - return 2; |
522 | | - return 1; |
| 525 | + int p_size = period_size; |
| 526 | + int s_size = sample_size; |
| 527 | + |
| 528 | + if (DMA_BURST_ALIGNED(p_size, s_size, MCHP_PDMC_DMA_8_WORD_CHUNK)) |
| 529 | + return MCHP_PDMC_DMA_8_WORD_CHUNK; |
| 530 | + if (DMA_BURST_ALIGNED(p_size, s_size, MCHP_PDMC_DMA_4_WORD_CHUNK)) |
| 531 | + return MCHP_PDMC_DMA_4_WORD_CHUNK; |
| 532 | + if (DMA_BURST_ALIGNED(p_size, s_size, MCHP_PDMC_DMA_2_WORD_CHUNK)) |
| 533 | + return MCHP_PDMC_DMA_2_WORD_CHUNK; |
| 534 | + return MCHP_PDMC_DMA_1_WORD_CHUNK; |
523 | 535 | } |
524 | 536 |
|
525 | 537 | static struct snd_pcm_chmap_elem mchp_pdmc_std_chmaps[] = { |
@@ -547,14 +559,18 @@ static int mchp_pdmc_hw_params(struct snd_pcm_substream *substream, |
547 | 559 | unsigned int channels = params_channels(params); |
548 | 560 | unsigned int osr = 0, osr_start; |
549 | 561 | unsigned int fs = params_rate(params); |
| 562 | + int sample_bytes = params_physical_width(params) / 8; |
| 563 | + int period_bytes = params_period_size(params) * |
| 564 | + params_channels(params) * sample_bytes; |
| 565 | + int maxburst; |
550 | 566 | u32 mr_val = 0; |
551 | 567 | u32 cfgr_val = 0; |
552 | 568 | int i; |
553 | 569 | int ret; |
554 | 570 |
|
555 | | - dev_dbg(comp->dev, "%s() rate=%u format=%#x width=%u channels=%u\n", |
| 571 | + dev_dbg(comp->dev, "%s() rate=%u format=%#x width=%u channels=%u period_bytes=%d\n", |
556 | 572 | __func__, params_rate(params), params_format(params), |
557 | | - params_width(params), params_channels(params)); |
| 573 | + params_width(params), params_channels(params), period_bytes); |
558 | 574 |
|
559 | 575 | if (channels > dd->mic_no) { |
560 | 576 | dev_err(comp->dev, "more channels %u than microphones %d\n", |
@@ -608,7 +624,8 @@ static int mchp_pdmc_hw_params(struct snd_pcm_substream *substream, |
608 | 624 |
|
609 | 625 | mr_val |= FIELD_PREP(MCHP_PDMC_MR_SINCORDER_MASK, dd->sinc_order); |
610 | 626 |
|
611 | | - dd->addr.maxburst = mchp_pdmc_period_to_maxburst(snd_pcm_lib_period_bytes(substream)); |
| 627 | + maxburst = mchp_pdmc_period_to_maxburst(period_bytes, sample_bytes); |
| 628 | + dd->addr.maxburst = maxburst; |
612 | 629 | mr_val |= FIELD_PREP(MCHP_PDMC_MR_CHUNK_MASK, dd->addr.maxburst); |
613 | 630 | dev_dbg(comp->dev, "maxburst set to %d\n", dd->addr.maxburst); |
614 | 631 |
|
@@ -760,6 +777,7 @@ static const struct snd_soc_dai_ops mchp_pdmc_dai_ops = { |
760 | 777 | }; |
761 | 778 |
|
762 | 779 | static struct snd_soc_dai_driver mchp_pdmc_dai = { |
| 780 | + .name = "mchp-pdmc", |
763 | 781 | .capture = { |
764 | 782 | .stream_name = "Capture", |
765 | 783 | .channels_min = 1, |
|
0 commit comments