Loading Documentation/devicetree/bindings/sound/fsl,ssi.txt +1 −7 Original line number Diff line number Diff line Loading @@ -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 Loading Documentation/devicetree/bindings/sound/fsl-sai.txt +19 −4 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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; }; sound/soc/codecs/rt5640.c +30 −19 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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, Loading sound/soc/codecs/rt5640.h +3 −0 Original line number Diff line number Diff line Loading @@ -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 sound/soc/fsl/fsl_sai.c +42 −10 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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); Loading @@ -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 Loading Loading @@ -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, Loading Loading @@ -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); Loading Loading @@ -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 Loading
Documentation/devicetree/bindings/sound/fsl,ssi.txt +1 −7 Original line number Diff line number Diff line Loading @@ -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 Loading
Documentation/devicetree/bindings/sound/fsl-sai.txt +19 −4 Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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; };
sound/soc/codecs/rt5640.c +30 −19 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; } Loading Loading @@ -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, Loading
sound/soc/codecs/rt5640.h +3 −0 Original line number Diff line number Diff line Loading @@ -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
sound/soc/fsl/fsl_sai.c +42 −10 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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); Loading @@ -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 Loading Loading @@ -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, Loading Loading @@ -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); Loading Loading @@ -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