Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 57b027f6 authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branches 'asoc/topic/fsl-easi', 'asoc/topic/fsl-sai',...

Merge remote-tracking branches 'asoc/topic/fsl-easi', 'asoc/topic/fsl-sai', 'asoc/topic/fsl-ssi' and 'asoc/topic/intel' into asoc-next
Loading
Loading
Loading
Loading
+1 −7
Original line number Diff line number Diff line
@@ -58,13 +58,7 @@ Optional properties:
		    Documentation/devicetree/bindings/dma/dma.txt.
- dma-names:	    Two dmas have to be defined, "tx" and "rx", if fsl,imx-fiq
		    is not defined.
- fsl,mode:         The operating mode for the SSI interface.
                    "i2s-slave" - I2S mode, SSI is clock slave
                    "i2s-master" - I2S mode, SSI is clock master
                    "lj-slave" - left-justified mode, SSI is clock slave
                    "lj-master" - l.j. mode, SSI is clock master
                    "rj-slave" - right-justified mode, SSI is clock slave
                    "rj-master" - r.j., SSI is clock master
- fsl,mode:         The operating mode for the AC97 interface only.
                    "ac97-slave" - AC97 mode, SSI is clock slave
                    "ac97-master" - AC97 mode, SSI is clock master

+19 −4
Original line number Diff line number Diff line
@@ -20,9 +20,24 @@ Required properties:
  See ../pinctrl/pinctrl-bindings.txt for details of the property values.
- big-endian: Boolean property, required if all the FTM_PWM registers
  are big-endian rather than little-endian.
- big-endian-data: If this property is absent, the little endian mode will
  be in use as default, or the big endian mode will be in use for all the
  fifo data.
- lsb-first: Configures whether the LSB or the MSB is transmitted first for
  the fifo data. If this property is absent, the MSB is transmitted first as
  default, or the LSB is transmitted first.
- fsl,sai-synchronous-rx: This is a boolean property. If present, indicating
  that SAI will work in the synchronous mode (sync Tx with Rx) which means
  both the transimitter and receiver will send and receive data by following
  receiver's bit clocks and frame sync clocks.
- fsl,sai-asynchronous: This is a boolean property. If present, indicating
  that SAI will work in the asynchronous mode, which means both transimitter
  and receiver will send and receive data by following their own bit clocks
  and frame sync clocks separately.

Note:
- If both fsl,sai-asynchronous and fsl,sai-synchronous-rx are absent, the
  default synchronous mode (sync Rx with Tx) will be used, which means both
  transimitter and receiver will send and receive data by following clocks
  of transimitter.
- fsl,sai-asynchronous and fsl,sai-synchronous-rx are exclusive.

Example:
sai2: sai@40031000 {
@@ -38,5 +53,5 @@ sai2: sai@40031000 {
	      dmas = <&edma0 0 VF610_EDMA_MUXID0_SAI2_TX>,
		   <&edma0 0 VF610_EDMA_MUXID0_SAI2_RX>;
	      big-endian;
	      big-endian-data;
	      lsb-first;
};
+30 −19
Original line number Diff line number Diff line
@@ -1906,6 +1906,32 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec,
	return 0;
}

int rt5640_dmic_enable(struct snd_soc_codec *codec,
		       bool dmic1_data_pin, bool dmic2_data_pin)
{
	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);

	regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1,
		RT5640_GP2_PIN_MASK, RT5640_GP2_PIN_DMIC1_SCL);

	if (dmic1_data_pin) {
		regmap_update_bits(rt5640->regmap, RT5640_DMIC,
			RT5640_DMIC_1_DP_MASK, RT5640_DMIC_1_DP_GPIO3);
		regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1,
			RT5640_GP3_PIN_MASK, RT5640_GP3_PIN_DMIC1_SDA);
	}

	if (dmic2_data_pin) {
		regmap_update_bits(rt5640->regmap, RT5640_DMIC,
			RT5640_DMIC_2_DP_MASK, RT5640_DMIC_2_DP_GPIO4);
		regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1,
			RT5640_GP4_PIN_MASK, RT5640_GP4_PIN_DMIC2_SDA);
	}

	return 0;
}
EXPORT_SYMBOL_GPL(rt5640_dmic_enable);

static int rt5640_probe(struct snd_soc_codec *codec)
{
	struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
@@ -1945,6 +1971,10 @@ static int rt5640_probe(struct snd_soc_codec *codec)
		return -ENODEV;
	}

	if (rt5640->pdata.dmic_en)
		rt5640_dmic_enable(codec, rt5640->pdata.dmic1_data_pin,
					  rt5640->pdata.dmic2_data_pin);

	return 0;
}

