Commit 86d811d8 authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'asoc/fix/davinci', 'asoc/fix/fsl-ssi',...

Merge remote-tracking branches 'asoc/fix/davinci', 'asoc/fix/fsl-ssi', 'asoc/fix/rockchip' and 'asoc/fix/rt286' into asoc-linus
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/dmi.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
...@@ -1132,6 +1133,17 @@ static const struct acpi_device_id rt298_acpi_match[] = { ...@@ -1132,6 +1133,17 @@ static const struct acpi_device_id rt298_acpi_match[] = {
}; };
MODULE_DEVICE_TABLE(acpi, rt298_acpi_match); MODULE_DEVICE_TABLE(acpi, rt298_acpi_match);
static const struct dmi_system_id force_combo_jack_table[] = {
{
.ident = "Intel Broxton P",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp"),
DMI_MATCH(DMI_PRODUCT_NAME, "Broxton P")
}
},
{ }
};
static int rt298_i2c_probe(struct i2c_client *i2c, static int rt298_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
...@@ -1184,11 +1196,16 @@ static int rt298_i2c_probe(struct i2c_client *i2c, ...@@ -1184,11 +1196,16 @@ static int rt298_i2c_probe(struct i2c_client *i2c,
/* enable jack combo mode on supported devices */ /* enable jack combo mode on supported devices */
acpiid = acpi_match_device(dev->driver->acpi_match_table, dev); acpiid = acpi_match_device(dev->driver->acpi_match_table, dev);
if (acpiid) { if (acpiid && acpiid->driver_data) {
rt298->pdata = *(struct rt298_platform_data *) rt298->pdata = *(struct rt298_platform_data *)
acpiid->driver_data; acpiid->driver_data;
} }
if (dmi_check_system(force_combo_jack_table)) {
rt298->pdata.cbj_en = true;
rt298->pdata.gpio2_en = false;
}
/* VREF Charging */ /* VREF Charging */
regmap_update_bits(rt298->regmap, 0x04, 0x80, 0x80); regmap_update_bits(rt298->regmap, 0x04, 0x80, 0x80);
regmap_update_bits(rt298->regmap, 0x1b, 0x860, 0x860); regmap_update_bits(rt298->regmap, 0x1b, 0x860, 0x860);
......
...@@ -489,7 +489,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, ...@@ -489,7 +489,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE); mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG, mcasp_clr_bits(mcasp, DAVINCI_MCASP_PDIR_REG,
ACLKX | AHCLKX | AFSX | ACLKR | AHCLKR | AFSR); ACLKX | AFSX | ACLKR | AHCLKR | AFSR);
mcasp->bclk_master = 0; mcasp->bclk_master = 0;
break; break;
default: default:
......
...@@ -137,6 +137,7 @@ static bool fsl_ssi_volatile_reg(struct device *dev, unsigned int reg) ...@@ -137,6 +137,7 @@ static bool fsl_ssi_volatile_reg(struct device *dev, unsigned int reg)
case CCSR_SSI_SACDAT: case CCSR_SSI_SACDAT:
case CCSR_SSI_SATAG: case CCSR_SSI_SATAG:
case CCSR_SSI_SACCST: case CCSR_SSI_SACCST:
case CCSR_SSI_SOR:
return true; return true;
default: default:
return false; return false;
......
...@@ -34,6 +34,13 @@ struct rk_i2s_dev { ...@@ -34,6 +34,13 @@ struct rk_i2s_dev {
struct regmap *regmap; struct regmap *regmap;
/*
* Used to indicate the tx/rx status.
* I2S controller hopes to start the tx and rx together,
* also to stop them when they are both try to stop.
*/
bool tx_start;
bool rx_start;
bool is_master_mode; bool is_master_mode;
}; };
...@@ -75,29 +82,37 @@ static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on) ...@@ -75,29 +82,37 @@ static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE); I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE);
regmap_update_bits(i2s->regmap, I2S_XFER, regmap_update_bits(i2s->regmap, I2S_XFER,
I2S_XFER_TXS_START, I2S_XFER_TXS_START | I2S_XFER_RXS_START,
I2S_XFER_TXS_START); I2S_XFER_TXS_START | I2S_XFER_RXS_START);
i2s->tx_start = true;
} else { } else {
i2s->tx_start = false;
regmap_update_bits(i2s->regmap, I2S_DMACR, regmap_update_bits(i2s->regmap, I2S_DMACR,
I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE); I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE);
regmap_update_bits(i2s->regmap, I2S_XFER, if (!i2s->rx_start) {
I2S_XFER_TXS_START, regmap_update_bits(i2s->regmap, I2S_XFER,
I2S_XFER_TXS_STOP); I2S_XFER_TXS_START |
I2S_XFER_RXS_START,
I2S_XFER_TXS_STOP |
I2S_XFER_RXS_STOP);
regmap_update_bits(i2s->regmap, I2S_CLR, regmap_update_bits(i2s->regmap, I2S_CLR,
I2S_CLR_TXC, I2S_CLR_TXC | I2S_CLR_RXC,
I2S_CLR_TXC); I2S_CLR_TXC | I2S_CLR_RXC);
regmap_read(i2s->regmap, I2S_CLR, &val);
/* Should wait for clear operation to finish */
while (val & I2S_CLR_TXC) {
regmap_read(i2s->regmap, I2S_CLR, &val); regmap_read(i2s->regmap, I2S_CLR, &val);
retry--;
if (!retry) { /* Should wait for clear operation to finish */
dev_warn(i2s->dev, "fail to clear\n"); while (val) {
break; regmap_read(i2s->regmap, I2S_CLR, &val);
retry--;
if (!retry) {
dev_warn(i2s->dev, "fail to clear\n");
break;
}
} }
} }
} }
...@@ -113,29 +128,37 @@ static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on) ...@@ -113,29 +128,37 @@ static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE); I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE);
regmap_update_bits(i2s->regmap, I2S_XFER, regmap_update_bits(i2s->regmap, I2S_XFER,
I2S_XFER_RXS_START, I2S_XFER_TXS_START | I2S_XFER_RXS_START,
I2S_XFER_RXS_START); I2S_XFER_TXS_START | I2S_XFER_RXS_START);
i2s->rx_start = true;
} else { } else {
i2s->rx_start = false;
regmap_update_bits(i2s->regmap, I2S_DMACR, regmap_update_bits(i2s->regmap, I2S_DMACR,
I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_DISABLE); I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_DISABLE);
regmap_update_bits(i2s->regmap, I2S_XFER, if (!i2s->tx_start) {
I2S_XFER_RXS_START, regmap_update_bits(i2s->regmap, I2S_XFER,
I2S_XFER_RXS_STOP); I2S_XFER_TXS_START |
I2S_XFER_RXS_START,
I2S_XFER_TXS_STOP |
I2S_XFER_RXS_STOP);
regmap_update_bits(i2s->regmap, I2S_CLR, regmap_update_bits(i2s->regmap, I2S_CLR,
I2S_CLR_RXC, I2S_CLR_TXC | I2S_CLR_RXC,
I2S_CLR_RXC); I2S_CLR_TXC | I2S_CLR_RXC);
regmap_read(i2s->regmap, I2S_CLR, &val);
/* Should wait for clear operation to finish */
while (val & I2S_CLR_RXC) {
regmap_read(i2s->regmap, I2S_CLR, &val); regmap_read(i2s->regmap, I2S_CLR, &val);
retry--;
if (!retry) { /* Should wait for clear operation to finish */
dev_warn(i2s->dev, "fail to clear\n"); while (val) {
break; regmap_read(i2s->regmap, I2S_CLR, &val);
retry--;
if (!retry) {
dev_warn(i2s->dev, "fail to clear\n");
break;
}
} }
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment