Merge remote-tracking branches 'asoc/topic/fsl-spdif', 'asoc/topic/imx', 'asoc/topic/intel', 'asoc/topic/mxs-saif' and 'asoc/topic/nuc900' into asoc-next
This commit is contained in:
Коммит
4f1eacf544
|
@ -14,10 +14,12 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/pm.h>
|
#include <linux/pm.h>
|
||||||
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/acpi.h>
|
#include <linux/acpi.h>
|
||||||
#include <linux/spi/spi.h>
|
#include <linux/spi/spi.h>
|
||||||
|
#include <linux/dmi.h>
|
||||||
#include <sound/core.h>
|
#include <sound/core.h>
|
||||||
#include <sound/pcm.h>
|
#include <sound/pcm.h>
|
||||||
#include <sound/pcm_params.h>
|
#include <sound/pcm_params.h>
|
||||||
|
@ -590,6 +592,89 @@ static int can_use_asrc(struct snd_soc_dapm_widget *source,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rt5670_sel_asrc_clk_src - select ASRC clock source for a set of filters
|
||||||
|
* @codec: SoC audio codec device.
|
||||||
|
* @filter_mask: mask of filters.
|
||||||
|
* @clk_src: clock source
|
||||||
|
*
|
||||||
|
* The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5670 can
|
||||||
|
* only support standard 32fs or 64fs i2s format, ASRC should be enabled to
|
||||||
|
* support special i2s clock format such as Intel's 100fs(100 * sampling rate).
|
||||||
|
* ASRC function will track i2s clock and generate a corresponding system clock
|
||||||
|
* for codec. This function provides an API to select the clock source for a
|
||||||
|
* set of filters specified by the mask. And the codec driver will turn on ASRC
|
||||||
|
* for these filters if ASRC is selected as their clock source.
|
||||||
|
*/
|
||||||
|
int rt5670_sel_asrc_clk_src(struct snd_soc_codec *codec,
|
||||||
|
unsigned int filter_mask, unsigned int clk_src)
|
||||||
|
{
|
||||||
|
unsigned int asrc2_mask = 0, asrc2_value = 0;
|
||||||
|
unsigned int asrc3_mask = 0, asrc3_value = 0;
|
||||||
|
|
||||||
|
if (clk_src > RT5670_CLK_SEL_SYS3)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (filter_mask & RT5670_DA_STEREO_FILTER) {
|
||||||
|
asrc2_mask |= RT5670_DA_STO_CLK_SEL_MASK;
|
||||||
|
asrc2_value = (asrc2_value & ~RT5670_DA_STO_CLK_SEL_MASK)
|
||||||
|
| (clk_src << RT5670_DA_STO_CLK_SEL_SFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter_mask & RT5670_DA_MONO_L_FILTER) {
|
||||||
|
asrc2_mask |= RT5670_DA_MONOL_CLK_SEL_MASK;
|
||||||
|
asrc2_value = (asrc2_value & ~RT5670_DA_MONOL_CLK_SEL_MASK)
|
||||||
|
| (clk_src << RT5670_DA_MONOL_CLK_SEL_SFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter_mask & RT5670_DA_MONO_R_FILTER) {
|
||||||
|
asrc2_mask |= RT5670_DA_MONOR_CLK_SEL_MASK;
|
||||||
|
asrc2_value = (asrc2_value & ~RT5670_DA_MONOR_CLK_SEL_MASK)
|
||||||
|
| (clk_src << RT5670_DA_MONOR_CLK_SEL_SFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter_mask & RT5670_AD_STEREO_FILTER) {
|
||||||
|
asrc2_mask |= RT5670_AD_STO1_CLK_SEL_MASK;
|
||||||
|
asrc2_value = (asrc2_value & ~RT5670_AD_STO1_CLK_SEL_MASK)
|
||||||
|
| (clk_src << RT5670_AD_STO1_CLK_SEL_SFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter_mask & RT5670_AD_MONO_L_FILTER) {
|
||||||
|
asrc3_mask |= RT5670_AD_MONOL_CLK_SEL_MASK;
|
||||||
|
asrc3_value = (asrc3_value & ~RT5670_AD_MONOL_CLK_SEL_MASK)
|
||||||
|
| (clk_src << RT5670_AD_MONOL_CLK_SEL_SFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter_mask & RT5670_AD_MONO_R_FILTER) {
|
||||||
|
asrc3_mask |= RT5670_AD_MONOR_CLK_SEL_MASK;
|
||||||
|
asrc3_value = (asrc3_value & ~RT5670_AD_MONOR_CLK_SEL_MASK)
|
||||||
|
| (clk_src << RT5670_AD_MONOR_CLK_SEL_SFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter_mask & RT5670_UP_RATE_FILTER) {
|
||||||
|
asrc3_mask |= RT5670_UP_CLK_SEL_MASK;
|
||||||
|
asrc3_value = (asrc3_value & ~RT5670_UP_CLK_SEL_MASK)
|
||||||
|
| (clk_src << RT5670_UP_CLK_SEL_SFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter_mask & RT5670_DOWN_RATE_FILTER) {
|
||||||
|
asrc3_mask |= RT5670_DOWN_CLK_SEL_MASK;
|
||||||
|
asrc3_value = (asrc3_value & ~RT5670_DOWN_CLK_SEL_MASK)
|
||||||
|
| (clk_src << RT5670_DOWN_CLK_SEL_SFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asrc2_mask)
|
||||||
|
snd_soc_update_bits(codec, RT5670_ASRC_2,
|
||||||
|
asrc2_mask, asrc2_value);
|
||||||
|
|
||||||
|
if (asrc3_mask)
|
||||||
|
snd_soc_update_bits(codec, RT5670_ASRC_3,
|
||||||
|
asrc3_mask, asrc3_value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(rt5670_sel_asrc_clk_src);
|
||||||
|
|
||||||
/* Digital Mixer */
|
/* Digital Mixer */
|
||||||
static const struct snd_kcontrol_new rt5670_sto1_adc_l_mix[] = {
|
static const struct snd_kcontrol_new rt5670_sto1_adc_l_mix[] = {
|
||||||
SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO1_ADC_MIXER,
|
SOC_DAPM_SINGLE("ADC1 Switch", RT5670_STO1_ADC_MIXER,
|
||||||
|
@ -2190,6 +2275,13 @@ static int rt5670_set_dai_sysclk(struct snd_soc_dai *dai,
|
||||||
if (freq == rt5670->sysclk && clk_id == rt5670->sysclk_src)
|
if (freq == rt5670->sysclk && clk_id == rt5670->sysclk_src)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (rt5670->pdata.jd_mode) {
|
||||||
|
if (clk_id == RT5670_SCLK_S_PLL1)
|
||||||
|
snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1");
|
||||||
|
else
|
||||||
|
snd_soc_dapm_disable_pin(&codec->dapm, "PLL1");
|
||||||
|
snd_soc_dapm_sync(&codec->dapm);
|
||||||
|
}
|
||||||
switch (clk_id) {
|
switch (clk_id) {
|
||||||
case RT5670_SCLK_S_MCLK:
|
case RT5670_SCLK_S_MCLK:
|
||||||
reg_val |= RT5670_SCLK_SRC_MCLK;
|
reg_val |= RT5670_SCLK_SRC_MCLK;
|
||||||
|
@ -2551,6 +2643,17 @@ static struct acpi_device_id rt5670_acpi_match[] = {
|
||||||
MODULE_DEVICE_TABLE(acpi, rt5670_acpi_match);
|
MODULE_DEVICE_TABLE(acpi, rt5670_acpi_match);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static const struct dmi_system_id dmi_platform_intel_braswell[] = {
|
||||||
|
{
|
||||||
|
.ident = "Intel Braswell",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
|
||||||
|
DMI_MATCH(DMI_BOARD_NAME, "Braswell CRB"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
static int rt5670_i2c_probe(struct i2c_client *i2c,
|
static int rt5670_i2c_probe(struct i2c_client *i2c,
|
||||||
const struct i2c_device_id *id)
|
const struct i2c_device_id *id)
|
||||||
{
|
{
|
||||||
|
@ -2570,6 +2673,12 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
|
||||||
if (pdata)
|
if (pdata)
|
||||||
rt5670->pdata = *pdata;
|
rt5670->pdata = *pdata;
|
||||||
|
|
||||||
|
if (dmi_check_system(dmi_platform_intel_braswell)) {
|
||||||
|
rt5670->pdata.dmic_en = true;
|
||||||
|
rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P;
|
||||||
|
rt5670->pdata.jd_mode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
rt5670->regmap = devm_regmap_init_i2c(i2c, &rt5670_regmap);
|
rt5670->regmap = devm_regmap_init_i2c(i2c, &rt5670_regmap);
|
||||||
if (IS_ERR(rt5670->regmap)) {
|
if (IS_ERR(rt5670->regmap)) {
|
||||||
ret = PTR_ERR(rt5670->regmap);
|
ret = PTR_ERR(rt5670->regmap);
|
||||||
|
@ -2611,6 +2720,10 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rt5670->pdata.jd_mode) {
|
if (rt5670->pdata.jd_mode) {
|
||||||
|
regmap_update_bits(rt5670->regmap, RT5670_GLB_CLK,
|
||||||
|
RT5670_SCLK_SRC_MASK, RT5670_SCLK_SRC_RCCLK);
|
||||||
|
rt5670->sysclk = 0;
|
||||||
|
rt5670->sysclk_src = RT5670_SCLK_S_RCCLK;
|
||||||
regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG1,
|
regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG1,
|
||||||
RT5670_PWR_MB, RT5670_PWR_MB);
|
RT5670_PWR_MB, RT5670_PWR_MB);
|
||||||
regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG2,
|
regmap_update_bits(rt5670->regmap, RT5670_PWR_ANLG2,
|
||||||
|
@ -2718,18 +2831,26 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pm_runtime_enable(&i2c->dev);
|
||||||
|
pm_request_idle(&i2c->dev);
|
||||||
|
|
||||||
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5670,
|
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5670,
|
||||||
rt5670_dai, ARRAY_SIZE(rt5670_dai));
|
rt5670_dai, ARRAY_SIZE(rt5670_dai));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
pm_runtime_put(&i2c->dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
err:
|
err:
|
||||||
|
pm_runtime_disable(&i2c->dev);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rt5670_i2c_remove(struct i2c_client *i2c)
|
static int rt5670_i2c_remove(struct i2c_client *i2c)
|
||||||
{
|
{
|
||||||
|
pm_runtime_disable(&i2c->dev);
|
||||||
snd_soc_unregister_codec(&i2c->dev);
|
snd_soc_unregister_codec(&i2c->dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1023,50 +1023,33 @@
|
||||||
#define RT5670_DMIC_2_M_NOR (0x0 << 8)
|
#define RT5670_DMIC_2_M_NOR (0x0 << 8)
|
||||||
#define RT5670_DMIC_2_M_ASYN (0x1 << 8)
|
#define RT5670_DMIC_2_M_ASYN (0x1 << 8)
|
||||||
|
|
||||||
|
/* ASRC clock source selection (0x84, 0x85) */
|
||||||
|
#define RT5670_CLK_SEL_SYS (0x0)
|
||||||
|
#define RT5670_CLK_SEL_I2S1_ASRC (0x1)
|
||||||
|
#define RT5670_CLK_SEL_I2S2_ASRC (0x2)
|
||||||
|
#define RT5670_CLK_SEL_I2S3_ASRC (0x3)
|
||||||
|
#define RT5670_CLK_SEL_SYS2 (0x5)
|
||||||
|
#define RT5670_CLK_SEL_SYS3 (0x6)
|
||||||
|
|
||||||
/* ASRC Control 2 (0x84) */
|
/* ASRC Control 2 (0x84) */
|
||||||
#define RT5670_MDA_L_M_MASK (0x1 << 15)
|
#define RT5670_DA_STO_CLK_SEL_MASK (0xf << 12)
|
||||||
#define RT5670_MDA_L_M_SFT 15
|
#define RT5670_DA_STO_CLK_SEL_SFT 12
|
||||||
#define RT5670_MDA_L_M_NOR (0x0 << 15)
|
#define RT5670_DA_MONOL_CLK_SEL_MASK (0xf << 8)
|
||||||
#define RT5670_MDA_L_M_ASYN (0x1 << 15)
|
#define RT5670_DA_MONOL_CLK_SEL_SFT 8
|
||||||
#define RT5670_MDA_R_M_MASK (0x1 << 14)
|
#define RT5670_DA_MONOR_CLK_SEL_MASK (0xf << 4)
|
||||||
#define RT5670_MDA_R_M_SFT 14
|
#define RT5670_DA_MONOR_CLK_SEL_SFT 4
|
||||||
#define RT5670_MDA_R_M_NOR (0x0 << 14)
|
#define RT5670_AD_STO1_CLK_SEL_MASK (0xf << 0)
|
||||||
#define RT5670_MDA_R_M_ASYN (0x1 << 14)
|
#define RT5670_AD_STO1_CLK_SEL_SFT 0
|
||||||
#define RT5670_MAD_L_M_MASK (0x1 << 13)
|
|
||||||
#define RT5670_MAD_L_M_SFT 13
|
|
||||||
#define RT5670_MAD_L_M_NOR (0x0 << 13)
|
|
||||||
#define RT5670_MAD_L_M_ASYN (0x1 << 13)
|
|
||||||
#define RT5670_MAD_R_M_MASK (0x1 << 12)
|
|
||||||
#define RT5670_MAD_R_M_SFT 12
|
|
||||||
#define RT5670_MAD_R_M_NOR (0x0 << 12)
|
|
||||||
#define RT5670_MAD_R_M_ASYN (0x1 << 12)
|
|
||||||
#define RT5670_ADC_M_MASK (0x1 << 11)
|
|
||||||
#define RT5670_ADC_M_SFT 11
|
|
||||||
#define RT5670_ADC_M_NOR (0x0 << 11)
|
|
||||||
#define RT5670_ADC_M_ASYN (0x1 << 11)
|
|
||||||
#define RT5670_STO_DAC_M_MASK (0x1 << 5)
|
|
||||||
#define RT5670_STO_DAC_M_SFT 5
|
|
||||||
#define RT5670_STO_DAC_M_NOR (0x0 << 5)
|
|
||||||
#define RT5670_STO_DAC_M_ASYN (0x1 << 5)
|
|
||||||
#define RT5670_I2S1_R_D_MASK (0x1 << 4)
|
|
||||||
#define RT5670_I2S1_R_D_SFT 4
|
|
||||||
#define RT5670_I2S1_R_D_DIS (0x0 << 4)
|
|
||||||
#define RT5670_I2S1_R_D_EN (0x1 << 4)
|
|
||||||
#define RT5670_I2S2_R_D_MASK (0x1 << 3)
|
|
||||||
#define RT5670_I2S2_R_D_SFT 3
|
|
||||||
#define RT5670_I2S2_R_D_DIS (0x0 << 3)
|
|
||||||
#define RT5670_I2S2_R_D_EN (0x1 << 3)
|
|
||||||
#define RT5670_PRE_SCLK_MASK (0x3)
|
|
||||||
#define RT5670_PRE_SCLK_SFT 0
|
|
||||||
#define RT5670_PRE_SCLK_512 (0x0)
|
|
||||||
#define RT5670_PRE_SCLK_1024 (0x1)
|
|
||||||
#define RT5670_PRE_SCLK_2048 (0x2)
|
|
||||||
|
|
||||||
/* ASRC Control 3 (0x85) */
|
/* ASRC Control 3 (0x85) */
|
||||||
#define RT5670_I2S1_RATE_MASK (0xf << 12)
|
#define RT5670_UP_CLK_SEL_MASK (0xf << 12)
|
||||||
#define RT5670_I2S1_RATE_SFT 12
|
#define RT5670_UP_CLK_SEL_SFT 12
|
||||||
#define RT5670_I2S2_RATE_MASK (0xf << 8)
|
#define RT5670_DOWN_CLK_SEL_MASK (0xf << 8)
|
||||||
#define RT5670_I2S2_RATE_SFT 8
|
#define RT5670_DOWN_CLK_SEL_SFT 8
|
||||||
|
#define RT5670_AD_MONOL_CLK_SEL_MASK (0xf << 4)
|
||||||
|
#define RT5670_AD_MONOL_CLK_SEL_SFT 4
|
||||||
|
#define RT5670_AD_MONOR_CLK_SEL_MASK (0xf << 0)
|
||||||
|
#define RT5670_AD_MONOR_CLK_SEL_SFT 0
|
||||||
|
|
||||||
/* ASRC Control 4 (0x89) */
|
/* ASRC Control 4 (0x89) */
|
||||||
#define RT5670_I2S1_PD_MASK (0x7 << 12)
|
#define RT5670_I2S1_PD_MASK (0x7 << 12)
|
||||||
|
@ -1983,6 +1966,21 @@ enum {
|
||||||
RT5670_DMIC_DATA_GPIO5,
|
RT5670_DMIC_DATA_GPIO5,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* filter mask */
|
||||||
|
enum {
|
||||||
|
RT5670_DA_STEREO_FILTER = 0x1,
|
||||||
|
RT5670_DA_MONO_L_FILTER = (0x1 << 1),
|
||||||
|
RT5670_DA_MONO_R_FILTER = (0x1 << 2),
|
||||||
|
RT5670_AD_STEREO_FILTER = (0x1 << 3),
|
||||||
|
RT5670_AD_MONO_L_FILTER = (0x1 << 4),
|
||||||
|
RT5670_AD_MONO_R_FILTER = (0x1 << 5),
|
||||||
|
RT5670_UP_RATE_FILTER = (0x1 << 6),
|
||||||
|
RT5670_DOWN_RATE_FILTER = (0x1 << 7),
|
||||||
|
};
|
||||||
|
|
||||||
|
int rt5670_sel_asrc_clk_src(struct snd_soc_codec *codec,
|
||||||
|
unsigned int filter_mask, unsigned int clk_src);
|
||||||
|
|
||||||
struct rt5670_priv {
|
struct rt5670_priv {
|
||||||
struct snd_soc_codec *codec;
|
struct snd_soc_codec *codec;
|
||||||
struct rt5670_platform_data pdata;
|
struct rt5670_platform_data pdata;
|
||||||
|
|
|
@ -90,7 +90,6 @@ struct spdif_mixer_control {
|
||||||
* @sysclk: system clock for rx clock rate measurement
|
* @sysclk: system clock for rx clock rate measurement
|
||||||
* @dma_params_tx: DMA parameters for transmit channel
|
* @dma_params_tx: DMA parameters for transmit channel
|
||||||
* @dma_params_rx: DMA parameters for receive channel
|
* @dma_params_rx: DMA parameters for receive channel
|
||||||
* @name: driver name
|
|
||||||
*/
|
*/
|
||||||
struct fsl_spdif_priv {
|
struct fsl_spdif_priv {
|
||||||
struct spdif_mixer_control fsl_spdif_control;
|
struct spdif_mixer_control fsl_spdif_control;
|
||||||
|
@ -109,12 +108,8 @@ struct fsl_spdif_priv {
|
||||||
struct clk *sysclk;
|
struct clk *sysclk;
|
||||||
struct snd_dmaengine_dai_dma_data dma_params_tx;
|
struct snd_dmaengine_dai_dma_data dma_params_tx;
|
||||||
struct snd_dmaengine_dai_dma_data dma_params_rx;
|
struct snd_dmaengine_dai_dma_data dma_params_rx;
|
||||||
|
|
||||||
/* The name space will be allocated dynamically */
|
|
||||||
char name[0];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* DPLL locked and lock loss interrupt handler */
|
/* DPLL locked and lock loss interrupt handler */
|
||||||
static void spdif_irq_dpll_lock(struct fsl_spdif_priv *spdif_priv)
|
static void spdif_irq_dpll_lock(struct fsl_spdif_priv *spdif_priv)
|
||||||
{
|
{
|
||||||
|
@ -1169,19 +1164,15 @@ static int fsl_spdif_probe(struct platform_device *pdev)
|
||||||
if (!np)
|
if (!np)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
spdif_priv = devm_kzalloc(&pdev->dev,
|
spdif_priv = devm_kzalloc(&pdev->dev, sizeof(*spdif_priv), GFP_KERNEL);
|
||||||
sizeof(struct fsl_spdif_priv) + strlen(np->name) + 1,
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!spdif_priv)
|
if (!spdif_priv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
strcpy(spdif_priv->name, np->name);
|
|
||||||
|
|
||||||
spdif_priv->pdev = pdev;
|
spdif_priv->pdev = pdev;
|
||||||
|
|
||||||
/* Initialize this copy of the CPU DAI driver structure */
|
/* Initialize this copy of the CPU DAI driver structure */
|
||||||
memcpy(&spdif_priv->cpu_dai_drv, &fsl_spdif_dai, sizeof(fsl_spdif_dai));
|
memcpy(&spdif_priv->cpu_dai_drv, &fsl_spdif_dai, sizeof(fsl_spdif_dai));
|
||||||
spdif_priv->cpu_dai_drv.name = spdif_priv->name;
|
spdif_priv->cpu_dai_drv.name = dev_name(&pdev->dev);
|
||||||
|
|
||||||
/* Get the addresses and IRQ */
|
/* Get the addresses and IRQ */
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
|
@ -1203,7 +1194,7 @@ static int fsl_spdif_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = devm_request_irq(&pdev->dev, irq, spdif_isr, 0,
|
ret = devm_request_irq(&pdev->dev, irq, spdif_isr, 0,
|
||||||
spdif_priv->name, spdif_priv);
|
dev_name(&pdev->dev), spdif_priv);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "could not claim irq %u\n", irq);
|
dev_err(&pdev->dev, "could not claim irq %u\n", irq);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -160,7 +160,7 @@ struct fsl_ssi_soc_data {
|
||||||
*/
|
*/
|
||||||
struct fsl_ssi_private {
|
struct fsl_ssi_private {
|
||||||
struct regmap *regs;
|
struct regmap *regs;
|
||||||
unsigned int irq;
|
int irq;
|
||||||
struct snd_soc_dai_driver cpu_dai_drv;
|
struct snd_soc_dai_driver cpu_dai_drv;
|
||||||
|
|
||||||
unsigned int dai_fmt;
|
unsigned int dai_fmt;
|
||||||
|
|
|
@ -60,6 +60,7 @@ static int imx_spdif_audio_probe(struct platform_device *pdev)
|
||||||
data->card.dev = &pdev->dev;
|
data->card.dev = &pdev->dev;
|
||||||
data->card.dai_link = &data->dai;
|
data->card.dai_link = &data->dai;
|
||||||
data->card.num_links = 1;
|
data->card.num_links = 1;
|
||||||
|
data->card.owner = THIS_MODULE;
|
||||||
|
|
||||||
ret = snd_soc_of_parse_card_name(&data->card, "model");
|
ret = snd_soc_of_parse_card_name(&data->card, "model");
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -46,7 +46,7 @@ config SND_SOC_INTEL_BAYTRAIL
|
||||||
|
|
||||||
config SND_SOC_INTEL_HASWELL_MACH
|
config SND_SOC_INTEL_HASWELL_MACH
|
||||||
tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint"
|
tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint"
|
||||||
depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && I2C && \\
|
depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && I2C && \
|
||||||
I2C_DESIGNWARE_PLATFORM
|
I2C_DESIGNWARE_PLATFORM
|
||||||
select SND_SOC_INTEL_HASWELL
|
select SND_SOC_INTEL_HASWELL
|
||||||
select SND_SOC_RT5640
|
select SND_SOC_RT5640
|
||||||
|
@ -76,7 +76,7 @@ config SND_SOC_INTEL_BYT_MAX98090_MACH
|
||||||
|
|
||||||
config SND_SOC_INTEL_BROADWELL_MACH
|
config SND_SOC_INTEL_BROADWELL_MACH
|
||||||
tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint"
|
tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint"
|
||||||
depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && DW_DMAC && \\
|
depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && DW_DMAC && \
|
||||||
I2C_DESIGNWARE_PLATFORM
|
I2C_DESIGNWARE_PLATFORM
|
||||||
select SND_SOC_INTEL_HASWELL
|
select SND_SOC_INTEL_HASWELL
|
||||||
select SND_COMPRESS_OFFLOAD
|
select SND_COMPRESS_OFFLOAD
|
||||||
|
|
|
@ -140,8 +140,6 @@ static struct snd_soc_ops broadwell_rt286_ops = {
|
||||||
|
|
||||||
static int broadwell_rtd_init(struct snd_soc_pcm_runtime *rtd)
|
static int broadwell_rtd_init(struct snd_soc_pcm_runtime *rtd)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = rtd->codec;
|
|
||||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
|
||||||
struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev);
|
struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev);
|
||||||
struct sst_hsw *broadwell = pdata->dsp;
|
struct sst_hsw *broadwell = pdata->dsp;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -155,14 +153,6 @@ static int broadwell_rtd_init(struct snd_soc_pcm_runtime *rtd)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* always connected - check HP for jack detect */
|
|
||||||
snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
|
|
||||||
snd_soc_dapm_enable_pin(dapm, "Speaker");
|
|
||||||
snd_soc_dapm_enable_pin(dapm, "Mic Jack");
|
|
||||||
snd_soc_dapm_enable_pin(dapm, "Line Jack");
|
|
||||||
snd_soc_dapm_enable_pin(dapm, "DMIC1");
|
|
||||||
snd_soc_dapm_enable_pin(dapm, "DMIC2");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,7 +132,6 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct snd_soc_codec *codec = runtime->codec;
|
struct snd_soc_codec *codec = runtime->codec;
|
||||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
|
||||||
struct snd_soc_card *card = runtime->card;
|
struct snd_soc_card *card = runtime->card;
|
||||||
const struct snd_soc_dapm_route *custom_map;
|
const struct snd_soc_dapm_route *custom_map;
|
||||||
int num_routes;
|
int num_routes;
|
||||||
|
@ -161,7 +160,7 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
|
||||||
num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map);
|
num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = snd_soc_dapm_add_routes(dapm, custom_map, num_routes);
|
ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -171,13 +170,8 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_soc_dapm_ignore_suspend(dapm, "HPOL");
|
snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
|
||||||
snd_soc_dapm_ignore_suspend(dapm, "HPOR");
|
snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
|
||||||
|
|
||||||
snd_soc_dapm_ignore_suspend(dapm, "SPOLP");
|
|
||||||
snd_soc_dapm_ignore_suspend(dapm, "SPOLN");
|
|
||||||
snd_soc_dapm_ignore_suspend(dapm, "SPORP");
|
|
||||||
snd_soc_dapm_ignore_suspend(dapm, "SPORN");
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,7 +215,6 @@ static int snd_byt_mc_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
static struct platform_driver snd_byt_mc_driver = {
|
static struct platform_driver snd_byt_mc_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.owner = THIS_MODULE,
|
|
||||||
.name = "bytt100_rt5640",
|
.name = "bytt100_rt5640",
|
||||||
.pm = &snd_soc_pm_ops,
|
.pm = &snd_soc_pm_ops,
|
||||||
},
|
},
|
||||||
|
|
|
@ -140,6 +140,7 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct snd_soc_dai *codec_dai = runtime->codec_dai;
|
struct snd_soc_dai *codec_dai = runtime->codec_dai;
|
||||||
|
struct snd_soc_codec *codec = codec_dai->codec;
|
||||||
|
|
||||||
/* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */
|
/* TDM 4 slots 24 bit, set Rx & Tx bitmask to 4 active slots */
|
||||||
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0xF, 4, 24);
|
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xF, 0xF, 4, 24);
|
||||||
|
@ -148,6 +149,19 @@ static int cht_codec_init(struct snd_soc_pcm_runtime *runtime)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Select codec ASRC clock source to track I2S1 clock, because codec
|
||||||
|
* is in slave mode and 100fs I2S format (BCLK = 100 * LRCLK) cannot
|
||||||
|
* be supported by RT5672. Otherwise, ASRC will be disabled and cause
|
||||||
|
* noise.
|
||||||
|
*/
|
||||||
|
rt5670_sel_asrc_clk_src(codec,
|
||||||
|
RT5670_DA_STEREO_FILTER
|
||||||
|
| RT5670_DA_MONO_L_FILTER
|
||||||
|
| RT5670_DA_MONO_R_FILTER
|
||||||
|
| RT5670_AD_STEREO_FILTER
|
||||||
|
| RT5670_AD_MONO_L_FILTER
|
||||||
|
| RT5670_AD_MONO_R_FILTER,
|
||||||
|
RT5670_CLK_SEL_I2S1_ASRC);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +284,6 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
static struct platform_driver snd_cht_mc_driver = {
|
static struct platform_driver snd_cht_mc_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.owner = THIS_MODULE,
|
|
||||||
.name = "cht-bsw-rt5672",
|
.name = "cht-bsw-rt5672",
|
||||||
.pm = &snd_soc_pm_ops,
|
.pm = &snd_soc_pm_ops,
|
||||||
},
|
},
|
||||||
|
|
|
@ -320,11 +320,6 @@ static struct snd_pcm_ops sst_byt_pcm_ops = {
|
||||||
.mmap = sst_byt_pcm_mmap,
|
.mmap = sst_byt_pcm_mmap,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void sst_byt_pcm_free(struct snd_pcm *pcm)
|
|
||||||
{
|
|
||||||
snd_pcm_lib_preallocate_free_for_all(pcm);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sst_byt_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
static int sst_byt_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
||||||
{
|
{
|
||||||
struct snd_pcm *pcm = rtd->pcm;
|
struct snd_pcm *pcm = rtd->pcm;
|
||||||
|
@ -403,7 +398,6 @@ static struct snd_soc_platform_driver byt_soc_platform = {
|
||||||
.remove = sst_byt_pcm_remove,
|
.remove = sst_byt_pcm_remove,
|
||||||
.ops = &sst_byt_pcm_ops,
|
.ops = &sst_byt_pcm_ops,
|
||||||
.pcm_new = sst_byt_pcm_new,
|
.pcm_new = sst_byt_pcm_new,
|
||||||
.pcm_free = sst_byt_pcm_free,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_soc_component_driver byt_dai_component = {
|
static const struct snd_soc_component_driver byt_dai_component = {
|
||||||
|
|
|
@ -410,7 +410,6 @@ void sst_dsp_free(struct sst_dsp *sst)
|
||||||
if (sst->ops->free)
|
if (sst->ops->free)
|
||||||
sst->ops->free(sst);
|
sst->ops->free(sst);
|
||||||
|
|
||||||
if (sst->dma)
|
|
||||||
sst_dma_free(sst->dma);
|
sst_dma_free(sst->dma);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(sst_dsp_free);
|
EXPORT_SYMBOL_GPL(sst_dsp_free);
|
||||||
|
|
|
@ -497,6 +497,7 @@ struct sst_module *sst_module_new(struct sst_fw *sst_fw,
|
||||||
sst_module->sst_fw = sst_fw;
|
sst_module->sst_fw = sst_fw;
|
||||||
sst_module->scratch_size = template->scratch_size;
|
sst_module->scratch_size = template->scratch_size;
|
||||||
sst_module->persistent_size = template->persistent_size;
|
sst_module->persistent_size = template->persistent_size;
|
||||||
|
sst_module->entry = template->entry;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&sst_module->block_list);
|
INIT_LIST_HEAD(&sst_module->block_list);
|
||||||
INIT_LIST_HEAD(&sst_module->runtime_list);
|
INIT_LIST_HEAD(&sst_module->runtime_list);
|
||||||
|
@ -790,6 +791,7 @@ int sst_module_alloc_blocks(struct sst_module *module)
|
||||||
struct sst_block_allocator ba;
|
struct sst_block_allocator ba;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
memset(&ba, 0, sizeof(ba));
|
||||||
ba.size = module->size;
|
ba.size = module->size;
|
||||||
ba.type = module->type;
|
ba.type = module->type;
|
||||||
ba.offset = module->offset;
|
ba.offset = module->offset;
|
||||||
|
@ -863,6 +865,7 @@ int sst_module_runtime_alloc_blocks(struct sst_module_runtime *runtime,
|
||||||
if (module->persistent_size == 0)
|
if (module->persistent_size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
memset(&ba, 0, sizeof(ba));
|
||||||
ba.size = module->persistent_size;
|
ba.size = module->persistent_size;
|
||||||
ba.type = SST_MEM_DRAM;
|
ba.type = SST_MEM_DRAM;
|
||||||
|
|
||||||
|
|
|
@ -306,7 +306,7 @@ static void hsw_reset(struct sst_dsp *sst)
|
||||||
static int hsw_set_dsp_D0(struct sst_dsp *sst)
|
static int hsw_set_dsp_D0(struct sst_dsp *sst)
|
||||||
{
|
{
|
||||||
int tries = 10;
|
int tries = 10;
|
||||||
u32 reg;
|
u32 reg, fw_dump_bit;
|
||||||
|
|
||||||
/* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */
|
/* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */
|
||||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||||
|
@ -368,7 +368,9 @@ finish:
|
||||||
can't be accessed, please enable each block before accessing. */
|
can't be accessed, please enable each block before accessing. */
|
||||||
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
|
reg = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||||
reg |= SST_VDRTCL0_DSRAMPGE_MASK | SST_VDRTCL0_ISRAMPGE_MASK;
|
reg |= SST_VDRTCL0_DSRAMPGE_MASK | SST_VDRTCL0_ISRAMPGE_MASK;
|
||||||
writel(reg, sst->addr.pci_cfg + SST_VDRTCTL0);
|
/* for D0, always enable the block(DSRAM[0]) used for FW dump */
|
||||||
|
fw_dump_bit = 1 << SST_VDRTCL0_DSRAMPGE_SHIFT;
|
||||||
|
writel(reg & ~fw_dump_bit, sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||||
|
|
||||||
|
|
||||||
/* disable DMA finish function for SSP0 & SSP1 */
|
/* disable DMA finish function for SSP0 & SSP1 */
|
||||||
|
@ -491,6 +493,7 @@ static const struct sst_sram_shift sram_shift[] = {
|
||||||
{SST_DEV_ID_LYNX_POINT, 6, 16}, /* lp */
|
{SST_DEV_ID_LYNX_POINT, 6, 16}, /* lp */
|
||||||
{SST_DEV_ID_WILDCAT_POINT, 2, 12}, /* wpt */
|
{SST_DEV_ID_WILDCAT_POINT, 2, 12}, /* wpt */
|
||||||
};
|
};
|
||||||
|
|
||||||
static u32 hsw_block_get_bit(struct sst_mem_block *block)
|
static u32 hsw_block_get_bit(struct sst_mem_block *block)
|
||||||
{
|
{
|
||||||
u32 bit = 0, shift = 0, index;
|
u32 bit = 0, shift = 0, index;
|
||||||
|
@ -587,6 +590,8 @@ static int hsw_block_disable(struct sst_mem_block *block)
|
||||||
|
|
||||||
val = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
|
val = readl(sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||||
bit = hsw_block_get_bit(block);
|
bit = hsw_block_get_bit(block);
|
||||||
|
/* don't disable DSRAM[0], keep it always enable for FW dump*/
|
||||||
|
if (bit != (1 << SST_VDRTCL0_DSRAMPGE_SHIFT))
|
||||||
writel(val | bit, sst->addr.pci_cfg + SST_VDRTCTL0);
|
writel(val | bit, sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||||
|
|
||||||
/* wait 18 DSP clock ticks */
|
/* wait 18 DSP clock ticks */
|
||||||
|
@ -612,7 +617,7 @@ static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata)
|
||||||
const struct sst_adsp_memregion *region;
|
const struct sst_adsp_memregion *region;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
int ret = -ENODEV, i, j, region_count;
|
int ret = -ENODEV, i, j, region_count;
|
||||||
u32 offset, size;
|
u32 offset, size, fw_dump_bit;
|
||||||
|
|
||||||
dev = sst->dma_dev;
|
dev = sst->dma_dev;
|
||||||
|
|
||||||
|
@ -669,9 +674,11 @@ static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* always enable the block(DSRAM[0]) used for FW dump */
|
||||||
|
fw_dump_bit = 1 << SST_VDRTCL0_DSRAMPGE_SHIFT;
|
||||||
/* set default power gating control, enable power gating control for all blocks. that is,
|
/* set default power gating control, enable power gating control for all blocks. that is,
|
||||||
can't be accessed, please enable each block before accessing. */
|
can't be accessed, please enable each block before accessing. */
|
||||||
writel(0xffffffff, sst->addr.pci_cfg + SST_VDRTCTL0);
|
writel(0xffffffff & ~fw_dump_bit, sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,6 +94,8 @@
|
||||||
/* Mailbox */
|
/* Mailbox */
|
||||||
#define IPC_MAX_MAILBOX_BYTES 256
|
#define IPC_MAX_MAILBOX_BYTES 256
|
||||||
|
|
||||||
|
#define INVALID_STREAM_HW_ID 0xffffffff
|
||||||
|
|
||||||
/* Global Message - Types and Replies */
|
/* Global Message - Types and Replies */
|
||||||
enum ipc_glb_type {
|
enum ipc_glb_type {
|
||||||
IPC_GLB_GET_FW_VERSION = 0, /* Retrieves firmware version */
|
IPC_GLB_GET_FW_VERSION = 0, /* Retrieves firmware version */
|
||||||
|
@ -275,7 +277,6 @@ struct sst_hsw {
|
||||||
/* FW config */
|
/* FW config */
|
||||||
struct sst_hsw_ipc_fw_ready fw_ready;
|
struct sst_hsw_ipc_fw_ready fw_ready;
|
||||||
struct sst_hsw_ipc_fw_version version;
|
struct sst_hsw_ipc_fw_version version;
|
||||||
struct sst_module *scratch;
|
|
||||||
bool fw_done;
|
bool fw_done;
|
||||||
struct sst_fw *sst_fw;
|
struct sst_fw *sst_fw;
|
||||||
|
|
||||||
|
@ -1208,6 +1209,7 @@ struct sst_hsw_stream *sst_hsw_stream_new(struct sst_hsw *hsw, int id,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
spin_lock_irqsave(&sst->spinlock, flags);
|
spin_lock_irqsave(&sst->spinlock, flags);
|
||||||
|
stream->reply.stream_hw_id = INVALID_STREAM_HW_ID;
|
||||||
list_add(&stream->node, &hsw->stream_list);
|
list_add(&stream->node, &hsw->stream_list);
|
||||||
stream->notify_position = notify_position;
|
stream->notify_position = notify_position;
|
||||||
stream->pdata = data;
|
stream->pdata = data;
|
||||||
|
@ -2132,7 +2134,6 @@ void sst_hsw_dsp_free(struct device *dev, struct sst_pdata *pdata)
|
||||||
dma_free_coherent(hsw->dsp->dma_dev, SST_HSW_DX_CONTEXT_SIZE,
|
dma_free_coherent(hsw->dsp->dma_dev, SST_HSW_DX_CONTEXT_SIZE,
|
||||||
hsw->dx_context, hsw->dx_context_paddr);
|
hsw->dx_context, hsw->dx_context_paddr);
|
||||||
sst_dsp_free(hsw->dsp);
|
sst_dsp_free(hsw->dsp);
|
||||||
kfree(hsw->scratch);
|
|
||||||
kthread_stop(hsw->tx_thread);
|
kthread_stop(hsw->tx_thread);
|
||||||
kfree(hsw->msg);
|
kfree(hsw->msg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,6 @@ static const u32 volume_map[] = {
|
||||||
#define HSW_PCM_DAI_ID_OFFLOAD0 1
|
#define HSW_PCM_DAI_ID_OFFLOAD0 1
|
||||||
#define HSW_PCM_DAI_ID_OFFLOAD1 2
|
#define HSW_PCM_DAI_ID_OFFLOAD1 2
|
||||||
#define HSW_PCM_DAI_ID_LOOPBACK 3
|
#define HSW_PCM_DAI_ID_LOOPBACK 3
|
||||||
#define HSW_PCM_DAI_ID_CAPTURE 4
|
|
||||||
|
|
||||||
|
|
||||||
static const struct snd_pcm_hardware hsw_pcm_hardware = {
|
static const struct snd_pcm_hardware hsw_pcm_hardware = {
|
||||||
|
@ -99,6 +98,7 @@ static const struct snd_pcm_hardware hsw_pcm_hardware = {
|
||||||
|
|
||||||
struct hsw_pcm_module_map {
|
struct hsw_pcm_module_map {
|
||||||
int dai_id;
|
int dai_id;
|
||||||
|
int stream;
|
||||||
enum sst_hsw_module_id mod_id;
|
enum sst_hsw_module_id mod_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -135,7 +135,17 @@ struct hsw_priv_data {
|
||||||
struct snd_dma_buffer dmab[HSW_PCM_COUNT][2];
|
struct snd_dma_buffer dmab[HSW_PCM_COUNT][2];
|
||||||
|
|
||||||
/* DAI data */
|
/* DAI data */
|
||||||
struct hsw_pcm_data pcm[HSW_PCM_COUNT];
|
struct hsw_pcm_data pcm[HSW_PCM_COUNT][2];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* static mappings between PCMs and modules - may be dynamic in future */
|
||||||
|
static struct hsw_pcm_module_map mod_map[] = {
|
||||||
|
{HSW_PCM_DAI_ID_SYSTEM, 0, SST_HSW_MODULE_PCM_SYSTEM},
|
||||||
|
{HSW_PCM_DAI_ID_OFFLOAD0, 0, SST_HSW_MODULE_PCM},
|
||||||
|
{HSW_PCM_DAI_ID_OFFLOAD1, 0, SST_HSW_MODULE_PCM},
|
||||||
|
{HSW_PCM_DAI_ID_LOOPBACK, 1, SST_HSW_MODULE_PCM_REFERENCE},
|
||||||
|
{HSW_PCM_DAI_ID_SYSTEM, 1, SST_HSW_MODULE_PCM_CAPTURE},
|
||||||
};
|
};
|
||||||
|
|
||||||
static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data);
|
static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data);
|
||||||
|
@ -168,9 +178,14 @@ static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol,
|
||||||
(struct soc_mixer_control *)kcontrol->private_value;
|
(struct soc_mixer_control *)kcontrol->private_value;
|
||||||
struct hsw_priv_data *pdata =
|
struct hsw_priv_data *pdata =
|
||||||
snd_soc_platform_get_drvdata(platform);
|
snd_soc_platform_get_drvdata(platform);
|
||||||
struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg];
|
struct hsw_pcm_data *pcm_data;
|
||||||
struct sst_hsw *hsw = pdata->hsw;
|
struct sst_hsw *hsw = pdata->hsw;
|
||||||
u32 volume;
|
u32 volume;
|
||||||
|
int dai, stream;
|
||||||
|
|
||||||
|
dai = mod_map[mc->reg].dai_id;
|
||||||
|
stream = mod_map[mc->reg].stream;
|
||||||
|
pcm_data = &pdata->pcm[dai][stream];
|
||||||
|
|
||||||
mutex_lock(&pcm_data->mutex);
|
mutex_lock(&pcm_data->mutex);
|
||||||
pm_runtime_get_sync(pdata->dev);
|
pm_runtime_get_sync(pdata->dev);
|
||||||
|
@ -212,9 +227,14 @@ static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol,
|
||||||
(struct soc_mixer_control *)kcontrol->private_value;
|
(struct soc_mixer_control *)kcontrol->private_value;
|
||||||
struct hsw_priv_data *pdata =
|
struct hsw_priv_data *pdata =
|
||||||
snd_soc_platform_get_drvdata(platform);
|
snd_soc_platform_get_drvdata(platform);
|
||||||
struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg];
|
struct hsw_pcm_data *pcm_data;
|
||||||
struct sst_hsw *hsw = pdata->hsw;
|
struct sst_hsw *hsw = pdata->hsw;
|
||||||
u32 volume;
|
u32 volume;
|
||||||
|
int dai, stream;
|
||||||
|
|
||||||
|
dai = mod_map[mc->reg].dai_id;
|
||||||
|
stream = mod_map[mc->reg].stream;
|
||||||
|
pcm_data = &pdata->pcm[dai][stream];
|
||||||
|
|
||||||
mutex_lock(&pcm_data->mutex);
|
mutex_lock(&pcm_data->mutex);
|
||||||
pm_runtime_get_sync(pdata->dev);
|
pm_runtime_get_sync(pdata->dev);
|
||||||
|
@ -309,7 +329,7 @@ static const struct snd_kcontrol_new hsw_volume_controls[] = {
|
||||||
ARRAY_SIZE(volume_map) - 1, 0,
|
ARRAY_SIZE(volume_map) - 1, 0,
|
||||||
hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
|
hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
|
||||||
/* Mic Capture volume */
|
/* Mic Capture volume */
|
||||||
SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 0, 0, 8,
|
SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 4, 0, 8,
|
||||||
ARRAY_SIZE(volume_map) - 1, 0,
|
ARRAY_SIZE(volume_map) - 1, 0,
|
||||||
hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
|
hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
|
||||||
};
|
};
|
||||||
|
@ -353,7 +373,7 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||||
struct hsw_priv_data *pdata =
|
struct hsw_priv_data *pdata =
|
||||||
snd_soc_platform_get_drvdata(rtd->platform);
|
snd_soc_platform_get_drvdata(rtd->platform);
|
||||||
struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
|
struct hsw_pcm_data *pcm_data;
|
||||||
struct sst_hsw *hsw = pdata->hsw;
|
struct sst_hsw *hsw = pdata->hsw;
|
||||||
struct sst_module *module_data;
|
struct sst_module *module_data;
|
||||||
struct sst_dsp *dsp;
|
struct sst_dsp *dsp;
|
||||||
|
@ -362,7 +382,10 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||||
enum sst_hsw_stream_path_id path_id;
|
enum sst_hsw_stream_path_id path_id;
|
||||||
u32 rate, bits, map, pages, module_id;
|
u32 rate, bits, map, pages, module_id;
|
||||||
u8 channels;
|
u8 channels;
|
||||||
int ret;
|
int ret, dai;
|
||||||
|
|
||||||
|
dai = mod_map[rtd->cpu_dai->id].dai_id;
|
||||||
|
pcm_data = &pdata->pcm[dai][substream->stream];
|
||||||
|
|
||||||
/* check if we are being called a subsequent time */
|
/* check if we are being called a subsequent time */
|
||||||
if (pcm_data->allocated) {
|
if (pcm_data->allocated) {
|
||||||
|
@ -552,8 +575,12 @@ static int hsw_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
|
||||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||||
struct hsw_priv_data *pdata =
|
struct hsw_priv_data *pdata =
|
||||||
snd_soc_platform_get_drvdata(rtd->platform);
|
snd_soc_platform_get_drvdata(rtd->platform);
|
||||||
struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
|
struct hsw_pcm_data *pcm_data;
|
||||||
struct sst_hsw *hsw = pdata->hsw;
|
struct sst_hsw *hsw = pdata->hsw;
|
||||||
|
int dai;
|
||||||
|
|
||||||
|
dai = mod_map[rtd->cpu_dai->id].dai_id;
|
||||||
|
pcm_data = &pdata->pcm[dai][substream->stream];
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SNDRV_PCM_TRIGGER_START:
|
case SNDRV_PCM_TRIGGER_START:
|
||||||
|
@ -597,11 +624,16 @@ static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream)
|
||||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||||
struct hsw_priv_data *pdata =
|
struct hsw_priv_data *pdata =
|
||||||
snd_soc_platform_get_drvdata(rtd->platform);
|
snd_soc_platform_get_drvdata(rtd->platform);
|
||||||
struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
|
struct hsw_pcm_data *pcm_data;
|
||||||
struct sst_hsw *hsw = pdata->hsw;
|
struct sst_hsw *hsw = pdata->hsw;
|
||||||
snd_pcm_uframes_t offset;
|
snd_pcm_uframes_t offset;
|
||||||
uint64_t ppos;
|
uint64_t ppos;
|
||||||
u32 position = sst_hsw_get_dsp_position(hsw, pcm_data->stream);
|
u32 position;
|
||||||
|
int dai;
|
||||||
|
|
||||||
|
dai = mod_map[rtd->cpu_dai->id].dai_id;
|
||||||
|
pcm_data = &pdata->pcm[dai][substream->stream];
|
||||||
|
position = sst_hsw_get_dsp_position(hsw, pcm_data->stream);
|
||||||
|
|
||||||
offset = bytes_to_frames(runtime, position);
|
offset = bytes_to_frames(runtime, position);
|
||||||
ppos = sst_hsw_get_dsp_presentation_position(hsw, pcm_data->stream);
|
ppos = sst_hsw_get_dsp_presentation_position(hsw, pcm_data->stream);
|
||||||
|
@ -618,8 +650,10 @@ static int hsw_pcm_open(struct snd_pcm_substream *substream)
|
||||||
snd_soc_platform_get_drvdata(rtd->platform);
|
snd_soc_platform_get_drvdata(rtd->platform);
|
||||||
struct hsw_pcm_data *pcm_data;
|
struct hsw_pcm_data *pcm_data;
|
||||||
struct sst_hsw *hsw = pdata->hsw;
|
struct sst_hsw *hsw = pdata->hsw;
|
||||||
|
int dai;
|
||||||
|
|
||||||
pcm_data = &pdata->pcm[rtd->cpu_dai->id];
|
dai = mod_map[rtd->cpu_dai->id].dai_id;
|
||||||
|
pcm_data = &pdata->pcm[dai][substream->stream];
|
||||||
|
|
||||||
mutex_lock(&pcm_data->mutex);
|
mutex_lock(&pcm_data->mutex);
|
||||||
pm_runtime_get_sync(pdata->dev);
|
pm_runtime_get_sync(pdata->dev);
|
||||||
|
@ -648,9 +682,12 @@ static int hsw_pcm_close(struct snd_pcm_substream *substream)
|
||||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||||
struct hsw_priv_data *pdata =
|
struct hsw_priv_data *pdata =
|
||||||
snd_soc_platform_get_drvdata(rtd->platform);
|
snd_soc_platform_get_drvdata(rtd->platform);
|
||||||
struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
|
struct hsw_pcm_data *pcm_data;
|
||||||
struct sst_hsw *hsw = pdata->hsw;
|
struct sst_hsw *hsw = pdata->hsw;
|
||||||
int ret;
|
int ret, dai;
|
||||||
|
|
||||||
|
dai = mod_map[rtd->cpu_dai->id].dai_id;
|
||||||
|
pcm_data = &pdata->pcm[dai][substream->stream];
|
||||||
|
|
||||||
mutex_lock(&pcm_data->mutex);
|
mutex_lock(&pcm_data->mutex);
|
||||||
ret = sst_hsw_stream_reset(hsw, pcm_data->stream);
|
ret = sst_hsw_stream_reset(hsw, pcm_data->stream);
|
||||||
|
@ -685,15 +722,6 @@ static struct snd_pcm_ops hsw_pcm_ops = {
|
||||||
.page = snd_pcm_sgbuf_ops_page,
|
.page = snd_pcm_sgbuf_ops_page,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* static mappings between PCMs and modules - may be dynamic in future */
|
|
||||||
static struct hsw_pcm_module_map mod_map[] = {
|
|
||||||
{HSW_PCM_DAI_ID_SYSTEM, SST_HSW_MODULE_PCM_SYSTEM},
|
|
||||||
{HSW_PCM_DAI_ID_OFFLOAD0, SST_HSW_MODULE_PCM},
|
|
||||||
{HSW_PCM_DAI_ID_OFFLOAD1, SST_HSW_MODULE_PCM},
|
|
||||||
{HSW_PCM_DAI_ID_LOOPBACK, SST_HSW_MODULE_PCM_REFERENCE},
|
|
||||||
{HSW_PCM_DAI_ID_CAPTURE, SST_HSW_MODULE_PCM_CAPTURE},
|
|
||||||
};
|
|
||||||
|
|
||||||
static int hsw_pcm_create_modules(struct hsw_priv_data *pdata)
|
static int hsw_pcm_create_modules(struct hsw_priv_data *pdata)
|
||||||
{
|
{
|
||||||
struct sst_hsw *hsw = pdata->hsw;
|
struct sst_hsw *hsw = pdata->hsw;
|
||||||
|
@ -701,7 +729,7 @@ static int hsw_pcm_create_modules(struct hsw_priv_data *pdata)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
|
for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
|
||||||
pcm_data = &pdata->pcm[i];
|
pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
|
||||||
|
|
||||||
/* create new runtime module, use same offset if recreated */
|
/* create new runtime module, use same offset if recreated */
|
||||||
pcm_data->runtime = sst_hsw_runtime_module_create(hsw,
|
pcm_data->runtime = sst_hsw_runtime_module_create(hsw,
|
||||||
|
@ -716,7 +744,7 @@ static int hsw_pcm_create_modules(struct hsw_priv_data *pdata)
|
||||||
|
|
||||||
err:
|
err:
|
||||||
for (--i; i >= 0; i--) {
|
for (--i; i >= 0; i--) {
|
||||||
pcm_data = &pdata->pcm[i];
|
pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
|
||||||
sst_hsw_runtime_module_free(pcm_data->runtime);
|
sst_hsw_runtime_module_free(pcm_data->runtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -729,17 +757,12 @@ static void hsw_pcm_free_modules(struct hsw_priv_data *pdata)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
|
for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
|
||||||
pcm_data = &pdata->pcm[i];
|
pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
|
||||||
|
|
||||||
sst_hsw_runtime_module_free(pcm_data->runtime);
|
sst_hsw_runtime_module_free(pcm_data->runtime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hsw_pcm_free(struct snd_pcm *pcm)
|
|
||||||
{
|
|
||||||
snd_pcm_lib_preallocate_free_for_all(pcm);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
||||||
{
|
{
|
||||||
struct snd_pcm *pcm = rtd->pcm;
|
struct snd_pcm *pcm = rtd->pcm;
|
||||||
|
@ -762,7 +785,10 @@ static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
priv_data->pcm[rtd->cpu_dai->id].hsw_pcm = pcm;
|
if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream)
|
||||||
|
priv_data->pcm[rtd->cpu_dai->id][SNDRV_PCM_STREAM_PLAYBACK].hsw_pcm = pcm;
|
||||||
|
if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream)
|
||||||
|
priv_data->pcm[rtd->cpu_dai->id][SNDRV_PCM_STREAM_CAPTURE].hsw_pcm = pcm;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -871,10 +897,9 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform)
|
||||||
/* allocate DSP buffer page tables */
|
/* allocate DSP buffer page tables */
|
||||||
for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) {
|
for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) {
|
||||||
|
|
||||||
mutex_init(&priv_data->pcm[i].mutex);
|
|
||||||
|
|
||||||
/* playback */
|
/* playback */
|
||||||
if (hsw_dais[i].playback.channels_min) {
|
if (hsw_dais[i].playback.channels_min) {
|
||||||
|
mutex_init(&priv_data->pcm[i][SNDRV_PCM_STREAM_PLAYBACK].mutex);
|
||||||
ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev,
|
ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev,
|
||||||
PAGE_SIZE, &priv_data->dmab[i][0]);
|
PAGE_SIZE, &priv_data->dmab[i][0]);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -883,6 +908,7 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform)
|
||||||
|
|
||||||
/* capture */
|
/* capture */
|
||||||
if (hsw_dais[i].capture.channels_min) {
|
if (hsw_dais[i].capture.channels_min) {
|
||||||
|
mutex_init(&priv_data->pcm[i][SNDRV_PCM_STREAM_CAPTURE].mutex);
|
||||||
ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev,
|
ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev,
|
||||||
PAGE_SIZE, &priv_data->dmab[i][1]);
|
PAGE_SIZE, &priv_data->dmab[i][1]);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -936,7 +962,6 @@ static struct snd_soc_platform_driver hsw_soc_platform = {
|
||||||
.remove = hsw_pcm_remove,
|
.remove = hsw_pcm_remove,
|
||||||
.ops = &hsw_pcm_ops,
|
.ops = &hsw_pcm_ops,
|
||||||
.pcm_new = hsw_pcm_new,
|
.pcm_new = hsw_pcm_new,
|
||||||
.pcm_free = hsw_pcm_free,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_soc_component_driver hsw_dai_component = {
|
static const struct snd_soc_component_driver hsw_dai_component = {
|
||||||
|
@ -1081,8 +1106,8 @@ static void hsw_pcm_complete(struct device *dev)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < HSW_PCM_DAI_ID_CAPTURE + 1; i++) {
|
for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
|
||||||
pcm_data = &pdata->pcm[i];
|
pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
|
||||||
|
|
||||||
if (!pcm_data->substream)
|
if (!pcm_data->substream)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1115,8 +1140,8 @@ static int hsw_pcm_prepare(struct device *dev)
|
||||||
if (pdata->pm_state == HSW_PM_STATE_D3)
|
if (pdata->pm_state == HSW_PM_STATE_D3)
|
||||||
return 0;
|
return 0;
|
||||||
/* suspend all active streams */
|
/* suspend all active streams */
|
||||||
for (i = 0; i < HSW_PCM_DAI_ID_CAPTURE + 1; i++) {
|
for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
|
||||||
pcm_data = &pdata->pcm[i];
|
pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
|
||||||
|
|
||||||
if (!pcm_data->substream)
|
if (!pcm_data->substream)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1134,8 +1159,8 @@ static int hsw_pcm_prepare(struct device *dev)
|
||||||
sst_hsw_dsp_runtime_suspend(hsw);
|
sst_hsw_dsp_runtime_suspend(hsw);
|
||||||
|
|
||||||
/* preserve persistent memory */
|
/* preserve persistent memory */
|
||||||
for (i = 0; i < HSW_PCM_DAI_ID_CAPTURE + 1; i++) {
|
for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
|
||||||
pcm_data = &pdata->pcm[i];
|
pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream];
|
||||||
|
|
||||||
if (!pcm_data->substream)
|
if (!pcm_data->substream)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -643,12 +643,6 @@ static struct snd_pcm_ops sst_platform_ops = {
|
||||||
.pointer = sst_platform_pcm_pointer,
|
.pointer = sst_platform_pcm_pointer,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void sst_pcm_free(struct snd_pcm *pcm)
|
|
||||||
{
|
|
||||||
dev_dbg(pcm->dev, "sst_pcm_free called\n");
|
|
||||||
snd_pcm_lib_preallocate_free_for_all(pcm);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd)
|
||||||
{
|
{
|
||||||
struct snd_soc_dai *dai = rtd->cpu_dai;
|
struct snd_soc_dai *dai = rtd->cpu_dai;
|
||||||
|
@ -679,7 +673,6 @@ static struct snd_soc_platform_driver sst_soc_platform_drv = {
|
||||||
.ops = &sst_platform_ops,
|
.ops = &sst_platform_ops,
|
||||||
.compr_ops = &sst_platform_compr_ops,
|
.compr_ops = &sst_platform_compr_ops,
|
||||||
.pcm_new = sst_pcm_new,
|
.pcm_new = sst_pcm_new,
|
||||||
.pcm_free = sst_pcm_free,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_soc_component_driver sst_component = {
|
static const struct snd_soc_component_driver sst_component = {
|
||||||
|
|
|
@ -245,7 +245,7 @@ static struct sst_machines *sst_acpi_find_machine(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sst_acpi_probe(struct platform_device *pdev)
|
static int sst_acpi_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -332,7 +332,7 @@ do_sst_cleanup:
|
||||||
* This function is called by OS when a device is unloaded
|
* This function is called by OS when a device is unloaded
|
||||||
* This frees the interrupt etc
|
* This frees the interrupt etc
|
||||||
*/
|
*/
|
||||||
int sst_acpi_remove(struct platform_device *pdev)
|
static int sst_acpi_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct intel_sst_drv *ctx;
|
struct intel_sst_drv *ctx;
|
||||||
|
|
||||||
|
@ -352,6 +352,8 @@ static struct sst_machines sst_acpi_bytcr[] = {
|
||||||
static struct sst_machines sst_acpi_chv[] = {
|
static struct sst_machines sst_acpi_chv[] = {
|
||||||
{"10EC5670", "cht-bsw", "cht-bsw-rt5672", NULL, "fw_sst_22a8.bin",
|
{"10EC5670", "cht-bsw", "cht-bsw-rt5672", NULL, "fw_sst_22a8.bin",
|
||||||
&chv_platform_data },
|
&chv_platform_data },
|
||||||
|
{"10EC5645", "cht-bsw", "cht-bsw-rt5645", NULL, "fw_sst_22a8.bin",
|
||||||
|
&chv_platform_data },
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -366,7 +368,6 @@ MODULE_DEVICE_TABLE(acpi, sst_acpi_ids);
|
||||||
static struct platform_driver sst_acpi_driver = {
|
static struct platform_driver sst_acpi_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "intel_sst_acpi",
|
.name = "intel_sst_acpi",
|
||||||
.owner = THIS_MODULE,
|
|
||||||
.acpi_match_table = ACPI_PTR(sst_acpi_ids),
|
.acpi_match_table = ACPI_PTR(sst_acpi_ids),
|
||||||
.pm = &intel_sst_pm,
|
.pm = &intel_sst_pm,
|
||||||
},
|
},
|
||||||
|
|
|
@ -324,7 +324,6 @@ void sst_firmware_load_cb(const struct firmware *fw, void *context)
|
||||||
|
|
||||||
if (ctx->sst_state != SST_RESET ||
|
if (ctx->sst_state != SST_RESET ||
|
||||||
ctx->fw_in_mem != NULL) {
|
ctx->fw_in_mem != NULL) {
|
||||||
if (fw != NULL)
|
|
||||||
release_firmware(fw);
|
release_firmware(fw);
|
||||||
mutex_unlock(&ctx->sst_lock);
|
mutex_unlock(&ctx->sst_lock);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -710,7 +710,7 @@ static int mxs_saif_probe(struct platform_device *pdev)
|
||||||
struct device_node *np = pdev->dev.of_node;
|
struct device_node *np = pdev->dev.of_node;
|
||||||
struct resource *iores;
|
struct resource *iores;
|
||||||
struct mxs_saif *saif;
|
struct mxs_saif *saif;
|
||||||
int ret = 0;
|
int irq, ret = 0;
|
||||||
struct device_node *master;
|
struct device_node *master;
|
||||||
|
|
||||||
if (!np)
|
if (!np)
|
||||||
|
@ -763,16 +763,16 @@ static int mxs_saif_probe(struct platform_device *pdev)
|
||||||
if (IS_ERR(saif->base))
|
if (IS_ERR(saif->base))
|
||||||
return PTR_ERR(saif->base);
|
return PTR_ERR(saif->base);
|
||||||
|
|
||||||
saif->irq = platform_get_irq(pdev, 0);
|
irq = platform_get_irq(pdev, 0);
|
||||||
if (saif->irq < 0) {
|
if (irq < 0) {
|
||||||
ret = saif->irq;
|
ret = irq;
|
||||||
dev_err(&pdev->dev, "failed to get irq resource: %d\n",
|
dev_err(&pdev->dev, "failed to get irq resource: %d\n",
|
||||||
ret);
|
ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
saif->dev = &pdev->dev;
|
saif->dev = &pdev->dev;
|
||||||
ret = devm_request_irq(&pdev->dev, saif->irq, mxs_saif_irq, 0,
|
ret = devm_request_irq(&pdev->dev, irq, mxs_saif_irq, 0,
|
||||||
dev_name(&pdev->dev), saif);
|
dev_name(&pdev->dev), saif);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "failed to request irq\n");
|
dev_err(&pdev->dev, "failed to request irq\n");
|
||||||
|
|
|
@ -116,7 +116,6 @@ struct mxs_saif {
|
||||||
unsigned int mclk;
|
unsigned int mclk;
|
||||||
unsigned int mclk_in_use;
|
unsigned int mclk_in_use;
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
int irq;
|
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
unsigned int master_id;
|
unsigned int master_id;
|
||||||
unsigned int cur_rate;
|
unsigned int cur_rate;
|
||||||
|
|
|
@ -306,11 +306,6 @@ static struct snd_pcm_ops nuc900_dma_ops = {
|
||||||
.mmap = nuc900_dma_mmap,
|
.mmap = nuc900_dma_mmap,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void nuc900_dma_free_dma_buffers(struct snd_pcm *pcm)
|
|
||||||
{
|
|
||||||
snd_pcm_lib_preallocate_free_for_all(pcm);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd)
|
static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd)
|
||||||
{
|
{
|
||||||
struct snd_card *card = rtd->card->snd_card;
|
struct snd_card *card = rtd->card->snd_card;
|
||||||
|
@ -330,7 +325,6 @@ static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd)
|
||||||
static struct snd_soc_platform_driver nuc900_soc_platform = {
|
static struct snd_soc_platform_driver nuc900_soc_platform = {
|
||||||
.ops = &nuc900_dma_ops,
|
.ops = &nuc900_dma_ops,
|
||||||
.pcm_new = nuc900_dma_new,
|
.pcm_new = nuc900_dma_new,
|
||||||
.pcm_free = nuc900_dma_free_dma_buffers,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int nuc900_soc_platform_probe(struct platform_device *pdev)
|
static int nuc900_soc_platform_probe(struct platform_device *pdev)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче