mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-22 17:44:26 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			109 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 2bbdc5b38603384996271a8817b0578a2360af2f Mon Sep 17 00:00:00 2001
 | |
| From: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
 | |
| Date: Mon, 1 Mar 2021 19:09:03 +0200
 | |
| Subject: [PATCH 152/247] ASoC: mchp-i2s-mcc: Add support to select TDM pins
 | |
| 
 | |
| SAMA7G5's I2S-MCC has 4 pairs of DIN/DOUT pins. Since TDM only uses a
 | |
| single pair of pins for synchronous capture and playback, the controller
 | |
| needs to be told which of the pair is connected. This can be mentioned
 | |
| using the "microchip,tdm-data-pair" property from DT. The property is
 | |
| optional, useful only if TDM is used. If it's missing, DIN/DOUT 0 pins
 | |
| will be used by default.
 | |
| 
 | |
| Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
 | |
| Link: https://lore.kernel.org/r/20210301170905.835091-6-codrin.ciubotariu@microchip.com
 | |
| Signed-off-by: Mark Brown <broonie@kernel.org>
 | |
| ---
 | |
|  sound/soc/atmel/mchp-i2s-mcc.c | 52 +++++++++++++++++++++++++++++++---
 | |
|  1 file changed, 48 insertions(+), 4 deletions(-)
 | |
| 
 | |
| --- a/sound/soc/atmel/mchp-i2s-mcc.c
 | |
| +++ b/sound/soc/atmel/mchp-i2s-mcc.c
 | |
| @@ -100,6 +100,8 @@
 | |
|  #define MCHP_I2SMCC_MRA_DATALENGTH_8_BITS_COMPACT	(7 << 1)
 | |
|  
 | |
|  #define MCHP_I2SMCC_MRA_WIRECFG_MASK		GENMASK(5, 4)
 | |
| +#define MCHP_I2SMCC_MRA_WIRECFG_TDM(pin)	(((pin) << 4) & \
 | |
| +						 MCHP_I2SMCC_MRA_WIRECFG_MASK)
 | |
|  #define MCHP_I2SMCC_MRA_WIRECFG_I2S_1_TDM_0	(0 << 4)
 | |
|  #define MCHP_I2SMCC_MRA_WIRECFG_I2S_2_TDM_1	(1 << 4)
 | |
|  #define MCHP_I2SMCC_MRA_WIRECFG_I2S_4_TDM_2	(2 << 4)
 | |
| @@ -245,6 +247,7 @@ struct mchp_i2s_mcc_dev {
 | |
|  	unsigned int				frame_length;
 | |
|  	int					tdm_slots;
 | |
|  	int					channels;
 | |
| +	u8					tdm_data_pair;
 | |
|  	unsigned int				gclk_use:1;
 | |
|  	unsigned int				gclk_running:1;
 | |
|  	unsigned int				tx_rdy:1;
 | |
| @@ -589,6 +592,8 @@ static int mchp_i2s_mcc_hw_params(struct
 | |
|  		if (!frame_length)
 | |
|  			frame_length = 2 * params_physical_width(params);
 | |
|  	} else if (dev->fmt & SND_SOC_DAIFMT_DSP_A) {
 | |
| +		mra |= MCHP_I2SMCC_MRA_WIRECFG_TDM(dev->tdm_data_pair);
 | |
| +
 | |
|  		if (dev->tdm_slots) {
 | |
|  			if (channels % 2 && channels * 2 <= dev->tdm_slots) {
 | |
|  				/*
 | |
| @@ -914,6 +919,45 @@ static const struct of_device_id mchp_i2
 | |
|  MODULE_DEVICE_TABLE(of, mchp_i2s_mcc_dt_ids);
 | |
|  #endif
 | |
|  
 | |
| +static int mchp_i2s_mcc_soc_data_parse(struct platform_device *pdev,
 | |
| +				       struct mchp_i2s_mcc_dev *dev)
 | |
| +{
 | |
| +	int err;
 | |
| +
 | |
| +	if (!dev->soc) {
 | |
| +		dev_err(&pdev->dev, "failed to get soc data\n");
 | |
| +		return -ENODEV;
 | |
| +	}
 | |
| +
 | |
| +	if (dev->soc->data_pin_pair_num == 1)
 | |
| +		return 0;
 | |
| +
 | |
| +	err = of_property_read_u8(pdev->dev.of_node, "microchip,tdm-data-pair",
 | |
| +				  &dev->tdm_data_pair);
 | |
| +	if (err < 0 && err != -EINVAL) {
 | |
| +		dev_err(&pdev->dev,
 | |
| +			"bad property data for 'microchip,tdm-data-pair': %d",
 | |
| +			err);
 | |
| +		return err;
 | |
| +	}
 | |
| +	if (err == -EINVAL) {
 | |
| +		dev_info(&pdev->dev,
 | |
| +			 "'microchip,tdm-data-pair' not found; assuming DIN/DOUT 0 for TDM\n");
 | |
| +		dev->tdm_data_pair = 0;
 | |
| +	} else {
 | |
| +		if (dev->tdm_data_pair > dev->soc->data_pin_pair_num - 1) {
 | |
| +			dev_err(&pdev->dev,
 | |
| +				"invalid value for 'microchip,tdm-data-pair': %d\n",
 | |
| +				dev->tdm_data_pair);
 | |
| +			return -EINVAL;
 | |
| +		}
 | |
| +		dev_dbg(&pdev->dev, "TMD format on DIN/DOUT %d pins\n",
 | |
| +			dev->tdm_data_pair);
 | |
| +	}
 | |
| +
 | |
| +	return 0;
 | |
| +}
 | |
| +
 | |
|  static int mchp_i2s_mcc_probe(struct platform_device *pdev)
 | |
|  {
 | |
|  	struct mchp_i2s_mcc_dev *dev;
 | |
| @@ -966,10 +1010,10 @@ static int mchp_i2s_mcc_probe(struct pla
 | |
|  	}
 | |
|  
 | |
|  	dev->soc = of_device_get_match_data(&pdev->dev);
 | |
| -	if (!dev->soc) {
 | |
| -		dev_err(&pdev->dev, "failed to get soc data\n");
 | |
| -		return -ENODEV;
 | |
| -	}
 | |
| +	err = mchp_i2s_mcc_soc_data_parse(pdev, dev);
 | |
| +	if (err < 0)
 | |
| +		return err;
 | |
| +
 | |
|  	dev->dev = &pdev->dev;
 | |
|  	dev->regmap = regmap;
 | |
|  	platform_set_drvdata(pdev, dev);
 |