Commit 0cf4610b authored by Jerome Brunet's avatar Jerome Brunet Committed by Mark Brown

ASoC: hdmi-codec: remove ops dependency on the dai id

The dependency on the dai_id can be removed by setting different ops
for the i2s and spdif dai and storing the dai format information in
each dai structure. It simplies the code a bit.
Signed-off-by: default avatarJerome Brunet <jbrunet@baylibre.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 1de005d4
...@@ -278,7 +278,6 @@ static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = { ...@@ -278,7 +278,6 @@ static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = {
struct hdmi_codec_priv { struct hdmi_codec_priv {
struct hdmi_codec_pdata hcd; struct hdmi_codec_pdata hcd;
struct hdmi_codec_daifmt daifmt[2];
uint8_t eld[MAX_ELD_BYTES]; uint8_t eld[MAX_ELD_BYTES];
struct snd_pcm_chmap *chmap_info; struct snd_pcm_chmap *chmap_info;
unsigned int chmap_idx; unsigned int chmap_idx;
...@@ -445,6 +444,7 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, ...@@ -445,6 +444,7 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
{ {
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
struct hdmi_codec_params hp = { struct hdmi_codec_params hp = {
.iec = { .iec = {
.status = { 0 }, .status = { 0 },
...@@ -489,28 +489,27 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, ...@@ -489,28 +489,27 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
hp.channels = params_channels(params); hp.channels = params_channels(params);
return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data, return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data,
&hcp->daifmt[dai->id], &hp); cf, &hp);
} }
static int hdmi_codec_set_fmt(struct snd_soc_dai *dai, static int hdmi_codec_i2s_set_fmt(struct snd_soc_dai *dai,
unsigned int fmt) unsigned int fmt)
{ {
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
struct hdmi_codec_daifmt cf = { 0 };
if (dai->id == DAI_ID_SPDIF) /* Reset daifmt */
return 0; memset(cf, 0, sizeof(*cf));
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM: case SND_SOC_DAIFMT_CBM_CFM:
cf.bit_clk_master = 1; cf->bit_clk_master = 1;
cf.frame_clk_master = 1; cf->frame_clk_master = 1;
break; break;
case SND_SOC_DAIFMT_CBS_CFM: case SND_SOC_DAIFMT_CBS_CFM:
cf.frame_clk_master = 1; cf->frame_clk_master = 1;
break; break;
case SND_SOC_DAIFMT_CBM_CFS: case SND_SOC_DAIFMT_CBM_CFS:
cf.bit_clk_master = 1; cf->bit_clk_master = 1;
break; break;
case SND_SOC_DAIFMT_CBS_CFS: case SND_SOC_DAIFMT_CBS_CFS:
break; break;
...@@ -522,43 +521,41 @@ static int hdmi_codec_set_fmt(struct snd_soc_dai *dai, ...@@ -522,43 +521,41 @@ static int hdmi_codec_set_fmt(struct snd_soc_dai *dai,
case SND_SOC_DAIFMT_NB_NF: case SND_SOC_DAIFMT_NB_NF:
break; break;
case SND_SOC_DAIFMT_NB_IF: case SND_SOC_DAIFMT_NB_IF:
cf.frame_clk_inv = 1; cf->frame_clk_inv = 1;
break; break;
case SND_SOC_DAIFMT_IB_NF: case SND_SOC_DAIFMT_IB_NF:
cf.bit_clk_inv = 1; cf->bit_clk_inv = 1;
break; break;
case SND_SOC_DAIFMT_IB_IF: case SND_SOC_DAIFMT_IB_IF:
cf.frame_clk_inv = 1; cf->frame_clk_inv = 1;
cf.bit_clk_inv = 1; cf->bit_clk_inv = 1;
break; break;
} }
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S: case SND_SOC_DAIFMT_I2S:
cf.fmt = HDMI_I2S; cf->fmt = HDMI_I2S;
break; break;
case SND_SOC_DAIFMT_DSP_A: case SND_SOC_DAIFMT_DSP_A:
cf.fmt = HDMI_DSP_A; cf->fmt = HDMI_DSP_A;
break; break;
case SND_SOC_DAIFMT_DSP_B: case SND_SOC_DAIFMT_DSP_B:
cf.fmt = HDMI_DSP_B; cf->fmt = HDMI_DSP_B;
break; break;
case SND_SOC_DAIFMT_RIGHT_J: case SND_SOC_DAIFMT_RIGHT_J:
cf.fmt = HDMI_RIGHT_J; cf->fmt = HDMI_RIGHT_J;
break; break;
case SND_SOC_DAIFMT_LEFT_J: case SND_SOC_DAIFMT_LEFT_J:
cf.fmt = HDMI_LEFT_J; cf->fmt = HDMI_LEFT_J;
break; break;
case SND_SOC_DAIFMT_AC97: case SND_SOC_DAIFMT_AC97:
cf.fmt = HDMI_AC97; cf->fmt = HDMI_AC97;
break; break;
default: default:
dev_err(dai->dev, "Invalid DAI interface format\n"); dev_err(dai->dev, "Invalid DAI interface format\n");
return -EINVAL; return -EINVAL;
} }
hcp->daifmt[dai->id] = cf;
return 0; return 0;
} }
...@@ -573,14 +570,20 @@ static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute) ...@@ -573,14 +570,20 @@ static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute)
return 0; return 0;
} }
static const struct snd_soc_dai_ops hdmi_dai_ops = { static const struct snd_soc_dai_ops hdmi_codec_i2s_dai_ops = {
.startup = hdmi_codec_startup, .startup = hdmi_codec_startup,
.shutdown = hdmi_codec_shutdown, .shutdown = hdmi_codec_shutdown,
.hw_params = hdmi_codec_hw_params, .hw_params = hdmi_codec_hw_params,
.set_fmt = hdmi_codec_set_fmt, .set_fmt = hdmi_codec_i2s_set_fmt,
.digital_mute = hdmi_codec_digital_mute, .digital_mute = hdmi_codec_digital_mute,
}; };
static const struct snd_soc_dai_ops hdmi_codec_spdif_dai_ops = {
.startup = hdmi_codec_startup,
.shutdown = hdmi_codec_shutdown,
.hw_params = hdmi_codec_hw_params,
.digital_mute = hdmi_codec_digital_mute,
};
#define HDMI_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ #define HDMI_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
...@@ -648,20 +651,52 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, ...@@ -648,20 +651,52 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
static int hdmi_dai_probe(struct snd_soc_dai *dai) static int hdmi_dai_probe(struct snd_soc_dai *dai)
{ {
struct snd_soc_dapm_context *dapm; struct snd_soc_dapm_context *dapm;
struct hdmi_codec_daifmt *daifmt;
struct snd_soc_dapm_route route = { struct snd_soc_dapm_route route = {
.sink = "TX", .sink = "TX",
.source = dai->driver->playback.stream_name, .source = dai->driver->playback.stream_name,
}; };
int ret;
dapm = snd_soc_component_get_dapm(dai->component); dapm = snd_soc_component_get_dapm(dai->component);
ret = snd_soc_dapm_add_routes(dapm, &route, 1);
if (ret)
return ret;
daifmt = kzalloc(sizeof(*daifmt), GFP_KERNEL);
if (!daifmt)
return -ENOMEM;
return snd_soc_dapm_add_routes(dapm, &route, 1); dai->playback_dma_data = daifmt;
return 0;
}
static int hdmi_dai_spdif_probe(struct snd_soc_dai *dai)
{
struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
int ret;
ret = hdmi_dai_probe(dai);
if (ret)
return ret;
cf = dai->playback_dma_data;
cf->fmt = HDMI_SPDIF;
return 0;
}
static int hdmi_codec_dai_remove(struct snd_soc_dai *dai)
{
kfree(dai->playback_dma_data);
return 0;
} }
static const struct snd_soc_dai_driver hdmi_i2s_dai = { static const struct snd_soc_dai_driver hdmi_i2s_dai = {
.name = "i2s-hifi", .name = "i2s-hifi",
.id = DAI_ID_I2S, .id = DAI_ID_I2S,
.probe = hdmi_dai_probe, .probe = hdmi_dai_probe,
.remove = hdmi_codec_dai_remove,
.playback = { .playback = {
.stream_name = "I2S Playback", .stream_name = "I2S Playback",
.channels_min = 2, .channels_min = 2,
...@@ -670,14 +705,15 @@ static const struct snd_soc_dai_driver hdmi_i2s_dai = { ...@@ -670,14 +705,15 @@ static const struct snd_soc_dai_driver hdmi_i2s_dai = {
.formats = I2S_FORMATS, .formats = I2S_FORMATS,
.sig_bits = 24, .sig_bits = 24,
}, },
.ops = &hdmi_dai_ops, .ops = &hdmi_codec_i2s_dai_ops,
.pcm_new = hdmi_codec_pcm_new, .pcm_new = hdmi_codec_pcm_new,
}; };
static const struct snd_soc_dai_driver hdmi_spdif_dai = { static const struct snd_soc_dai_driver hdmi_spdif_dai = {
.name = "spdif-hifi", .name = "spdif-hifi",
.id = DAI_ID_SPDIF, .id = DAI_ID_SPDIF,
.probe = hdmi_dai_probe, .probe = hdmi_dai_spdif_probe,
.remove = hdmi_codec_dai_remove,
.playback = { .playback = {
.stream_name = "SPDIF Playback", .stream_name = "SPDIF Playback",
.channels_min = 2, .channels_min = 2,
...@@ -685,7 +721,7 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = { ...@@ -685,7 +721,7 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = {
.rates = HDMI_RATES, .rates = HDMI_RATES,
.formats = SPDIF_FORMATS, .formats = SPDIF_FORMATS,
}, },
.ops = &hdmi_dai_ops, .ops = &hdmi_codec_spdif_dai_ops,
.pcm_new = hdmi_codec_pcm_new, .pcm_new = hdmi_codec_pcm_new,
}; };
...@@ -747,10 +783,8 @@ static int hdmi_codec_probe(struct platform_device *pdev) ...@@ -747,10 +783,8 @@ static int hdmi_codec_probe(struct platform_device *pdev)
i++; i++;
} }
if (hcd->spdif) { if (hcd->spdif)
daidrv[i] = hdmi_spdif_dai; daidrv[i] = hdmi_spdif_dai;
hcp->daifmt[DAI_ID_SPDIF].fmt = HDMI_SPDIF;
}
dev_set_drvdata(dev, hcp); dev_set_drvdata(dev, hcp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment