mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-24 09:13:20 -05:00
Merge remote-tracking branches 'asoc/topic/sta529', 'asoc/topic/sti-sas', 'asoc/topic/stm32', 'asoc/topic/sun4i' and 'asoc/topic/sun8i' into asoc-next
This commit is contained in:
commit
e8c768dad0
9 changed files with 262 additions and 155 deletions
|
@ -45,6 +45,12 @@ SAI subnodes Optional properties:
|
|||
This property sets SAI sub-block as slave of another SAI sub-block.
|
||||
Must contain the phandle and index of the sai sub-block providing
|
||||
the synchronization.
|
||||
- st,iec60958: support S/PDIF IEC6958 protocol for playback
|
||||
IEC60958 protocol is not available for capture.
|
||||
By default, custom protocol is assumed, meaning that protocol is
|
||||
configured according to protocol defined in related DAI link node,
|
||||
such as i2s, left justified, right justified, dsp and pdm protocols.
|
||||
Note: ac97 protocol is not supported by SAI driver
|
||||
|
||||
The device node should contain one 'port' child node with one child 'endpoint'
|
||||
node, according to the bindings defined in Documentation/devicetree/bindings/
|
||||
|
|
|
@ -151,28 +151,28 @@ static const struct snd_kcontrol_new sta529_snd_controls[] = {
|
|||
SOC_ENUM("PWM Select", pwm_src),
|
||||
};
|
||||
|
||||
static int sta529_set_bias_level(struct snd_soc_codec *codec, enum
|
||||
static int sta529_set_bias_level(struct snd_soc_component *component, enum
|
||||
snd_soc_bias_level level)
|
||||
{
|
||||
struct sta529 *sta529 = snd_soc_codec_get_drvdata(codec);
|
||||
struct sta529 *sta529 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
switch (level) {
|
||||
case SND_SOC_BIAS_ON:
|
||||
case SND_SOC_BIAS_PREPARE:
|
||||
snd_soc_update_bits(codec, STA529_FFXCFG0, POWER_CNTLMSAK,
|
||||
snd_soc_component_update_bits(component, STA529_FFXCFG0, POWER_CNTLMSAK,
|
||||
POWER_UP);
|
||||
snd_soc_update_bits(codec, STA529_MISC, FFX_CLK_MSK,
|
||||
snd_soc_component_update_bits(component, STA529_MISC, FFX_CLK_MSK,
|
||||
FFX_CLK_ENB);
|
||||
break;
|
||||
case SND_SOC_BIAS_STANDBY:
|
||||
if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF)
|
||||
if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
|
||||
regcache_sync(sta529->regmap);
|
||||
snd_soc_update_bits(codec, STA529_FFXCFG0,
|
||||
snd_soc_component_update_bits(component, STA529_FFXCFG0,
|
||||
POWER_CNTLMSAK, POWER_STDBY);
|
||||
/* Making FFX output to zero */
|
||||
snd_soc_update_bits(codec, STA529_FFXCFG0, FFX_MASK,
|
||||
snd_soc_component_update_bits(component, STA529_FFXCFG0, FFX_MASK,
|
||||
FFX_OFF);
|
||||
snd_soc_update_bits(codec, STA529_MISC, FFX_CLK_MSK,
|
||||
snd_soc_component_update_bits(component, STA529_MISC, FFX_CLK_MSK,
|
||||
FFX_CLK_DIS);
|
||||
break;
|
||||
case SND_SOC_BIAS_OFF:
|
||||
|
@ -187,7 +187,7 @@ static int sta529_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
struct snd_soc_component *component = dai->component;
|
||||
int pdata, play_freq_val, record_freq_val;
|
||||
int bclk_to_fs_ratio;
|
||||
|
||||
|
@ -205,7 +205,7 @@ static int sta529_hw_params(struct snd_pcm_substream *substream,
|
|||
bclk_to_fs_ratio = 2;
|
||||
break;
|
||||
default:
|
||||
dev_err(codec->dev, "Unsupported format\n");
|
||||
dev_err(component->dev, "Unsupported format\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -228,23 +228,23 @@ static int sta529_hw_params(struct snd_pcm_substream *substream,
|
|||
record_freq_val = 0;
|
||||
break;
|
||||
default:
|
||||
dev_err(codec->dev, "Unsupported rate\n");
|
||||
dev_err(component->dev, "Unsupported rate\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
snd_soc_update_bits(codec, STA529_S2PCFG1, PDATA_LEN_MSK,
|
||||
snd_soc_component_update_bits(component, STA529_S2PCFG1, PDATA_LEN_MSK,
|
||||
pdata << 6);
|
||||
snd_soc_update_bits(codec, STA529_S2PCFG1, BCLK_TO_FS_MSK,
|
||||
snd_soc_component_update_bits(component, STA529_S2PCFG1, BCLK_TO_FS_MSK,
|
||||
bclk_to_fs_ratio << 4);
|
||||
snd_soc_update_bits(codec, STA529_MISC, PLAY_FREQ_RANGE_MSK,
|
||||
snd_soc_component_update_bits(component, STA529_MISC, PLAY_FREQ_RANGE_MSK,
|
||||
play_freq_val << 4);
|
||||
} else {
|
||||
snd_soc_update_bits(codec, STA529_P2SCFG1, PDATA_LEN_MSK,
|
||||
snd_soc_component_update_bits(component, STA529_P2SCFG1, PDATA_LEN_MSK,
|
||||
pdata << 6);
|
||||
snd_soc_update_bits(codec, STA529_P2SCFG1, BCLK_TO_FS_MSK,
|
||||
snd_soc_component_update_bits(component, STA529_P2SCFG1, BCLK_TO_FS_MSK,
|
||||
bclk_to_fs_ratio << 4);
|
||||
snd_soc_update_bits(codec, STA529_MISC, CAP_FREQ_RANGE_MSK,
|
||||
snd_soc_component_update_bits(component, STA529_MISC, CAP_FREQ_RANGE_MSK,
|
||||
record_freq_val << 2);
|
||||
}
|
||||
|
||||
|
@ -258,14 +258,14 @@ static int sta529_mute(struct snd_soc_dai *dai, int mute)
|
|||
if (mute)
|
||||
val |= CODEC_MUTE_VAL;
|
||||
|
||||
snd_soc_update_bits(dai->codec, STA529_FFXCFG0, AUDIO_MUTE_MSK, val);
|
||||
snd_soc_component_update_bits(dai->component, STA529_FFXCFG0, AUDIO_MUTE_MSK, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sta529_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
|
||||
{
|
||||
struct snd_soc_codec *codec = codec_dai->codec;
|
||||
struct snd_soc_component *component = codec_dai->component;
|
||||
u8 mode = 0;
|
||||
|
||||
/* interface format */
|
||||
|
@ -283,7 +283,7 @@ static int sta529_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
snd_soc_update_bits(codec, STA529_S2PCFG0, DATA_FORMAT_MSK, mode);
|
||||
snd_soc_component_update_bits(component, STA529_S2PCFG0, DATA_FORMAT_MSK, mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -313,14 +313,15 @@ static struct snd_soc_dai_driver sta529_dai = {
|
|||
.ops = &sta529_dai_ops,
|
||||
};
|
||||
|
||||
static const struct snd_soc_codec_driver sta529_codec_driver = {
|
||||
.set_bias_level = sta529_set_bias_level,
|
||||
.suspend_bias_off = true,
|
||||
|
||||
.component_driver = {
|
||||
.controls = sta529_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(sta529_snd_controls),
|
||||
},
|
||||
static const struct snd_soc_component_driver sta529_component_driver = {
|
||||
.set_bias_level = sta529_set_bias_level,
|
||||
.controls = sta529_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(sta529_snd_controls),
|
||||
.suspend_bias_off = 1,
|
||||
.idle_bias_on = 1,
|
||||
.use_pmdown_time = 1,
|
||||
.endianness = 1,
|
||||
.non_legacy_dai_naming = 1,
|
||||
};
|
||||
|
||||
static const struct regmap_config sta529_regmap = {
|
||||
|
@ -354,21 +355,14 @@ static int sta529_i2c_probe(struct i2c_client *i2c,
|
|||
|
||||
i2c_set_clientdata(i2c, sta529);
|
||||
|
||||
ret = snd_soc_register_codec(&i2c->dev,
|
||||
&sta529_codec_driver, &sta529_dai, 1);
|
||||
ret = devm_snd_soc_register_component(&i2c->dev,
|
||||
&sta529_component_driver, &sta529_dai, 1);
|
||||
if (ret != 0)
|
||||
dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sta529_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
snd_soc_unregister_codec(&client->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id sta529_i2c_id[] = {
|
||||
{ "sta529", 0 },
|
||||
{ }
|
||||
|
@ -387,7 +381,6 @@ static struct i2c_driver sta529_i2c_driver = {
|
|||
.of_match_table = sta529_of_match,
|
||||
},
|
||||
.probe = sta529_i2c_probe,
|
||||
.remove = sta529_i2c_remove,
|
||||
.id_table = sta529_i2c_id,
|
||||
};
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ static int sti_sas_write_reg(void *context, unsigned int reg,
|
|||
return status;
|
||||
}
|
||||
|
||||
static int sti_sas_init_sas_registers(struct snd_soc_codec *codec,
|
||||
static int sti_sas_init_sas_registers(struct snd_soc_component *component,
|
||||
struct sti_sas_data *data)
|
||||
{
|
||||
int ret;
|
||||
|
@ -116,35 +116,35 @@ static int sti_sas_init_sas_registers(struct snd_soc_codec *codec,
|
|||
*/
|
||||
|
||||
/* Initialise bi-phase formatter to disabled */
|
||||
ret = snd_soc_update_bits(codec, STIH407_AUDIO_GLUE_CTRL,
|
||||
ret = snd_soc_component_update_bits(component, STIH407_AUDIO_GLUE_CTRL,
|
||||
SPDIF_BIPHASE_ENABLE_MASK, 0);
|
||||
|
||||
if (!ret)
|
||||
/* Initialise bi-phase formatter idle value to 0 */
|
||||
ret = snd_soc_update_bits(codec, STIH407_AUDIO_GLUE_CTRL,
|
||||
ret = snd_soc_component_update_bits(component, STIH407_AUDIO_GLUE_CTRL,
|
||||
SPDIF_BIPHASE_IDLE_MASK, 0);
|
||||
if (ret < 0) {
|
||||
dev_err(codec->dev, "Failed to update SPDIF registers\n");
|
||||
dev_err(component->dev, "Failed to update SPDIF registers\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Init DAC configuration */
|
||||
/* init configuration */
|
||||
ret = snd_soc_update_bits(codec, STIH407_AUDIO_DAC_CTRL,
|
||||
ret = snd_soc_component_update_bits(component, STIH407_AUDIO_DAC_CTRL,
|
||||
STIH407_DAC_STANDBY_MASK,
|
||||
STIH407_DAC_STANDBY_MASK);
|
||||
|
||||
if (!ret)
|
||||
ret = snd_soc_update_bits(codec, STIH407_AUDIO_DAC_CTRL,
|
||||
ret = snd_soc_component_update_bits(component, STIH407_AUDIO_DAC_CTRL,
|
||||
STIH407_DAC_STANDBY_ANA_MASK,
|
||||
STIH407_DAC_STANDBY_ANA_MASK);
|
||||
if (!ret)
|
||||
ret = snd_soc_update_bits(codec, STIH407_AUDIO_DAC_CTRL,
|
||||
ret = snd_soc_component_update_bits(component, STIH407_AUDIO_DAC_CTRL,
|
||||
STIH407_DAC_SOFTMUTE_MASK,
|
||||
STIH407_DAC_SOFTMUTE_MASK);
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(codec->dev, "Failed to update DAC registers\n");
|
||||
dev_err(component->dev, "Failed to update DAC registers\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -158,7 +158,7 @@ static int sti_sas_dac_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
|||
{
|
||||
/* Sanity check only */
|
||||
if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
|
||||
dev_err(dai->codec->dev,
|
||||
dev_err(dai->component->dev,
|
||||
"%s: ERROR: Unsupporter master mask 0x%x\n",
|
||||
__func__, fmt & SND_SOC_DAIFMT_MASTER_MASK);
|
||||
return -EINVAL;
|
||||
|
@ -183,14 +183,14 @@ static const struct snd_soc_dapm_route stih407_sas_route[] = {
|
|||
|
||||
static int stih407_sas_dac_mute(struct snd_soc_dai *dai, int mute, int stream)
|
||||
{
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
struct snd_soc_component *component = dai->component;
|
||||
|
||||
if (mute) {
|
||||
return snd_soc_update_bits(codec, STIH407_AUDIO_DAC_CTRL,
|
||||
return snd_soc_component_update_bits(component, STIH407_AUDIO_DAC_CTRL,
|
||||
STIH407_DAC_SOFTMUTE_MASK,
|
||||
STIH407_DAC_SOFTMUTE_MASK);
|
||||
} else {
|
||||
return snd_soc_update_bits(codec, STIH407_AUDIO_DAC_CTRL,
|
||||
return snd_soc_component_update_bits(component, STIH407_AUDIO_DAC_CTRL,
|
||||
STIH407_DAC_SOFTMUTE_MASK,
|
||||
0);
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ static int sti_sas_spdif_set_fmt(struct snd_soc_dai *dai,
|
|||
unsigned int fmt)
|
||||
{
|
||||
if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
|
||||
dev_err(dai->codec->dev,
|
||||
dev_err(dai->component->dev,
|
||||
"%s: ERROR: Unsupporter master mask 0x%x\n",
|
||||
__func__, fmt & SND_SOC_DAIFMT_MASTER_MASK);
|
||||
return -EINVAL;
|
||||
|
@ -221,19 +221,19 @@ static int sti_sas_spdif_set_fmt(struct snd_soc_dai *dai,
|
|||
static int sti_sas_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
struct snd_soc_component *component = dai->component;
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
return snd_soc_update_bits(codec, STIH407_AUDIO_GLUE_CTRL,
|
||||
return snd_soc_component_update_bits(component, STIH407_AUDIO_GLUE_CTRL,
|
||||
SPDIF_BIPHASE_ENABLE_MASK,
|
||||
SPDIF_BIPHASE_ENABLE_MASK);
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
return snd_soc_update_bits(codec, STIH407_AUDIO_GLUE_CTRL,
|
||||
return snd_soc_component_update_bits(component, STIH407_AUDIO_GLUE_CTRL,
|
||||
SPDIF_BIPHASE_ENABLE_MASK,
|
||||
0);
|
||||
default:
|
||||
|
@ -260,8 +260,8 @@ static bool sti_sas_volatile_register(struct device *dev, unsigned int reg)
|
|||
static int sti_sas_set_sysclk(struct snd_soc_dai *dai, int clk_id,
|
||||
unsigned int freq, int dir)
|
||||
{
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
struct sti_sas_data *drvdata = dev_get_drvdata(codec->dev);
|
||||
struct snd_soc_component *component = dai->component;
|
||||
struct sti_sas_data *drvdata = dev_get_drvdata(component->dev);
|
||||
|
||||
if (dir == SND_SOC_CLOCK_OUT)
|
||||
return 0;
|
||||
|
@ -285,20 +285,20 @@ static int sti_sas_set_sysclk(struct snd_soc_dai *dai, int clk_id,
|
|||
static int sti_sas_prepare(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
struct sti_sas_data *drvdata = dev_get_drvdata(codec->dev);
|
||||
struct snd_soc_component *component = dai->component;
|
||||
struct sti_sas_data *drvdata = dev_get_drvdata(component->dev);
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
|
||||
switch (dai->id) {
|
||||
case STI_SAS_DAI_SPDIF_OUT:
|
||||
if ((drvdata->spdif.mclk / runtime->rate) != 128) {
|
||||
dev_err(codec->dev, "unexpected mclk-fs ratio\n");
|
||||
dev_err(component->dev, "unexpected mclk-fs ratio\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case STI_SAS_DAI_ANALOG_OUT:
|
||||
if ((drvdata->dac.mclk / runtime->rate) != 256) {
|
||||
dev_err(codec->dev, "unexpected mclk-fs ratio\n");
|
||||
dev_err(component->dev, "unexpected mclk-fs ratio\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
|
@ -375,29 +375,33 @@ static struct snd_soc_dai_driver sti_sas_dai[] = {
|
|||
};
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int sti_sas_resume(struct snd_soc_codec *codec)
|
||||
static int sti_sas_resume(struct snd_soc_component *component)
|
||||
{
|
||||
struct sti_sas_data *drvdata = dev_get_drvdata(codec->dev);
|
||||
struct sti_sas_data *drvdata = dev_get_drvdata(component->dev);
|
||||
|
||||
return sti_sas_init_sas_registers(codec, drvdata);
|
||||
return sti_sas_init_sas_registers(component, drvdata);
|
||||
}
|
||||
#else
|
||||
#define sti_sas_resume NULL
|
||||
#endif
|
||||
|
||||
static int sti_sas_codec_probe(struct snd_soc_codec *codec)
|
||||
static int sti_sas_component_probe(struct snd_soc_component *component)
|
||||
{
|
||||
struct sti_sas_data *drvdata = dev_get_drvdata(codec->dev);
|
||||
struct sti_sas_data *drvdata = dev_get_drvdata(component->dev);
|
||||
int ret;
|
||||
|
||||
ret = sti_sas_init_sas_registers(codec, drvdata);
|
||||
ret = sti_sas_init_sas_registers(component, drvdata);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct snd_soc_codec_driver sti_sas_driver = {
|
||||
.probe = sti_sas_codec_probe,
|
||||
.resume = sti_sas_resume,
|
||||
static struct snd_soc_component_driver sti_sas_driver = {
|
||||
.probe = sti_sas_component_probe,
|
||||
.resume = sti_sas_resume,
|
||||
.idle_bias_on = 1,
|
||||
.use_pmdown_time = 1,
|
||||
.endianness = 1,
|
||||
.non_legacy_dai_naming = 1,
|
||||
};
|
||||
|
||||
static const struct of_device_id sti_sas_dev_match[] = {
|
||||
|
@ -452,34 +456,26 @@ static int sti_sas_driver_probe(struct platform_device *pdev)
|
|||
sti_sas_dai[STI_SAS_DAI_ANALOG_OUT].ops = drvdata->dev_data->dac_ops;
|
||||
|
||||
/* Set dapms*/
|
||||
sti_sas_driver.component_driver.dapm_widgets = drvdata->dev_data->dapm_widgets;
|
||||
sti_sas_driver.component_driver.num_dapm_widgets = drvdata->dev_data->num_dapm_widgets;
|
||||
sti_sas_driver.dapm_widgets = drvdata->dev_data->dapm_widgets;
|
||||
sti_sas_driver.num_dapm_widgets = drvdata->dev_data->num_dapm_widgets;
|
||||
|
||||
sti_sas_driver.component_driver.dapm_routes = drvdata->dev_data->dapm_routes;
|
||||
sti_sas_driver.component_driver.num_dapm_routes = drvdata->dev_data->num_dapm_routes;
|
||||
sti_sas_driver.dapm_routes = drvdata->dev_data->dapm_routes;
|
||||
sti_sas_driver.num_dapm_routes = drvdata->dev_data->num_dapm_routes;
|
||||
|
||||
/* Store context */
|
||||
dev_set_drvdata(&pdev->dev, drvdata);
|
||||
|
||||
return snd_soc_register_codec(&pdev->dev, &sti_sas_driver,
|
||||
return devm_snd_soc_register_component(&pdev->dev, &sti_sas_driver,
|
||||
sti_sas_dai,
|
||||
ARRAY_SIZE(sti_sas_dai));
|
||||
}
|
||||
|
||||
static int sti_sas_driver_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_soc_unregister_codec(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver sti_sas_platform_driver = {
|
||||
.driver = {
|
||||
.name = "sti-sas-codec",
|
||||
.of_match_table = sti_sas_dev_match,
|
||||
},
|
||||
.probe = sti_sas_driver_probe,
|
||||
.remove = sti_sas_driver_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(sti_sas_platform_driver);
|
||||
|
|
|
@ -30,10 +30,12 @@
|
|||
|
||||
static const struct stm32_sai_conf stm32_sai_conf_f4 = {
|
||||
.version = SAI_STM32F4,
|
||||
.has_spdif = false,
|
||||
};
|
||||
|
||||
static const struct stm32_sai_conf stm32_sai_conf_h7 = {
|
||||
.version = SAI_STM32H7,
|
||||
.has_spdif = true,
|
||||
};
|
||||
|
||||
static const struct of_device_id stm32_sai_ids[] = {
|
||||
|
|
|
@ -248,9 +248,11 @@ enum stm32_sai_version {
|
|||
/**
|
||||
* struct stm32_sai_conf - SAI configuration
|
||||
* @version: SAI version
|
||||
* @has_spdif: SAI S/PDIF support flag
|
||||
*/
|
||||
struct stm32_sai_conf {
|
||||
int version;
|
||||
bool has_spdif;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <linux/of_platform.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <sound/asoundef.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
|
@ -30,6 +31,7 @@
|
|||
#include "stm32_sai.h"
|
||||
|
||||
#define SAI_FREE_PROTOCOL 0x0
|
||||
#define SAI_SPDIF_PROTOCOL 0x1
|
||||
|
||||
#define SAI_SLOT_SIZE_AUTO 0x0
|
||||
#define SAI_SLOT_SIZE_16 0x1
|
||||
|
@ -59,8 +61,13 @@
|
|||
#define SAI_SYNC_INTERNAL 0x1
|
||||
#define SAI_SYNC_EXTERNAL 0x2
|
||||
|
||||
#define STM_SAI_PROTOCOL_IS_SPDIF(ip) ((ip)->spdif)
|
||||
#define STM_SAI_HAS_SPDIF(x) ((x)->pdata->conf->has_spdif)
|
||||
#define STM_SAI_HAS_EXT_SYNC(x) (!STM_SAI_IS_F4(sai->pdata))
|
||||
|
||||
#define SAI_IEC60958_BLOCK_FRAMES 192
|
||||
#define SAI_IEC60958_STATUS_BYTES 24
|
||||
|
||||
/**
|
||||
* struct stm32_sai_sub_data - private data of SAI sub block (block A or B)
|
||||
* @pdev: device data pointer
|
||||
|
@ -78,6 +85,7 @@
|
|||
* @id: SAI sub block id corresponding to sub-block A or B
|
||||
* @dir: SAI block direction (playback or capture). set at init
|
||||
* @master: SAI block mode flag. (true=master, false=slave) set at init
|
||||
* @spdif: SAI S/PDIF iec60958 mode flag. set at init
|
||||
* @fmt: SAI block format. relevant only for custom protocols. set at init
|
||||
* @sync: SAI block synchronization mode. (none, internal or external)
|
||||
* @synco: SAI block ext sync source (provider setting). (none, sub-block A/B)
|
||||
|
@ -87,6 +95,8 @@
|
|||
* @slot_width: rx or tx slot width in bits
|
||||
* @slot_mask: rx or tx active slots mask. set at init or at runtime
|
||||
* @data_size: PCM data width. corresponds to PCM substream width.
|
||||
* @spdif_frm_cnt: S/PDIF playback frame counter
|
||||
* @spdif_status_bits: S/PDIF status bits
|
||||
*/
|
||||
struct stm32_sai_sub_data {
|
||||
struct platform_device *pdev;
|
||||
|
@ -104,6 +114,7 @@ struct stm32_sai_sub_data {
|
|||
unsigned int id;
|
||||
int dir;
|
||||
bool master;
|
||||
bool spdif;
|
||||
int fmt;
|
||||
int sync;
|
||||
int synco;
|
||||
|
@ -113,6 +124,8 @@ struct stm32_sai_sub_data {
|
|||
int slot_width;
|
||||
int slot_mask;
|
||||
int data_size;
|
||||
unsigned int spdif_frm_cnt;
|
||||
unsigned char spdif_status_bits[SAI_IEC60958_STATUS_BYTES];
|
||||
};
|
||||
|
||||
enum stm32_sai_fifo_th {
|
||||
|
@ -171,6 +184,10 @@ static bool stm32_sai_sub_writeable_reg(struct device *dev, unsigned int reg)
|
|||
}
|
||||
}
|
||||
|
||||
static const unsigned char default_status_bits[SAI_IEC60958_STATUS_BYTES] = {
|
||||
0, 0, 0, IEC958_AES3_CON_FS_48000,
|
||||
};
|
||||
|
||||
static const struct regmap_config stm32_sai_sub_regmap_config_f4 = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
|
@ -277,6 +294,11 @@ static int stm32_sai_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask,
|
|||
struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
|
||||
int slotr, slotr_mask, slot_size;
|
||||
|
||||
if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
|
||||
dev_warn(cpu_dai->dev, "Slot setting relevant only for TDM\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev_dbg(cpu_dai->dev, "Masks tx/rx:%#x/%#x, slots:%d, width:%d\n",
|
||||
tx_mask, rx_mask, slots, slot_width);
|
||||
|
||||
|
@ -326,8 +348,17 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
|
|||
|
||||
dev_dbg(cpu_dai->dev, "fmt %x\n", fmt);
|
||||
|
||||
cr1_mask = SAI_XCR1_PRTCFG_MASK;
|
||||
cr1 = SAI_XCR1_PRTCFG_SET(SAI_FREE_PROTOCOL);
|
||||
/* Do not generate master by default */
|
||||
cr1 = SAI_XCR1_NODIV;
|
||||
cr1_mask = SAI_XCR1_NODIV;
|
||||
|
||||
cr1_mask |= SAI_XCR1_PRTCFG_MASK;
|
||||
if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
|
||||
cr1 |= SAI_XCR1_PRTCFG_SET(SAI_SPDIF_PROTOCOL);
|
||||
goto conf_update;
|
||||
}
|
||||
|
||||
cr1 |= SAI_XCR1_PRTCFG_SET(SAI_FREE_PROTOCOL);
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
/* SCK active high for all protocols */
|
||||
|
@ -409,10 +440,7 @@ static int stm32_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
|
|||
|
||||
cr1_mask |= SAI_XCR1_SLAVE;
|
||||
|
||||
/* do not generate master by default */
|
||||
cr1 |= SAI_XCR1_NODIV;
|
||||
cr1_mask |= SAI_XCR1_NODIV;
|
||||
|
||||
conf_update:
|
||||
ret = regmap_update_bits(sai->regmap, STM_SAI_CR1_REGX, cr1_mask, cr1);
|
||||
if (ret < 0) {
|
||||
dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
|
||||
|
@ -478,6 +506,12 @@ static int stm32_sai_set_config(struct snd_soc_dai *cpu_dai,
|
|||
SAI_XCR2_FFLUSH |
|
||||
SAI_XCR2_FTH_SET(STM_SAI_FIFO_TH_HALF));
|
||||
|
||||
/* DS bits in CR1 not set for SPDIF (size forced to 24 bits).*/
|
||||
if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
|
||||
sai->spdif_frm_cnt = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Mode, data format and channel config */
|
||||
cr1_mask = SAI_XCR1_DS_MASK;
|
||||
switch (params_format(params)) {
|
||||
|
@ -592,13 +626,14 @@ static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai,
|
|||
int cr1, mask, div = 0;
|
||||
int sai_clk_rate, mclk_ratio, den, ret;
|
||||
int version = sai->pdata->conf->version;
|
||||
unsigned int rate = params_rate(params);
|
||||
|
||||
if (!sai->mclk_rate) {
|
||||
dev_err(cpu_dai->dev, "Mclk rate is null\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!(params_rate(params) % 11025))
|
||||
if (!(rate % 11025))
|
||||
clk_set_parent(sai->sai_ck, sai->pdata->clk_x11k);
|
||||
else
|
||||
clk_set_parent(sai->sai_ck, sai->pdata->clk_x8k);
|
||||
|
@ -623,24 +658,28 @@ static int stm32_sai_configure_clock(struct snd_soc_dai *cpu_dai,
|
|||
* MCKDIV = sai_ck / (frl x ws) (NOMCK=1)
|
||||
* Note: NOMCK/NODIV correspond to same bit.
|
||||
*/
|
||||
if (sai->mclk_rate) {
|
||||
mclk_ratio = sai->mclk_rate / params_rate(params);
|
||||
if (mclk_ratio != 256) {
|
||||
if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
|
||||
div = DIV_ROUND_CLOSEST(sai_clk_rate,
|
||||
(params_rate(params) * 128));
|
||||
} else {
|
||||
if (sai->mclk_rate) {
|
||||
mclk_ratio = sai->mclk_rate / rate;
|
||||
if (mclk_ratio == 512) {
|
||||
mask = SAI_XCR1_OSR;
|
||||
cr1 = SAI_XCR1_OSR;
|
||||
} else {
|
||||
} else if (mclk_ratio != 256) {
|
||||
dev_err(cpu_dai->dev,
|
||||
"Wrong mclk ratio %d\n",
|
||||
mclk_ratio);
|
||||
return -EINVAL;
|
||||
}
|
||||
div = DIV_ROUND_CLOSEST(sai_clk_rate,
|
||||
sai->mclk_rate);
|
||||
} else {
|
||||
/* mclk-fs not set, master clock not active */
|
||||
den = sai->fs_length * params_rate(params);
|
||||
div = DIV_ROUND_CLOSEST(sai_clk_rate, den);
|
||||
}
|
||||
div = DIV_ROUND_CLOSEST(sai_clk_rate, sai->mclk_rate);
|
||||
} else {
|
||||
/* mclk-fs not set, master clock not active. NOMCK=1 */
|
||||
den = sai->fs_length * params_rate(params);
|
||||
div = DIV_ROUND_CLOSEST(sai_clk_rate, den);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -670,10 +709,12 @@ static int stm32_sai_hw_params(struct snd_pcm_substream *substream,
|
|||
|
||||
sai->data_size = params_width(params);
|
||||
|
||||
ret = stm32_sai_set_slots(cpu_dai);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
stm32_sai_set_frame(cpu_dai);
|
||||
if (!STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
|
||||
ret = stm32_sai_set_slots(cpu_dai);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
stm32_sai_set_frame(cpu_dai);
|
||||
}
|
||||
|
||||
ret = stm32_sai_set_config(cpu_dai, substream, params);
|
||||
if (ret)
|
||||
|
@ -723,6 +764,9 @@ static int stm32_sai_trigger(struct snd_pcm_substream *substream, int cmd,
|
|||
(unsigned int)~SAI_XCR1_DMAEN);
|
||||
if (ret < 0)
|
||||
dev_err(cpu_dai->dev, "Failed to update CR1 register\n");
|
||||
|
||||
if (STM_SAI_PROTOCOL_IS_SPDIF(sai))
|
||||
sai->spdif_frm_cnt = 0;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
@ -776,6 +820,10 @@ static int stm32_sai_dai_probe(struct snd_soc_dai *cpu_dai)
|
|||
sai->synco, sai->synci);
|
||||
}
|
||||
|
||||
if (STM_SAI_PROTOCOL_IS_SPDIF(sai))
|
||||
memcpy(sai->spdif_status_bits, default_status_bits,
|
||||
sizeof(default_status_bits));
|
||||
|
||||
cr1_mask |= SAI_XCR1_SYNCEN_MASK;
|
||||
cr1 |= SAI_XCR1_SYNCEN_SET(sai->sync);
|
||||
|
||||
|
@ -792,6 +840,42 @@ static const struct snd_soc_dai_ops stm32_sai_pcm_dai_ops = {
|
|||
.shutdown = stm32_sai_shutdown,
|
||||
};
|
||||
|
||||
static int stm32_sai_pcm_process_spdif(struct snd_pcm_substream *substream,
|
||||
int channel, unsigned long hwoff,
|
||||
void *buf, unsigned long bytes)
|
||||
{
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||
struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev);
|
||||
int *ptr = (int *)(runtime->dma_area + hwoff +
|
||||
channel * (runtime->dma_bytes / runtime->channels));
|
||||
ssize_t cnt = bytes_to_samples(runtime, bytes);
|
||||
unsigned int frm_cnt = sai->spdif_frm_cnt;
|
||||
unsigned int byte;
|
||||
unsigned int mask;
|
||||
|
||||
do {
|
||||
*ptr = ((*ptr >> 8) & 0x00ffffff);
|
||||
|
||||
/* Set channel status bit */
|
||||
byte = frm_cnt >> 3;
|
||||
mask = 1 << (frm_cnt - (byte << 3));
|
||||
if (sai->spdif_status_bits[byte] & mask)
|
||||
*ptr |= 0x04000000;
|
||||
ptr++;
|
||||
|
||||
if (!(cnt % 2))
|
||||
frm_cnt++;
|
||||
|
||||
if (frm_cnt == SAI_IEC60958_BLOCK_FRAMES)
|
||||
frm_cnt = 0;
|
||||
} while (--cnt);
|
||||
sai->spdif_frm_cnt = frm_cnt;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_pcm_hardware stm32_sai_pcm_hw = {
|
||||
.info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP,
|
||||
.buffer_bytes_max = 8 * PAGE_SIZE,
|
||||
|
@ -842,8 +926,14 @@ static struct snd_soc_dai_driver stm32_sai_capture_dai[] = {
|
|||
};
|
||||
|
||||
static const struct snd_dmaengine_pcm_config stm32_sai_pcm_config = {
|
||||
.pcm_hardware = &stm32_sai_pcm_hw,
|
||||
.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
|
||||
.pcm_hardware = &stm32_sai_pcm_hw,
|
||||
.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
|
||||
};
|
||||
|
||||
static const struct snd_dmaengine_pcm_config stm32_sai_pcm_config_spdif = {
|
||||
.pcm_hardware = &stm32_sai_pcm_hw,
|
||||
.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
|
||||
.process = stm32_sai_pcm_process_spdif,
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver stm32_component = {
|
||||
|
@ -900,6 +990,18 @@ static int stm32_sai_sub_parse_of(struct platform_device *pdev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Get spdif iec60958 property */
|
||||
sai->spdif = false;
|
||||
if (of_get_property(np, "st,iec60958", NULL)) {
|
||||
if (!STM_SAI_HAS_SPDIF(sai) ||
|
||||
sai->dir == SNDRV_PCM_STREAM_CAPTURE) {
|
||||
dev_err(&pdev->dev, "S/PDIF IEC60958 not supported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
sai->spdif = true;
|
||||
sai->master = true;
|
||||
}
|
||||
|
||||
/* Get synchronization property */
|
||||
args.np = NULL;
|
||||
ret = of_parse_phandle_with_fixed_args(np, "st,sync", 1, 0, &args);
|
||||
|
@ -999,6 +1101,7 @@ static int stm32_sai_sub_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct stm32_sai_sub_data *sai;
|
||||
const struct of_device_id *of_id;
|
||||
const struct snd_dmaengine_pcm_config *conf = &stm32_sai_pcm_config;
|
||||
int ret;
|
||||
|
||||
sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
|
||||
|
@ -1039,8 +1142,10 @@ static int stm32_sai_sub_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
|
||||
&stm32_sai_pcm_config, 0);
|
||||
if (STM_SAI_PROTOCOL_IS_SPDIF(sai))
|
||||
conf = &stm32_sai_pcm_config_spdif;
|
||||
|
||||
ret = devm_snd_dmaengine_pcm_register(&pdev->dev, conf, 0);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Could not register pcm dma\n");
|
||||
return ret;
|
||||
|
|
|
@ -819,7 +819,6 @@ static const struct snd_soc_dai_ops stm32_spdifrx_pcm_dai_ops = {
|
|||
|
||||
static struct snd_soc_dai_driver stm32_spdifrx_dai[] = {
|
||||
{
|
||||
.name = "spdifrx-capture-cpu-dai",
|
||||
.probe = stm32_spdifrx_dai_probe,
|
||||
.capture = {
|
||||
.stream_name = "CPU-Capture",
|
||||
|
@ -858,8 +857,8 @@ static const struct of_device_id stm32_spdifrx_ids[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
static int stm_spdifrx_parse_of(struct platform_device *pdev,
|
||||
struct stm32_spdifrx_data *spdifrx)
|
||||
static int stm32_spdifrx_parse_of(struct platform_device *pdev,
|
||||
struct stm32_spdifrx_data *spdifrx)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
const struct of_device_id *of_id;
|
||||
|
@ -914,7 +913,7 @@ static int stm32_spdifrx_probe(struct platform_device *pdev)
|
|||
|
||||
platform_set_drvdata(pdev, spdifrx);
|
||||
|
||||
ret = stm_spdifrx_parse_of(pdev, spdifrx);
|
||||
ret = stm32_spdifrx_parse_of(pdev, spdifrx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -792,15 +792,17 @@ static const struct snd_soc_dapm_route sun4i_codec_codec_dapm_routes[] = {
|
|||
{ "Mic1", NULL, "VMIC" },
|
||||
};
|
||||
|
||||
static const struct snd_soc_codec_driver sun4i_codec_codec = {
|
||||
.component_driver = {
|
||||
.controls = sun4i_codec_controls,
|
||||
.num_controls = ARRAY_SIZE(sun4i_codec_controls),
|
||||
.dapm_widgets = sun4i_codec_codec_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
|
||||
.dapm_routes = sun4i_codec_codec_dapm_routes,
|
||||
.num_dapm_routes = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
|
||||
},
|
||||
static const struct snd_soc_component_driver sun4i_codec_codec = {
|
||||
.controls = sun4i_codec_controls,
|
||||
.num_controls = ARRAY_SIZE(sun4i_codec_controls),
|
||||
.dapm_widgets = sun4i_codec_codec_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
|
||||
.dapm_routes = sun4i_codec_codec_dapm_routes,
|
||||
.num_dapm_routes = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
|
||||
.idle_bias_on = 1,
|
||||
.use_pmdown_time = 1,
|
||||
.endianness = 1,
|
||||
.non_legacy_dai_naming = 1,
|
||||
};
|
||||
|
||||
/*** sun6i Codec ***/
|
||||
|
@ -1098,15 +1100,17 @@ static const struct snd_soc_dapm_route sun6i_codec_codec_dapm_routes[] = {
|
|||
{ "Right ADC", NULL, "Right ADC Mixer" },
|
||||
};
|
||||
|
||||
static const struct snd_soc_codec_driver sun6i_codec_codec = {
|
||||
.component_driver = {
|
||||
.controls = sun6i_codec_codec_widgets,
|
||||
.num_controls = ARRAY_SIZE(sun6i_codec_codec_widgets),
|
||||
.dapm_widgets = sun6i_codec_codec_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(sun6i_codec_codec_dapm_widgets),
|
||||
.dapm_routes = sun6i_codec_codec_dapm_routes,
|
||||
.num_dapm_routes = ARRAY_SIZE(sun6i_codec_codec_dapm_routes),
|
||||
},
|
||||
static const struct snd_soc_component_driver sun6i_codec_codec = {
|
||||
.controls = sun6i_codec_codec_widgets,
|
||||
.num_controls = ARRAY_SIZE(sun6i_codec_codec_widgets),
|
||||
.dapm_widgets = sun6i_codec_codec_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(sun6i_codec_codec_dapm_widgets),
|
||||
.dapm_routes = sun6i_codec_codec_dapm_routes,
|
||||
.num_dapm_routes = ARRAY_SIZE(sun6i_codec_codec_dapm_routes),
|
||||
.idle_bias_on = 1,
|
||||
.use_pmdown_time = 1,
|
||||
.endianness = 1,
|
||||
.non_legacy_dai_naming = 1,
|
||||
};
|
||||
|
||||
/* sun8i A23 codec */
|
||||
|
@ -1126,13 +1130,15 @@ static const struct snd_soc_dapm_widget sun8i_a23_codec_codec_widgets[] = {
|
|||
|
||||
};
|
||||
|
||||
static const struct snd_soc_codec_driver sun8i_a23_codec_codec = {
|
||||
.component_driver = {
|
||||
.controls = sun8i_a23_codec_codec_controls,
|
||||
.num_controls = ARRAY_SIZE(sun8i_a23_codec_codec_controls),
|
||||
.dapm_widgets = sun8i_a23_codec_codec_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(sun8i_a23_codec_codec_widgets),
|
||||
},
|
||||
static const struct snd_soc_component_driver sun8i_a23_codec_codec = {
|
||||
.controls = sun8i_a23_codec_codec_controls,
|
||||
.num_controls = ARRAY_SIZE(sun8i_a23_codec_codec_controls),
|
||||
.dapm_widgets = sun8i_a23_codec_codec_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(sun8i_a23_codec_codec_widgets),
|
||||
.idle_bias_on = 1,
|
||||
.use_pmdown_time = 1,
|
||||
.endianness = 1,
|
||||
.non_legacy_dai_naming = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver sun4i_codec_component = {
|
||||
|
@ -1450,7 +1456,7 @@ static const struct regmap_config sun8i_v3s_codec_regmap_config = {
|
|||
|
||||
struct sun4i_codec_quirks {
|
||||
const struct regmap_config *regmap_config;
|
||||
const struct snd_soc_codec_driver *codec;
|
||||
const struct snd_soc_component_driver *codec;
|
||||
struct snd_soc_card * (*create_card)(struct device *dev);
|
||||
struct reg_field reg_adc_fifoc; /* used for regmap_field */
|
||||
unsigned int reg_dac_txdata; /* TX FIFO offset for DMA config */
|
||||
|
@ -1657,7 +1663,7 @@ static int sun4i_codec_probe(struct platform_device *pdev)
|
|||
scodec->capture_dma_data.maxburst = 8;
|
||||
scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
||||
|
||||
ret = snd_soc_register_codec(&pdev->dev, quirks->codec,
|
||||
ret = devm_snd_soc_register_component(&pdev->dev, quirks->codec,
|
||||
&sun4i_codec_dai, 1);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to register our codec\n");
|
||||
|
@ -1669,20 +1675,20 @@ static int sun4i_codec_probe(struct platform_device *pdev)
|
|||
&dummy_cpu_dai, 1);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to register our DAI\n");
|
||||
goto err_unregister_codec;
|
||||
goto err_assert_reset;
|
||||
}
|
||||
|
||||
ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to register against DMAEngine\n");
|
||||
goto err_unregister_codec;
|
||||
goto err_assert_reset;
|
||||
}
|
||||
|
||||
card = quirks->create_card(&pdev->dev);
|
||||
if (IS_ERR(card)) {
|
||||
ret = PTR_ERR(card);
|
||||
dev_err(&pdev->dev, "Failed to create our card\n");
|
||||
goto err_unregister_codec;
|
||||
goto err_assert_reset;
|
||||
}
|
||||
|
||||
snd_soc_card_set_drvdata(card, scodec);
|
||||
|
@ -1690,13 +1696,11 @@ static int sun4i_codec_probe(struct platform_device *pdev)
|
|||
ret = snd_soc_register_card(card);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to register our card\n");
|
||||
goto err_unregister_codec;
|
||||
goto err_assert_reset;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_unregister_codec:
|
||||
snd_soc_unregister_codec(&pdev->dev);
|
||||
err_assert_reset:
|
||||
if (scodec->rst)
|
||||
reset_control_assert(scodec->rst);
|
||||
|
@ -1711,7 +1715,6 @@ static int sun4i_codec_remove(struct platform_device *pdev)
|
|||
struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
|
||||
|
||||
snd_soc_unregister_card(card);
|
||||
snd_soc_unregister_codec(&pdev->dev);
|
||||
if (scodec->rst)
|
||||
reset_control_assert(scodec->rst);
|
||||
clk_disable_unprepare(scodec->clk_apb);
|
||||
|
|
|
@ -184,7 +184,7 @@ static int sun8i_codec_get_hw_rate(struct snd_pcm_hw_params *params)
|
|||
|
||||
static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
||||
{
|
||||
struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
|
||||
struct sun8i_codec *scodec = snd_soc_component_get_drvdata(dai->component);
|
||||
u32 value;
|
||||
|
||||
/* clock masters */
|
||||
|
@ -304,7 +304,7 @@ static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec);
|
||||
struct sun8i_codec *scodec = snd_soc_component_get_drvdata(dai->component);
|
||||
int sample_rate;
|
||||
u8 bclk_div;
|
||||
|
||||
|
@ -500,13 +500,15 @@ static struct snd_soc_dai_driver sun8i_codec_dai = {
|
|||
.ops = &sun8i_codec_dai_ops,
|
||||
};
|
||||
|
||||
static const struct snd_soc_codec_driver sun8i_soc_codec = {
|
||||
.component_driver = {
|
||||
.dapm_widgets = sun8i_codec_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(sun8i_codec_dapm_widgets),
|
||||
.dapm_routes = sun8i_codec_dapm_routes,
|
||||
.num_dapm_routes = ARRAY_SIZE(sun8i_codec_dapm_routes),
|
||||
},
|
||||
static const struct snd_soc_component_driver sun8i_soc_component = {
|
||||
.dapm_widgets = sun8i_codec_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(sun8i_codec_dapm_widgets),
|
||||
.dapm_routes = sun8i_codec_dapm_routes,
|
||||
.num_dapm_routes = ARRAY_SIZE(sun8i_codec_dapm_routes),
|
||||
.idle_bias_on = 1,
|
||||
.use_pmdown_time = 1,
|
||||
.endianness = 1,
|
||||
.non_legacy_dai_naming = 1,
|
||||
};
|
||||
|
||||
static const struct regmap_config sun8i_codec_regmap_config = {
|
||||
|
@ -566,7 +568,7 @@ static int sun8i_codec_probe(struct platform_device *pdev)
|
|||
goto err_pm_disable;
|
||||
}
|
||||
|
||||
ret = snd_soc_register_codec(&pdev->dev, &sun8i_soc_codec,
|
||||
ret = devm_snd_soc_register_component(&pdev->dev, &sun8i_soc_component,
|
||||
&sun8i_codec_dai, 1);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to register codec\n");
|
||||
|
@ -594,7 +596,6 @@ static int sun8i_codec_remove(struct platform_device *pdev)
|
|||
if (!pm_runtime_status_suspended(&pdev->dev))
|
||||
sun8i_codec_runtime_suspend(&pdev->dev);
|
||||
|
||||
snd_soc_unregister_codec(&pdev->dev);
|
||||
clk_disable_unprepare(scodec->clk_module);
|
||||
clk_disable_unprepare(scodec->clk_bus);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue