152-ASoC-mchp-i2s-mcc-Add-support-to-select-TDM-pins.patch 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. From 2bbdc5b38603384996271a8817b0578a2360af2f Mon Sep 17 00:00:00 2001
  2. From: Codrin Ciubotariu <[email protected]>
  3. Date: Mon, 1 Mar 2021 19:09:03 +0200
  4. Subject: [PATCH 152/247] ASoC: mchp-i2s-mcc: Add support to select TDM pins
  5. SAMA7G5's I2S-MCC has 4 pairs of DIN/DOUT pins. Since TDM only uses a
  6. single pair of pins for synchronous capture and playback, the controller
  7. needs to be told which of the pair is connected. This can be mentioned
  8. using the "microchip,tdm-data-pair" property from DT. The property is
  9. optional, useful only if TDM is used. If it's missing, DIN/DOUT 0 pins
  10. will be used by default.
  11. Signed-off-by: Codrin Ciubotariu <[email protected]>
  12. Link: https://lore.kernel.org/r/[email protected]
  13. Signed-off-by: Mark Brown <[email protected]>
  14. ---
  15. sound/soc/atmel/mchp-i2s-mcc.c | 52 +++++++++++++++++++++++++++++++---
  16. 1 file changed, 48 insertions(+), 4 deletions(-)
  17. diff --git a/sound/soc/atmel/mchp-i2s-mcc.c b/sound/soc/atmel/mchp-i2s-mcc.c
  18. index dca4fd1e2dfd..0818fa864f0e 100644
  19. --- a/sound/soc/atmel/mchp-i2s-mcc.c
  20. +++ b/sound/soc/atmel/mchp-i2s-mcc.c
  21. @@ -100,6 +100,8 @@
  22. #define MCHP_I2SMCC_MRA_DATALENGTH_8_BITS_COMPACT (7 << 1)
  23. #define MCHP_I2SMCC_MRA_WIRECFG_MASK GENMASK(5, 4)
  24. +#define MCHP_I2SMCC_MRA_WIRECFG_TDM(pin) (((pin) << 4) & \
  25. + MCHP_I2SMCC_MRA_WIRECFG_MASK)
  26. #define MCHP_I2SMCC_MRA_WIRECFG_I2S_1_TDM_0 (0 << 4)
  27. #define MCHP_I2SMCC_MRA_WIRECFG_I2S_2_TDM_1 (1 << 4)
  28. #define MCHP_I2SMCC_MRA_WIRECFG_I2S_4_TDM_2 (2 << 4)
  29. @@ -245,6 +247,7 @@ struct mchp_i2s_mcc_dev {
  30. unsigned int frame_length;
  31. int tdm_slots;
  32. int channels;
  33. + u8 tdm_data_pair;
  34. unsigned int gclk_use:1;
  35. unsigned int gclk_running:1;
  36. unsigned int tx_rdy:1;
  37. @@ -589,6 +592,8 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream,
  38. if (!frame_length)
  39. frame_length = 2 * params_physical_width(params);
  40. } else if (dev->fmt & SND_SOC_DAIFMT_DSP_A) {
  41. + mra |= MCHP_I2SMCC_MRA_WIRECFG_TDM(dev->tdm_data_pair);
  42. +
  43. if (dev->tdm_slots) {
  44. if (channels % 2 && channels * 2 <= dev->tdm_slots) {
  45. /*
  46. @@ -914,6 +919,45 @@ static const struct of_device_id mchp_i2s_mcc_dt_ids[] = {
  47. MODULE_DEVICE_TABLE(of, mchp_i2s_mcc_dt_ids);
  48. #endif
  49. +static int mchp_i2s_mcc_soc_data_parse(struct platform_device *pdev,
  50. + struct mchp_i2s_mcc_dev *dev)
  51. +{
  52. + int err;
  53. +
  54. + if (!dev->soc) {
  55. + dev_err(&pdev->dev, "failed to get soc data\n");
  56. + return -ENODEV;
  57. + }
  58. +
  59. + if (dev->soc->data_pin_pair_num == 1)
  60. + return 0;
  61. +
  62. + err = of_property_read_u8(pdev->dev.of_node, "microchip,tdm-data-pair",
  63. + &dev->tdm_data_pair);
  64. + if (err < 0 && err != -EINVAL) {
  65. + dev_err(&pdev->dev,
  66. + "bad property data for 'microchip,tdm-data-pair': %d",
  67. + err);
  68. + return err;
  69. + }
  70. + if (err == -EINVAL) {
  71. + dev_info(&pdev->dev,
  72. + "'microchip,tdm-data-pair' not found; assuming DIN/DOUT 0 for TDM\n");
  73. + dev->tdm_data_pair = 0;
  74. + } else {
  75. + if (dev->tdm_data_pair > dev->soc->data_pin_pair_num - 1) {
  76. + dev_err(&pdev->dev,
  77. + "invalid value for 'microchip,tdm-data-pair': %d\n",
  78. + dev->tdm_data_pair);
  79. + return -EINVAL;
  80. + }
  81. + dev_dbg(&pdev->dev, "TMD format on DIN/DOUT %d pins\n",
  82. + dev->tdm_data_pair);
  83. + }
  84. +
  85. + return 0;
  86. +}
  87. +
  88. static int mchp_i2s_mcc_probe(struct platform_device *pdev)
  89. {
  90. struct mchp_i2s_mcc_dev *dev;
  91. @@ -966,10 +1010,10 @@ static int mchp_i2s_mcc_probe(struct platform_device *pdev)
  92. }
  93. dev->soc = of_device_get_match_data(&pdev->dev);
  94. - if (!dev->soc) {
  95. - dev_err(&pdev->dev, "failed to get soc data\n");
  96. - return -ENODEV;
  97. - }
  98. + err = mchp_i2s_mcc_soc_data_parse(pdev, dev);
  99. + if (err < 0)
  100. + return err;
  101. +
  102. dev->dev = &pdev->dev;
  103. dev->regmap = regmap;
  104. platform_set_drvdata(pdev, dev);
  105. --
  106. 2.32.0