Skip to content

Commit

Permalink
Merge remote-tracking branches 'asoc/topic/fsl-easi', 'asoc/topic/fsl…
Browse files Browse the repository at this point in the history
…-sai', 'asoc/topic/fsl-ssi' and 'asoc/topic/intel' into asoc-next
  • Loading branch information
broonie committed Oct 6, 2014
5 parents 565fefd + d177143 + eadb001 + b93427b + bb78cdd commit 57b027f
Show file tree
Hide file tree
Showing 13 changed files with 621 additions and 94 deletions.
8 changes: 1 addition & 7 deletions Documentation/devicetree/bindings/sound/fsl,ssi.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
23 changes: 19 additions & 4 deletions Documentation/devicetree/bindings/sound/fsl-sai.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
};
49 changes: 30 additions & 19 deletions sound/soc/codecs/rt5640.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions sound/soc/codecs/rt5640.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
52 changes: 42 additions & 10 deletions sound/soc/fsl/fsl_sai.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 6 additions & 1 deletion sound/soc/fsl/fsl_sai.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
/* SAI Transmit/Recieve Control Register */
#define FSL_SAI_CSR_TERE BIT(31)
#define FSL_SAI_CSR_FR BIT(25)
#define FSL_SAI_CSR_SR BIT(24)
#define FSL_SAI_CSR_xF_SHIFT 16
#define FSL_SAI_CSR_xF_W_SHIFT 18
#define FSL_SAI_CSR_xF_MASK (0x1f << FSL_SAI_CSR_xF_SHIFT)
Expand Down Expand Up @@ -131,12 +132,16 @@ struct fsl_sai {
struct clk *bus_clk;
struct clk *mclk_clk[FSL_SAI_MCLK_MAX];

bool big_endian_data;
bool is_lsb_first;
bool is_dsp_mode;
bool sai_on_imx;
bool synchronous[2];

struct snd_dmaengine_dai_dma_data dma_params_rx;
struct snd_dmaengine_dai_dma_data dma_params_tx;
};

#define TX 1
#define RX 0

#endif /* __FSL_SAI_H */
Loading

0 comments on commit 57b027f

Please sign in to comment.