153-ASoC-mchp-i2s-mcc-Add-FIFOs-support.patch 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. From 36bb4f0ab8e7ef69cc11d4d888aa898223b0e901 Mon Sep 17 00:00:00 2001
  2. From: Codrin Ciubotariu <[email protected]>
  3. Date: Mon, 1 Mar 2021 19:09:04 +0200
  4. Subject: [PATCH 153/247] ASoC: mchp-i2s-mcc: Add FIFOs support
  5. I2S-MCC found on SAMA7G5 includes 2 FIFOs (capture and playback). When
  6. FIFOs are enabled, bits I2SMCC_ISRA.TXLRDYx and I2SMCC_ISRA.TXRRDYx must
  7. not be used. Bits I2SMCC_ISRB.TXFFRDY and I2SMCC_ISRB.RXFFRDY must be used
  8. instead.
  9. Signed-off-by: Codrin Ciubotariu <[email protected]>
  10. Link: https://lore.kernel.org/r/[email protected]
  11. Signed-off-by: Mark Brown <[email protected]>
  12. ---
  13. sound/soc/atmel/mchp-i2s-mcc.c | 76 +++++++++++++++++++++++++---------
  14. 1 file changed, 56 insertions(+), 20 deletions(-)
  15. diff --git a/sound/soc/atmel/mchp-i2s-mcc.c b/sound/soc/atmel/mchp-i2s-mcc.c
  16. index 0818fa864f0e..188484e84f94 100644
  17. --- a/sound/soc/atmel/mchp-i2s-mcc.c
  18. +++ b/sound/soc/atmel/mchp-i2s-mcc.c
  19. @@ -176,7 +176,7 @@
  20. */
  21. #define MCHP_I2SMCC_MRB_CRAMODE_REGULAR (1 << 0)
  22. -#define MCHP_I2SMCC_MRB_FIFOEN BIT(1)
  23. +#define MCHP_I2SMCC_MRB_FIFOEN BIT(4)
  24. #define MCHP_I2SMCC_MRB_DMACHUNK_MASK GENMASK(9, 8)
  25. #define MCHP_I2SMCC_MRB_DMACHUNK(no_words) \
  26. @@ -230,6 +230,7 @@ static const struct regmap_config mchp_i2s_mcc_regmap_config = {
  27. struct mchp_i2s_mcc_soc_data {
  28. unsigned int data_pin_pair_num;
  29. + bool has_fifo;
  30. };
  31. struct mchp_i2s_mcc_dev {
  32. @@ -257,7 +258,7 @@ struct mchp_i2s_mcc_dev {
  33. static irqreturn_t mchp_i2s_mcc_interrupt(int irq, void *dev_id)
  34. {
  35. struct mchp_i2s_mcc_dev *dev = dev_id;
  36. - u32 sra, imra, srb, imrb, pendinga, pendingb, idra = 0;
  37. + u32 sra, imra, srb, imrb, pendinga, pendingb, idra = 0, idrb = 0;
  38. irqreturn_t ret = IRQ_NONE;
  39. regmap_read(dev->regmap, MCHP_I2SMCC_IMRA, &imra);
  40. @@ -275,24 +276,36 @@ static irqreturn_t mchp_i2s_mcc_interrupt(int irq, void *dev_id)
  41. * Tx/Rx ready interrupts are enabled when stopping only, to assure
  42. * availability and to disable clocks if necessary
  43. */
  44. - idra |= pendinga & (MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels) |
  45. - MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels));
  46. - if (idra)
  47. + if (dev->soc->has_fifo) {
  48. + idrb |= pendingb & (MCHP_I2SMCC_INT_TXFFRDY |
  49. + MCHP_I2SMCC_INT_RXFFRDY);
  50. + } else {
  51. + idra |= pendinga & (MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels) |
  52. + MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels));
  53. + }
  54. + if (idra || idrb)
  55. ret = IRQ_HANDLED;
  56. - if ((imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) &&
  57. - (imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) ==
  58. - (idra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels))) {
  59. + if ((!dev->soc->has_fifo &&
  60. + (imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) &&
  61. + (imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) ==
  62. + (idra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels))) ||
  63. + (dev->soc->has_fifo && imrb & MCHP_I2SMCC_INT_TXFFRDY)) {
  64. dev->tx_rdy = 1;
  65. wake_up_interruptible(&dev->wq_txrdy);
  66. }
  67. - if ((imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) &&
  68. - (imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) ==
  69. - (idra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels))) {
  70. + if ((!dev->soc->has_fifo &&
  71. + (imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) &&
  72. + (imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) ==
  73. + (idra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels))) ||
  74. + (dev->soc->has_fifo && imrb & MCHP_I2SMCC_INT_RXFFRDY)) {
  75. dev->rx_rdy = 1;
  76. wake_up_interruptible(&dev->wq_rxrdy);
  77. }
  78. - regmap_write(dev->regmap, MCHP_I2SMCC_IDRA, idra);
  79. + if (dev->soc->has_fifo)
  80. + regmap_write(dev->regmap, MCHP_I2SMCC_IDRB, idrb);
  81. + else
  82. + regmap_write(dev->regmap, MCHP_I2SMCC_IDRA, idra);
  83. return ret;
  84. }
  85. @@ -664,6 +677,10 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream,
  86. }
  87. }
  88. + /* enable FIFO if available */
  89. + if (dev->soc->has_fifo)
  90. + mrb |= MCHP_I2SMCC_MRB_FIFOEN;
  91. +
  92. /*
  93. * If we are already running, the wanted setup must be
  94. * the same with the one that's currently ongoing
  95. @@ -726,8 +743,13 @@ static int mchp_i2s_mcc_hw_free(struct snd_pcm_substream *substream,
  96. if (err == 0) {
  97. dev_warn_once(dev->dev,
  98. "Timeout waiting for Tx ready\n");
  99. - regmap_write(dev->regmap, MCHP_I2SMCC_IDRA,
  100. - MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels));
  101. + if (dev->soc->has_fifo)
  102. + regmap_write(dev->regmap, MCHP_I2SMCC_IDRB,
  103. + MCHP_I2SMCC_INT_TXFFRDY);
  104. + else
  105. + regmap_write(dev->regmap, MCHP_I2SMCC_IDRA,
  106. + MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels));
  107. +
  108. dev->tx_rdy = 1;
  109. }
  110. } else {
  111. @@ -737,8 +759,12 @@ static int mchp_i2s_mcc_hw_free(struct snd_pcm_substream *substream,
  112. if (err == 0) {
  113. dev_warn_once(dev->dev,
  114. "Timeout waiting for Rx ready\n");
  115. - regmap_write(dev->regmap, MCHP_I2SMCC_IDRA,
  116. - MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels));
  117. + if (dev->soc->has_fifo)
  118. + regmap_write(dev->regmap, MCHP_I2SMCC_IDRB,
  119. + MCHP_I2SMCC_INT_RXFFRDY);
  120. + else
  121. + regmap_write(dev->regmap, MCHP_I2SMCC_IDRA,
  122. + MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels));
  123. dev->rx_rdy = 1;
  124. }
  125. }
  126. @@ -765,7 +791,7 @@ static int mchp_i2s_mcc_trigger(struct snd_pcm_substream *substream, int cmd,
  127. struct mchp_i2s_mcc_dev *dev = snd_soc_dai_get_drvdata(dai);
  128. bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
  129. u32 cr = 0;
  130. - u32 iera = 0;
  131. + u32 iera = 0, ierb = 0;
  132. u32 sr;
  133. int err;
  134. @@ -789,7 +815,10 @@ static int mchp_i2s_mcc_trigger(struct snd_pcm_substream *substream, int cmd,
  135. * Enable Tx Ready interrupts on all channels
  136. * to assure all data is sent
  137. */
  138. - iera = MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels);
  139. + if (dev->soc->has_fifo)
  140. + ierb = MCHP_I2SMCC_INT_TXFFRDY;
  141. + else
  142. + iera = MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels);
  143. } else if (!is_playback && (sr & MCHP_I2SMCC_SR_RXEN)) {
  144. cr = MCHP_I2SMCC_CR_RXDIS;
  145. dev->rx_rdy = 0;
  146. @@ -797,7 +826,10 @@ static int mchp_i2s_mcc_trigger(struct snd_pcm_substream *substream, int cmd,
  147. * Enable Rx Ready interrupts on all channels
  148. * to assure all data is received
  149. */
  150. - iera = MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels);
  151. + if (dev->soc->has_fifo)
  152. + ierb = MCHP_I2SMCC_INT_RXFFRDY;
  153. + else
  154. + iera = MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels);
  155. }
  156. break;
  157. default:
  158. @@ -815,7 +847,10 @@ static int mchp_i2s_mcc_trigger(struct snd_pcm_substream *substream, int cmd,
  159. }
  160. }
  161. - regmap_write(dev->regmap, MCHP_I2SMCC_IERA, iera);
  162. + if (dev->soc->has_fifo)
  163. + regmap_write(dev->regmap, MCHP_I2SMCC_IERB, ierb);
  164. + else
  165. + regmap_write(dev->regmap, MCHP_I2SMCC_IERA, iera);
  166. regmap_write(dev->regmap, MCHP_I2SMCC_CR, cr);
  167. return 0;
  168. @@ -903,6 +938,7 @@ static struct mchp_i2s_mcc_soc_data mchp_i2s_mcc_sam9x60 = {
  169. static struct mchp_i2s_mcc_soc_data mchp_i2s_mcc_sama7g5 = {
  170. .data_pin_pair_num = 4,
  171. + .has_fifo = true,
  172. };
  173. static const struct of_device_id mchp_i2s_mcc_dt_ids[] = {
  174. --
  175. 2.32.0