@@ -2195,25 +2225,6 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
		regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4,
					RT5640_IN_DF2, RT5640_IN_DF2);

	if (rt5640->pdata.dmic_en) {
		regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1,
			RT5640_GP2_PIN_MASK, RT5640_GP2_PIN_DMIC1_SCL);

		if (rt5640->pdata.dmic1_data_pin) {
			regmap_update_bits(rt5640->regmap, RT5640_DMIC,
				RT5640_DMIC_1_DP_MASK, RT5640_DMIC_1_DP_GPIO3);
			regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1,
				RT5640_GP3_PIN_MASK, RT5640_GP3_PIN_DMIC1_SDA);
		}

		if (rt5640->pdata.dmic2_data_pin) {
			regmap_update_bits(rt5640->regmap, RT5640_DMIC,
				RT5640_DMIC_2_DP_MASK, RT5640_DMIC_2_DP_GPIO4);
			regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1,
				RT5640_GP4_PIN_MASK, RT5640_GP4_PIN_DMIC2_SDA);
		}
	}

	rt5640->hp_mute = 1;

	return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640,
+3 −0
Original line number Diff line number Diff line
@@ -2097,4 +2097,7 @@ struct rt5640_priv {
	bool hp_mute;
};

int rt5640_dmic_enable(struct snd_soc_codec *codec,
		       bool dmic1_data_pin, bool dmic2_data_pin);

#endif
+42 −10
Original line number Diff line number Diff line
@@ -175,7 +175,7 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
	bool tx = fsl_dir == FSL_FMT_TRANSMITTER;
	u32 val_cr2 = 0, val_cr4 = 0;

	if (!sai->big_endian_data)
	if (!sai->is_lsb_first)
		val_cr4 |= FSL_SAI_CR4_MF;

	/* DAI mode */
@@ -304,7 +304,7 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
	val_cr5 |= FSL_SAI_CR5_WNW(word_width);
	val_cr5 |= FSL_SAI_CR5_W0W(word_width);

	if (sai->big_endian_data)
	if (sai->is_lsb_first)
		val_cr5 |= FSL_SAI_CR5_FBT(0);
	else
		val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1);
@@ -330,13 +330,13 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
	u32 xcsr, count = 100;

	/*
	 * The transmitter bit clock and frame sync are to be
	 * used by both the transmitter and receiver.
	 * Asynchronous mode: Clear SYNC for both Tx and Rx.
	 * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx.
	 * Tx sync with Rx clocks: Clear SYNC for Rx, set it for Tx.
	 */
	regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC,
			   ~FSL_SAI_CR2_SYNC);
	regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, 0);
	regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC,
			   FSL_SAI_CR2_SYNC);
			   sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0);

	/*
	 * It is recommended that the transmitter is the last enabled
@@ -437,8 +437,13 @@ static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
{
	struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);

	regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 0xffffffff, 0x0);
	regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 0xffffffff, 0x0);
	/* Software Reset for both Tx and Rx */
	regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR);
	regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR);
	/* Clear SR bit to finish the reset */
	regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
	regmap_write(sai->regmap, FSL_SAI_RCSR, 0);

	regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK,
			   FSL_SAI_MAXBURST_TX * 2);
	regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK,
@@ -568,7 +573,7 @@ static int fsl_sai_probe(struct platform_device *pdev)
	if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx6sx-sai"))
		sai->sai_on_imx = true;

	sai->big_endian_data = of_property_read_bool(np, "big-endian-data");
	sai->is_lsb_first = of_property_read_bool(np, "lsb-first");

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(&pdev->dev, res);
@@ -617,6 +622,33 @@ static int fsl_sai_probe(struct platform_device *pdev)
		return ret;
	}

	/* Sync Tx with Rx as default by following old DT binding */
	sai->synchronous[RX] = true;
	sai->synchronous[TX] = false;
	fsl_sai_dai.symmetric_rates = 1;
	fsl_sai_dai.symmetric_channels = 1;
	fsl_sai_dai.symmetric_samplebits = 1;

	if (of_find_property(np, "fsl,sai-synchronous-rx", NULL) &&
	    of_find_property(np, "fsl,sai-asynchronous", NULL)) {
		/* error out if both synchronous and asynchronous are present */
		dev_err(&pdev->dev, "invalid binding for synchronous mode\n");
		return -EINVAL;
	}

	if (of_find_property(np, "fsl,sai-synchronous-rx", NULL)) {
		/* Sync Rx with Tx */
		sai->synchronous[RX] = false;
		sai->synchronous[TX] = true;
	} else if (of_find_property(np, "fsl,sai-asynchronous", NULL)) {
		/* Discard all settings for asynchronous mode */
		sai->synchronous[RX] = false;
		sai->synchronous[TX] = false;
		fsl_sai_dai.symmetric_rates = 0;
		fsl_sai_dai.symmetric_channels = 0;
		fsl_sai_dai.symmetric_samplebits = 0;
	}

	sai->dma_params_rx.addr = res->start + FSL_SAI_RDR;
	sai->dma_params_tx.addr = res->start + FSL_SAI_TDR;
	sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX;
Loading