Merge branch 'asoc-5.3' into asoc-next

This commit is contained in:
Mark Brown
2019-07-06 12:25:26 +01:00
312개의 변경된 파일26362개의 추가작업 그리고 4794개의 파일을 삭제

파일 보기

@@ -85,7 +85,6 @@ int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev,
const struct hdac_ext_bus_ops *ext_ops)
{
int ret;
static int idx;
/* check if io ops are provided, if not load the defaults */
if (io_ops == NULL)
@@ -96,7 +95,12 @@ int snd_hdac_ext_bus_init(struct hdac_bus *bus, struct device *dev,
return ret;
bus->ext_ops = ext_ops;
bus->idx = idx++;
/* FIXME:
* Currently only one bus is supported, if there is device with more
* buses, bus->idx should be greater than 0, but there needs to be a
* reliable way to always assign same number.
*/
bus->idx = 0;
bus->cmd_dma_state = true;
return 0;

파일 보기

@@ -298,69 +298,71 @@ static const struct snd_soc_ops cz_dmic1_cap_ops = {
.hw_params = cz_da7219_params,
};
SND_SOC_DAILINK_DEF(designware1,
DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.1.auto")));
SND_SOC_DAILINK_DEF(designware2,
DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.2.auto")));
SND_SOC_DAILINK_DEF(designware3,
DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.3.auto")));
SND_SOC_DAILINK_DEF(dlgs,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-DLGS7219:00", "da7219-hifi")));
SND_SOC_DAILINK_DEF(mx,
DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00", "HiFi")));
SND_SOC_DAILINK_DEF(adau,
DAILINK_COMP_ARRAY(COMP_CODEC("ADAU7002:00", "adau7002-hifi")));
SND_SOC_DAILINK_DEF(platform,
DAILINK_COMP_ARRAY(COMP_PLATFORM("acp_audio_dma.0.auto")));
static struct snd_soc_dai_link cz_dai_7219_98357[] = {
{
.name = "amd-da7219-play",
.stream_name = "Playback",
.platform_name = "acp_audio_dma.0.auto",
.cpu_dai_name = "designware-i2s.1.auto",
.codec_dai_name = "da7219-hifi",
.codec_name = "i2c-DLGS7219:00",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBM_CFM,
.init = cz_da7219_init,
.dpcm_playback = 1,
.ops = &cz_da7219_play_ops,
SND_SOC_DAILINK_REG(designware1, dlgs, platform),
},
{
.name = "amd-da7219-cap",
.stream_name = "Capture",
.platform_name = "acp_audio_dma.0.auto",
.cpu_dai_name = "designware-i2s.2.auto",
.codec_dai_name = "da7219-hifi",
.codec_name = "i2c-DLGS7219:00",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBM_CFM,
.dpcm_capture = 1,
.ops = &cz_da7219_cap_ops,
SND_SOC_DAILINK_REG(designware2, dlgs, platform),
},
{
.name = "amd-max98357-play",
.stream_name = "HiFi Playback",
.platform_name = "acp_audio_dma.0.auto",
.cpu_dai_name = "designware-i2s.3.auto",
.codec_dai_name = "HiFi",
.codec_name = "MX98357A:00",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBM_CFM,
.dpcm_playback = 1,
.ops = &cz_max_play_ops,
SND_SOC_DAILINK_REG(designware3, mx, platform),
},
{
/* C panel DMIC */
.name = "dmic0",
.stream_name = "DMIC0 Capture",
.platform_name = "acp_audio_dma.0.auto",
.cpu_dai_name = "designware-i2s.3.auto",
.codec_dai_name = "adau7002-hifi",
.codec_name = "ADAU7002:00",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBM_CFM,
.dpcm_capture = 1,
.ops = &cz_dmic0_cap_ops,
SND_SOC_DAILINK_REG(designware3, adau, platform),
},
{
/* A/B panel DMIC */
.name = "dmic1",
.stream_name = "DMIC1 Capture",
.platform_name = "acp_audio_dma.0.auto",
.cpu_dai_name = "designware-i2s.2.auto",
.codec_dai_name = "adau7002-hifi",
.codec_name = "ADAU7002:00",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBM_CFM,
.dpcm_capture = 1,
.ops = &cz_dmic1_cap_ops,
SND_SOC_DAILINK_REG(designware2, adau, platform),
},
};

파일 보기

@@ -95,29 +95,34 @@ static struct snd_soc_ops cz_aif1_ops = {
.hw_params = cz_aif1_hw_params,
};
SND_SOC_DAILINK_DEF(designware1,
DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.1.auto")));
SND_SOC_DAILINK_DEF(designware2,
DAILINK_COMP_ARRAY(COMP_CPU("designware-i2s.2.auto")));
SND_SOC_DAILINK_DEF(codec,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5650:00", "rt5645-aif1")));
SND_SOC_DAILINK_DEF(platform,
DAILINK_COMP_ARRAY(COMP_PLATFORM("acp_audio_dma.0.auto")));
static struct snd_soc_dai_link cz_dai_rt5650[] = {
{
.name = "amd-rt5645-play",
.stream_name = "RT5645_AIF1",
.platform_name = "acp_audio_dma.0.auto",
.cpu_dai_name = "designware-i2s.1.auto",
.codec_dai_name = "rt5645-aif1",
.codec_name = "i2c-10EC5650:00",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBM_CFM,
.init = cz_init,
.ops = &cz_aif1_ops,
SND_SOC_DAILINK_REG(designware1, codec, platform),
},
{
.name = "amd-rt5645-cap",
.stream_name = "RT5645_AIF1",
.platform_name = "acp_audio_dma.0.auto",
.cpu_dai_name = "designware-i2s.2.auto",
.codec_dai_name = "rt5645-aif1",
.codec_name = "i2c-10EC5650:00",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBM_CFM,
.ops = &cz_aif1_ops,
SND_SOC_DAILINK_REG(designware2, codec, platform),
},
};

파일 보기

@@ -32,6 +32,7 @@ struct i2s_stream_instance {
u16 channels;
u32 xfer_resolution;
struct page *pg;
u64 bytescount;
void __iomem *acp3x_base;
};
@@ -317,6 +318,24 @@ static int acp3x_dma_open(struct snd_pcm_substream *substream)
return 0;
}
static u64 acp_get_byte_count(struct i2s_stream_instance *rtd, int direction)
{
u64 byte_count;
if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
byte_count = rv_readl(rtd->acp3x_base +
mmACP_BT_TX_LINEARPOSITIONCNTR_HIGH);
byte_count |= rv_readl(rtd->acp3x_base +
mmACP_BT_TX_LINEARPOSITIONCNTR_LOW);
} else {
byte_count = rv_readl(rtd->acp3x_base +
mmACP_BT_RX_LINEARPOSITIONCNTR_HIGH);
byte_count |= rv_readl(rtd->acp3x_base +
mmACP_BT_RX_LINEARPOSITIONCNTR_LOW);
}
return byte_count;
}
static int acp3x_dma_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
@@ -350,18 +369,17 @@ static int acp3x_dma_hw_params(struct snd_pcm_substream *substream,
static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_pcm_substream *substream)
{
u32 pos = 0;
struct i2s_stream_instance *rtd = substream->runtime->private_data;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
pos = rv_readl(rtd->acp3x_base +
mmACP_BT_TX_LINKPOSITIONCNTR);
else
pos = rv_readl(rtd->acp3x_base +
mmACP_BT_RX_LINKPOSITIONCNTR);
if (pos >= MAX_BUFFER)
pos = 0;
u32 buffersize = 0;
u64 bytescount = 0;
struct i2s_stream_instance *rtd =
substream->runtime->private_data;
buffersize = frames_to_bytes(substream->runtime,
substream->runtime->buffer_size);
bytescount = acp_get_byte_count(rtd, substream->stream);
if (bytescount > rtd->bytescount)
bytescount -= rtd->bytescount;
pos = do_div(bytescount, buffersize);
return bytes_to_frames(substream->runtime, pos);
}
@@ -521,6 +539,7 @@ static int acp3x_dai_i2s_trigger(struct snd_pcm_substream *substream,
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
rtd->bytescount = acp_get_byte_count(rtd, substream->stream);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
rv_writel(period_bytes, rtd->acp3x_base +
mmACP_BT_TX_INTR_WATERMARK_SIZE);

파일 보기

@@ -497,17 +497,30 @@ static int atmel_classd_asoc_card_init(struct device *dev,
{
struct snd_soc_dai_link *dai_link;
struct atmel_classd *dd = snd_soc_card_get_drvdata(card);
struct snd_soc_dai_link_component *comp;
dai_link = devm_kzalloc(dev, sizeof(*dai_link), GFP_KERNEL);
if (!dai_link)
return -ENOMEM;
comp = devm_kzalloc(dev, 3 * sizeof(*comp), GFP_KERNEL);
if (!comp)
return -ENOMEM;
dai_link->cpus = &comp[0];
dai_link->codecs = &comp[1];
dai_link->platforms = &comp[2];
dai_link->num_cpus = 1;
dai_link->num_codecs = 1;
dai_link->num_platforms = 1;
dai_link->name = "CLASSD";
dai_link->stream_name = "CLASSD PCM";
dai_link->codec_dai_name = ATMEL_CLASSD_CODEC_DAI_NAME;
dai_link->cpu_dai_name = dev_name(dev);
dai_link->codec_name = dev_name(dev);
dai_link->platform_name = dev_name(dev);
dai_link->codecs->dai_name = ATMEL_CLASSD_CODEC_DAI_NAME;
dai_link->cpus->dai_name = dev_name(dev);
dai_link->codecs->name = dev_name(dev);
dai_link->platforms->name = dev_name(dev);
card->dai_link = dai_link;
card->num_links = 1;

파일 보기

@@ -111,16 +111,11 @@ static const struct snd_dmaengine_pcm_config atmel_dmaengine_pcm_config = {
int atmel_pcm_dma_platform_register(struct device *dev)
{
return snd_dmaengine_pcm_register(dev, &atmel_dmaengine_pcm_config, 0);
return devm_snd_dmaengine_pcm_register(dev,
&atmel_dmaengine_pcm_config, 0);
}
EXPORT_SYMBOL(atmel_pcm_dma_platform_register);
void atmel_pcm_dma_platform_unregister(struct device *dev)
{
snd_dmaengine_pcm_unregister(dev);
}
EXPORT_SYMBOL(atmel_pcm_dma_platform_unregister);
MODULE_AUTHOR("Bo Shen <voice.shen@atmel.com>");
MODULE_DESCRIPTION("Atmel DMA based PCM module");
MODULE_LICENSE("GPL");

파일 보기

@@ -393,11 +393,6 @@ int atmel_pcm_pdc_platform_register(struct device *dev)
}
EXPORT_SYMBOL(atmel_pcm_pdc_platform_register);
void atmel_pcm_pdc_platform_unregister(struct device *dev)
{
}
EXPORT_SYMBOL(atmel_pcm_pdc_platform_unregister);
MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
MODULE_DESCRIPTION("Atmel PCM module");
MODULE_LICENSE("GPL");

파일 보기

@@ -72,28 +72,20 @@ struct atmel_pcm_dma_params {
#if IS_ENABLED(CONFIG_SND_ATMEL_SOC_PDC)
int atmel_pcm_pdc_platform_register(struct device *dev);
void atmel_pcm_pdc_platform_unregister(struct device *dev);
#else
static inline int atmel_pcm_pdc_platform_register(struct device *dev)
{
return 0;
}
static inline void atmel_pcm_pdc_platform_unregister(struct device *dev)
{
}
#endif
#if IS_ENABLED(CONFIG_SND_ATMEL_SOC_DMA)
int atmel_pcm_dma_platform_register(struct device *dev);
void atmel_pcm_dma_platform_unregister(struct device *dev);
#else
static inline int atmel_pcm_dma_platform_register(struct device *dev)
{
return 0;
}
static inline void atmel_pcm_dma_platform_unregister(struct device *dev)
{
}
#endif
#endif /* _ATMEL_PCM_H */

파일 보기

@@ -508,17 +508,30 @@ static int atmel_pdmic_asoc_card_init(struct device *dev,
{
struct snd_soc_dai_link *dai_link;
struct atmel_pdmic *dd = snd_soc_card_get_drvdata(card);
struct snd_soc_dai_link_component *comp;
dai_link = devm_kzalloc(dev, sizeof(*dai_link), GFP_KERNEL);
if (!dai_link)
return -ENOMEM;
comp = devm_kzalloc(dev, 3 * sizeof(*comp), GFP_KERNEL);
if (!comp)
return -ENOMEM;
dai_link->cpus = &comp[0];
dai_link->codecs = &comp[1];
dai_link->platforms = &comp[2];
dai_link->num_cpus = 1;
dai_link->num_codecs = 1;
dai_link->num_platforms = 1;
dai_link->name = "PDMIC";
dai_link->stream_name = "PDMIC PCM";
dai_link->codec_dai_name = ATMEL_PDMIC_CODEC_DAI_NAME;
dai_link->cpu_dai_name = dev_name(dev);
dai_link->codec_name = dev_name(dev);
dai_link->platform_name = dev_name(dev);
dai_link->codecs->dai_name = ATMEL_PDMIC_CODEC_DAI_NAME;
dai_link->cpus->dai_name = dev_name(dev);
dai_link->codecs->name = dev_name(dev);
dai_link->platforms->name = dev_name(dev);
card->dai_link = dai_link;
card->num_links = 1;

파일 보기

@@ -1012,16 +1012,6 @@ static int asoc_ssc_init(struct device *dev)
return 0;
}
static void asoc_ssc_exit(struct device *dev)
{
struct ssc_device *ssc = dev_get_drvdata(dev);
if (ssc->pdata->use_dma)
atmel_pcm_dma_platform_unregister(dev);
else
atmel_pcm_pdc_platform_unregister(dev);
}
/**
* atmel_ssc_set_audio - Allocate the specified SSC for audio use.
*/
@@ -1050,7 +1040,6 @@ void atmel_ssc_put_audio(int ssc_id)
{
struct ssc_device *ssc = ssc_info[ssc_id].ssc;
asoc_ssc_exit(&ssc->pdev->dev);
ssc_free(ssc);
}
EXPORT_SYMBOL_GPL(atmel_ssc_put_audio);

파일 보기

@@ -56,14 +56,19 @@ static const struct snd_soc_ops atmel_asoc_wm8904_ops = {
.hw_params = atmel_asoc_wm8904_hw_params,
};
SND_SOC_DAILINK_DEFS(pcm,
DAILINK_COMP_ARRAY(COMP_EMPTY()),
DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "wm8904-hifi")),
DAILINK_COMP_ARRAY(COMP_EMPTY()));
static struct snd_soc_dai_link atmel_asoc_wm8904_dailink = {
.name = "WM8904",
.stream_name = "WM8904 PCM",
.codec_dai_name = "wm8904-hifi",
.dai_fmt = SND_SOC_DAIFMT_I2S
| SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBM_CFM,
.ops = &atmel_asoc_wm8904_ops,
SND_SOC_DAILINK_REG(pcm),
};
static struct snd_soc_card atmel_asoc_wm8904_card = {
@@ -107,8 +112,8 @@ static int atmel_asoc_wm8904_dt_init(struct platform_device *pdev)
ret = -EINVAL;
return ret;
}
dailink->cpu_of_node = cpu_np;
dailink->platform_of_node = cpu_np;
dailink->cpus->of_node = cpu_np;
dailink->platforms->of_node = cpu_np;
of_node_put(cpu_np);
codec_np = of_parse_phandle(np, "atmel,audio-codec", 0);
@@ -117,7 +122,7 @@ static int atmel_asoc_wm8904_dt_init(struct platform_device *pdev)
ret = -EINVAL;
return ret;
}
dailink->codec_of_node = codec_np;
dailink->codecs->of_node = codec_np;
of_node_put(codec_np);
return 0;
@@ -136,7 +141,7 @@ static int atmel_asoc_wm8904_probe(struct platform_device *pdev)
return ret;
}
id = of_alias_get_id((struct device_node *)dailink->cpu_of_node, "ssc");
id = of_alias_get_id((struct device_node *)dailink->cpus->of_node, "ssc");
ret = atmel_ssc_set_audio(id);
if (ret != 0) {
dev_err(&pdev->dev, "failed to set SSC %d for audio\n", id);
@@ -162,7 +167,7 @@ static int atmel_asoc_wm8904_remove(struct platform_device *pdev)
struct snd_soc_dai_link *dailink = &atmel_asoc_wm8904_dailink;
int id;
id = of_alias_get_id((struct device_node *)dailink->cpu_of_node, "ssc");
id = of_alias_get_id((struct device_node *)dailink->cpus->of_node, "ssc");
snd_soc_unregister_card(card);
atmel_ssc_put_audio(id);

파일 보기

@@ -63,6 +63,7 @@ static struct snd_soc_card snd_proto = {
static int snd_proto_probe(struct platform_device *pdev)
{
struct snd_soc_dai_link *dai;
struct snd_soc_dai_link_component *comp;
struct device_node *np = pdev->dev.of_node;
struct device_node *codec_np, *cpu_np;
struct device_node *bitclkmaster = NULL;
@@ -84,12 +85,24 @@ static int snd_proto_probe(struct platform_device *pdev)
if (!dai)
return -ENOMEM;
/* for cpus/codecs/platforms */
comp = devm_kzalloc(&pdev->dev, 3 * sizeof(*comp), GFP_KERNEL);
if (!comp)
return -ENOMEM;
snd_proto.dai_link = dai;
snd_proto.num_links = 1;
dai->cpus = &comp[0];
dai->num_cpus = 1;
dai->codecs = &comp[1];
dai->num_codecs = 1;
dai->platforms = &comp[2];
dai->num_platforms = 1;
dai->name = "WM8731";
dai->stream_name = "WM8731 HiFi";
dai->codec_dai_name = "wm8731-hifi";
dai->codecs->dai_name = "wm8731-hifi";
dai->init = &snd_proto_init;
codec_np = of_parse_phandle(np, "audio-codec", 0);
@@ -97,15 +110,15 @@ static int snd_proto_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "audio-codec node missing\n");
return -EINVAL;
}
dai->codec_of_node = codec_np;
dai->codecs->of_node = codec_np;
cpu_np = of_parse_phandle(np, "i2s-controller", 0);
if (!cpu_np) {
dev_err(&pdev->dev, "i2s-controller missing\n");
return -EINVAL;
}
dai->cpu_of_node = cpu_np;
dai->platform_of_node = cpu_np;
dai->cpus->of_node = cpu_np;
dai->platforms->of_node = cpu_np;
dai_fmt = snd_soc_of_parse_daifmt(np, NULL,
&bitclkmaster, &framemaster);

파일 보기

@@ -116,16 +116,18 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
return 0;
}
SND_SOC_DAILINK_DEFS(pcm,
DAILINK_COMP_ARRAY(COMP_CPU("at91rm9200_ssc.0")),
DAILINK_COMP_ARRAY(COMP_CODEC("wm8731.0-001b", "wm8731-hifi")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("at91rm9200_ssc.0")));
static struct snd_soc_dai_link at91sam9g20ek_dai = {
.name = "WM8731",
.stream_name = "WM8731 PCM",
.cpu_dai_name = "at91rm9200_ssc.0",
.codec_dai_name = "wm8731-hifi",
.init = at91sam9g20ek_wm8731_init,
.platform_name = "at91rm9200_ssc.0",
.codec_name = "wm8731.0-001b",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM,
SND_SOC_DAILINK_REG(pcm),
};
static struct snd_soc_card snd_soc_at91sam9g20ek = {
@@ -198,24 +200,24 @@ static int at91sam9g20ek_audio_probe(struct platform_device *pdev)
goto err;
/* Parse codec info */
at91sam9g20ek_dai.codec_name = NULL;
at91sam9g20ek_dai.codecs->name = NULL;
codec_np = of_parse_phandle(np, "atmel,audio-codec", 0);
if (!codec_np) {
dev_err(&pdev->dev, "codec info missing\n");
return -EINVAL;
}
at91sam9g20ek_dai.codec_of_node = codec_np;
at91sam9g20ek_dai.codecs->of_node = codec_np;
/* Parse dai and platform info */
at91sam9g20ek_dai.cpu_dai_name = NULL;
at91sam9g20ek_dai.platform_name = NULL;
at91sam9g20ek_dai.cpus->dai_name = NULL;
at91sam9g20ek_dai.platforms->name = NULL;
cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0);
if (!cpu_np) {
dev_err(&pdev->dev, "dai and pcm info missing\n");
return -EINVAL;
}
at91sam9g20ek_dai.cpu_of_node = cpu_np;
at91sam9g20ek_dai.platform_of_node = cpu_np;
at91sam9g20ek_dai.cpus->of_node = cpu_np;
at91sam9g20ek_dai.platforms->of_node = cpu_np;
of_node_put(codec_np);
of_node_put(cpu_np);

파일 보기

@@ -77,6 +77,7 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
struct snd_soc_card *card;
struct snd_soc_dai_link *dai;
struct sam9x5_drvdata *priv;
struct snd_soc_dai_link_component *comp;
int ret;
if (!np) {
@@ -87,7 +88,8 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
card = devm_kzalloc(&pdev->dev, sizeof(*card), GFP_KERNEL);
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
dai = devm_kzalloc(&pdev->dev, sizeof(*dai), GFP_KERNEL);
if (!dai || !card || !priv) {
comp = devm_kzalloc(&pdev->dev, 3 * sizeof(*comp), GFP_KERNEL);
if (!dai || !card || !priv || !comp) {
ret = -ENOMEM;
goto out;
}
@@ -100,9 +102,17 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
card->num_links = 1;
card->dapm_widgets = sam9x5_dapm_widgets;
card->num_dapm_widgets = ARRAY_SIZE(sam9x5_dapm_widgets);
dai->cpus = &comp[0];
dai->num_cpus = 1;
dai->codecs = &comp[1];
dai->num_codecs = 1;
dai->platforms = &comp[2];
dai->num_platforms = 1;
dai->name = "WM8731";
dai->stream_name = "WM8731 PCM";
dai->codec_dai_name = "wm8731-hifi";
dai->codecs->dai_name = "wm8731-hifi";
dai->init = sam9x5_wm8731_init;
dai->dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBM_CFM;
@@ -126,7 +136,7 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
goto out;
}
dai->codec_of_node = codec_np;
dai->codecs->of_node = codec_np;
cpu_np = of_parse_phandle(np, "atmel,ssc-controller", 0);
if (!cpu_np) {
@@ -134,8 +144,8 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
ret = -EINVAL;
goto out;
}
dai->cpu_of_node = cpu_np;
dai->platform_of_node = cpu_np;
dai->cpus->of_node = cpu_np;
dai->platforms->of_node = cpu_np;
priv->ssc_id = of_alias_get_id(cpu_np, "ssc");

파일 보기

@@ -294,13 +294,18 @@ static const struct snd_soc_dapm_route tse850_intercon[] = {
{ "DAC", NULL, "OUTL" },
};
SND_SOC_DAILINK_DEFS(pcm,
DAILINK_COMP_ARRAY(COMP_EMPTY()),
DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "pcm512x-hifi")),
DAILINK_COMP_ARRAY(COMP_EMPTY()));
static struct snd_soc_dai_link tse850_dailink = {
.name = "TSE-850",
.stream_name = "TSE-850-PCM",
.codec_dai_name = "pcm512x-hifi",
.dai_fmt = SND_SOC_DAIFMT_I2S
| SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBM_CFS,
SND_SOC_DAILINK_REG(pcm),
};
static struct snd_soc_card tse850_card = {
@@ -331,8 +336,8 @@ static int tse850_dt_init(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to get cpu dai\n");
return -EINVAL;
}
dailink->cpu_of_node = cpu_np;
dailink->platform_of_node = cpu_np;
dailink->cpus->of_node = cpu_np;
dailink->platforms->of_node = cpu_np;
of_node_put(cpu_np);
codec_np = of_parse_phandle(np, "axentia,audio-codec", 0);
@@ -340,7 +345,7 @@ static int tse850_dt_init(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to get codec info\n");
return -EINVAL;
}
dailink->codec_of_node = codec_np;
dailink->codecs->of_node = codec_np;
of_node_put(codec_np);
return 0;

파일 보기

@@ -19,13 +19,15 @@
#include "psc.h"
SND_SOC_DAILINK_DEFS(hifi,
DAILINK_COMP_ARRAY(COMP_CPU("alchemy-ac97c")),
DAILINK_COMP_ARRAY(COMP_CODEC("ac97-codec", "ac97-hifi")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("alchemy-pcm-dma.0")));
static struct snd_soc_dai_link db1000_ac97_dai = {
.name = "AC97",
.stream_name = "AC97 HiFi",
.codec_dai_name = "ac97-hifi",
.cpu_dai_name = "alchemy-ac97c",
.platform_name = "alchemy-pcm-dma.0",
.codec_name = "ac97-codec",
SND_SOC_DAILINK_REG(hifi),
};
static struct snd_soc_card db1000_ac97 = {

파일 보기

@@ -47,13 +47,15 @@ static const struct platform_device_id db1200_pids[] = {
/*------------------------- AC97 PART ---------------------------*/
SND_SOC_DAILINK_DEFS(db1200_ac97,
DAILINK_COMP_ARRAY(COMP_CPU("au1xpsc_ac97.1")),
DAILINK_COMP_ARRAY(COMP_CODEC("ac97-codec.1", "ac97-hifi")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("au1xpsc-pcm.1")));
static struct snd_soc_dai_link db1200_ac97_dai = {
.name = "AC97",
.stream_name = "AC97 HiFi",
.codec_dai_name = "ac97-hifi",
.cpu_dai_name = "au1xpsc_ac97.1",
.platform_name = "au1xpsc-pcm.1",
.codec_name = "ac97-codec.1",
SND_SOC_DAILINK_REG(db1200_ac97),
};
static struct snd_soc_card db1200_ac97_machine = {
@@ -63,13 +65,15 @@ static struct snd_soc_card db1200_ac97_machine = {
.num_links = 1,
};
SND_SOC_DAILINK_DEFS(db1300_ac97,
DAILINK_COMP_ARRAY(COMP_CPU("au1xpsc_ac97.1")),
DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec.1", "wm9712-hifi")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("au1xpsc-pcm.1")));
static struct snd_soc_dai_link db1300_ac97_dai = {
.name = "AC97",
.stream_name = "AC97 HiFi",
.codec_dai_name = "wm9712-hifi",
.cpu_dai_name = "au1xpsc_ac97.1",
.platform_name = "au1xpsc-pcm.1",
.codec_name = "wm9712-codec.1",
SND_SOC_DAILINK_REG(db1300_ac97),
};
static struct snd_soc_card db1300_ac97_machine = {
@@ -104,16 +108,18 @@ static const struct snd_soc_ops db1200_i2s_wm8731_ops = {
.startup = db1200_i2s_startup,
};
SND_SOC_DAILINK_DEFS(db1200_i2s,
DAILINK_COMP_ARRAY(COMP_CPU("au1xpsc_i2s.1")),
DAILINK_COMP_ARRAY(COMP_CODEC("wm8731.0-001b", "wm8731-hifi")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("au1xpsc-pcm.1")));
static struct snd_soc_dai_link db1200_i2s_dai = {
.name = "WM8731",
.stream_name = "WM8731 PCM",
.codec_dai_name = "wm8731-hifi",
.cpu_dai_name = "au1xpsc_i2s.1",
.platform_name = "au1xpsc-pcm.1",
.codec_name = "wm8731.0-001b",
.dai_fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM,
.ops = &db1200_i2s_wm8731_ops,
SND_SOC_DAILINK_REG(db1200_i2s),
};
static struct snd_soc_card db1200_i2s_machine = {
@@ -123,16 +129,18 @@ static struct snd_soc_card db1200_i2s_machine = {
.num_links = 1,
};
SND_SOC_DAILINK_DEFS(db1300_i2s,
DAILINK_COMP_ARRAY(COMP_CPU("au1xpsc_i2s.2")),
DAILINK_COMP_ARRAY(COMP_CODEC("wm8731.0-001b", "wm8731-hifi")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("au1xpsc-pcm.2")));
static struct snd_soc_dai_link db1300_i2s_dai = {
.name = "WM8731",
.stream_name = "WM8731 PCM",
.codec_dai_name = "wm8731-hifi",
.cpu_dai_name = "au1xpsc_i2s.2",
.platform_name = "au1xpsc-pcm.2",
.codec_name = "wm8731.0-001b",
.dai_fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM,
.ops = &db1200_i2s_wm8731_ops,
SND_SOC_DAILINK_REG(db1300_i2s),
};
static struct snd_soc_card db1300_i2s_machine = {
@@ -142,16 +150,18 @@ static struct snd_soc_card db1300_i2s_machine = {
.num_links = 1,
};
SND_SOC_DAILINK_DEFS(db1550_i2s,
DAILINK_COMP_ARRAY(COMP_CPU("au1xpsc_i2s.3")),
DAILINK_COMP_ARRAY(COMP_CODEC("wm8731.0-001b", "wm8731-hifi")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("au1xpsc-pcm.3")));
static struct snd_soc_dai_link db1550_i2s_dai = {
.name = "WM8731",
.stream_name = "WM8731 PCM",
.codec_dai_name = "wm8731-hifi",
.cpu_dai_name = "au1xpsc_i2s.3",
.platform_name = "au1xpsc-pcm.3",
.codec_name = "wm8731.0-001b",
.dai_fmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM,
.ops = &db1200_i2s_wm8731_ops,
SND_SOC_DAILINK_REG(db1550_i2s),
};
static struct snd_soc_card db1550_i2s_machine = {

파일 보기

@@ -340,16 +340,14 @@ static int au1xpsc_i2s_drvprobe(struct platform_device *pdev)
platform_set_drvdata(pdev, wd);
return snd_soc_register_component(&pdev->dev, &au1xpsc_i2s_component,
&wd->dai_drv, 1);
return devm_snd_soc_register_component(&pdev->dev,
&au1xpsc_i2s_component, &wd->dai_drv, 1);
}
static int au1xpsc_i2s_drvremove(struct platform_device *pdev)
{
struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
snd_soc_unregister_component(&pdev->dev);
__raw_writel(0, I2S_CFG(wd));
wmb(); /* drain writebuffer */
__raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));

파일 보기

@@ -51,16 +51,18 @@ static const struct snd_soc_ops edb93xx_ops = {
.hw_params = edb93xx_hw_params,
};
SND_SOC_DAILINK_DEFS(hifi,
DAILINK_COMP_ARRAY(COMP_CPU("ep93xx-i2s")),
DAILINK_COMP_ARRAY(COMP_CODEC("spi0.0", "cs4271-hifi")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("ep93xx-i2s")));
static struct snd_soc_dai_link edb93xx_dai = {
.name = "CS4271",
.stream_name = "CS4271 HiFi",
.platform_name = "ep93xx-i2s",
.cpu_dai_name = "ep93xx-i2s",
.codec_name = "spi0.0",
.codec_dai_name = "cs4271-hifi",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
.ops = &edb93xx_ops,
SND_SOC_DAILINK_REG(hifi),
};
static struct snd_soc_card snd_soc_edb93xx = {

파일 보기

@@ -473,19 +473,17 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
dev_set_drvdata(&pdev->dev, info);
err = snd_soc_register_component(&pdev->dev, &ep93xx_i2s_component,
err = devm_snd_soc_register_component(&pdev->dev, &ep93xx_i2s_component,
&ep93xx_i2s_dai, 1);
if (err)
goto fail_put_lrclk;
err = devm_ep93xx_pcm_platform_register(&pdev->dev);
if (err)
goto fail_unregister;
goto fail_put_lrclk;
return 0;
fail_unregister:
snd_soc_unregister_component(&pdev->dev);
fail_put_lrclk:
clk_put(info->lrclk);
fail_put_sclk:
@@ -500,7 +498,6 @@ static int ep93xx_i2s_remove(struct platform_device *pdev)
{
struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev);
snd_soc_unregister_component(&pdev->dev);
clk_put(info->lrclk);
clk_put(info->sclk);
clk_put(info->mclk);

파일 보기

@@ -18,13 +18,15 @@
#include <asm/mach-types.h>
SND_SOC_DAILINK_DEFS(hifi,
DAILINK_COMP_ARRAY(COMP_CPU("ep93xx-ac97")),
DAILINK_COMP_ARRAY(COMP_CODEC("ac97-codec", "ac97-hifi")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("ep93xx-ac97")));
static struct snd_soc_dai_link simone_dai = {
.name = "AC97",
.stream_name = "AC97 HiFi",
.cpu_dai_name = "ep93xx-ac97",
.codec_dai_name = "ac97-hifi",
.codec_name = "ac97-codec",
.platform_name = "ep93xx-ac97",
SND_SOC_DAILINK_REG(hifi),
};
static struct snd_soc_card snd_soc_simone = {

파일 보기

@@ -60,16 +60,19 @@ static const struct snd_soc_dapm_route audio_map[] = {
{"MICIN", NULL, "Mic Jack"},
};
SND_SOC_DAILINK_DEFS(aic23,
DAILINK_COMP_ARRAY(COMP_CPU("ep93xx-i2s")),
DAILINK_COMP_ARRAY(COMP_CODEC("tlv320aic23-codec.0-001a",
"tlv320aic23-hifi")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("ep93xx-i2s")));
static struct snd_soc_dai_link snappercl15_dai = {
.name = "tlv320aic23",
.stream_name = "AIC23",
.cpu_dai_name = "ep93xx-i2s",
.codec_dai_name = "tlv320aic23-hifi",
.codec_name = "tlv320aic23-codec.0-001a",
.platform_name = "ep93xx-i2s",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
.ops = &snappercl15_ops,
SND_SOC_DAILINK_REG(aic23),
};
static struct snd_soc_card snd_soc_snappercl15 = {

파일 보기

@@ -71,8 +71,12 @@ config SND_SOC_ALL_CODECS
select SND_SOC_CS4341 if SND_SOC_I2C_AND_SPI
select SND_SOC_CS4349 if I2C
select SND_SOC_CS47L24 if MFD_CS47L24
select SND_SOC_CS47L35 if MFD_CS47L35
select SND_SOC_CS47L85 if MFD_CS47L85
select SND_SOC_CS47L90 if MFD_CS47L90
select SND_SOC_CS53L30 if I2C
select SND_SOC_CX20442 if TTY
select SND_SOC_CX2072X if I2C
select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI
select SND_SOC_DA7213 if I2C
select SND_SOC_DA7218 if I2C
@@ -140,7 +144,9 @@ config SND_SOC_ALL_CODECS
select SND_SOC_RT274 if I2C
select SND_SOC_RT286 if I2C
select SND_SOC_RT298 if I2C
select SND_SOC_RT1011 if I2C
select SND_SOC_RT1305 if I2C
select SND_SOC_RT1308 if I2C
select SND_SOC_RT5514 if I2C
select SND_SOC_RT5616 if I2C
select SND_SOC_RT5631 if I2C
@@ -283,10 +289,12 @@ config SND_SOC_WM_HUBS
config SND_SOC_WM_ADSP
tristate
select SND_SOC_COMPRESS
default y if SND_SOC_MADERA=y
default y if SND_SOC_CS47L24=y
default y if SND_SOC_WM5102=y
default y if SND_SOC_WM5110=y
default y if SND_SOC_WM2200=y
default m if SND_SOC_MADERA=m
default m if SND_SOC_CS47L24=m
default m if SND_SOC_WM5102=m
default m if SND_SOC_WM5110=m
@@ -576,6 +584,15 @@ config SND_SOC_CS4349
config SND_SOC_CS47L24
tristate
config SND_SOC_CS47L35
tristate
config SND_SOC_CS47L85
tristate
config SND_SOC_CS47L90
tristate
# Cirrus Logic Quad-Channel ADC
config SND_SOC_CS53L30
tristate "Cirrus Logic CS53L30 CODEC"
@@ -585,6 +602,12 @@ config SND_SOC_CX20442
tristate
depends on TTY
config SND_SOC_CX2072X
tristate "Conexant CX2072X CODEC"
depends on I2C
help
Enable support for Conexant CX20721 and CX20723 codec chips.
config SND_SOC_JZ4740_CODEC
depends on MIPS || COMPILE_TEST
select REGMAP_MMIO
@@ -697,6 +720,15 @@ config SND_SOC_LOCHNAGAR_SC
This driver support the sound card functionality of the Cirrus
Logic Lochnagar audio development board.
config SND_SOC_MADERA
tristate
default y if SND_SOC_CS47L35=y
default y if SND_SOC_CS47L85=y
default y if SND_SOC_CS47L90=y
default m if SND_SOC_CS47L35=m
default m if SND_SOC_CS47L85=m
default m if SND_SOC_CS47L90=m
config SND_SOC_MAX98088
tristate "Maxim MAX98088/9 Low-Power, Stereo Audio Codec"
depends on I2C
@@ -708,7 +740,8 @@ config SND_SOC_MAX98095
tristate
config SND_SOC_MAX98357A
tristate
tristate "Maxim MAX98357A CODEC"
depends on GPIOLIB
config SND_SOC_MAX98371
tristate
@@ -870,7 +903,9 @@ config SND_SOC_RL6231
default y if SND_SOC_RT5670=y
default y if SND_SOC_RT5677=y
default y if SND_SOC_RT5682=y
default y if SND_SOC_RT1011=y
default y if SND_SOC_RT1305=y
default y if SND_SOC_RT1308=y
default m if SND_SOC_RT5514=m
default m if SND_SOC_RT5616=m
default m if SND_SOC_RT5640=m
@@ -884,7 +919,9 @@ config SND_SOC_RL6231
default m if SND_SOC_RT5670=m
default m if SND_SOC_RT5677=m
default m if SND_SOC_RT5682=m
default m if SND_SOC_RT1011=m
default m if SND_SOC_RT1305=m
default m if SND_SOC_RT1308=m
config SND_SOC_RL6347A
tristate
@@ -907,9 +944,15 @@ config SND_SOC_RT298
tristate
depends on I2C
config SND_SOC_RT1011
tristate
config SND_SOC_RT1305
tristate
config SND_SOC_RT1308
tristate
config SND_SOC_RT5514
tristate

파일 보기

@@ -65,8 +65,12 @@ snd-soc-cs43130-objs := cs43130.o
snd-soc-cs4341-objs := cs4341.o
snd-soc-cs4349-objs := cs4349.o
snd-soc-cs47l24-objs := cs47l24.o
snd-soc-cs47l35-objs := cs47l35.o
snd-soc-cs47l85-objs := cs47l85.o
snd-soc-cs47l90-objs := cs47l90.o
snd-soc-cs53l30-objs := cs53l30.o
snd-soc-cx20442-objs := cx20442.o
snd-soc-cx2072x-objs := cx2072x.o
snd-soc-da7210-objs := da7210.o
snd-soc-da7213-objs := da7213.o
snd-soc-da7218-objs := da7218.o
@@ -92,6 +96,7 @@ snd-soc-l3-objs := l3.o
snd-soc-lm4857-objs := lm4857.o
snd-soc-lm49453-objs := lm49453.o
snd-soc-lochnagar-sc-objs := lochnagar-sc.o
snd-soc-madera-objs := madera.o
snd-soc-max9759-objs := max9759.o
snd-soc-max9768-objs := max9768.o
snd-soc-max98088-objs := max98088.o
@@ -141,7 +146,9 @@ snd-soc-pcm512x-spi-objs := pcm512x-spi.o
snd-soc-rk3328-objs := rk3328_codec.o
snd-soc-rl6231-objs := rl6231.o
snd-soc-rl6347a-objs := rl6347a.o
snd-soc-rt1011-objs := rt1011.o
snd-soc-rt1305-objs := rt1305.o
snd-soc-rt1308-objs := rt1308.o
snd-soc-rt274-objs := rt274.o
snd-soc-rt286-objs := rt286.o
snd-soc-rt298-objs := rt298.o
@@ -339,8 +346,12 @@ obj-$(CONFIG_SND_SOC_CS43130) += snd-soc-cs43130.o
obj-$(CONFIG_SND_SOC_CS4341) += snd-soc-cs4341.o
obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o
obj-$(CONFIG_SND_SOC_CS47L24) += snd-soc-cs47l24.o
obj-$(CONFIG_SND_SOC_CS47L35) += snd-soc-cs47l35.o
obj-$(CONFIG_SND_SOC_CS47L85) += snd-soc-cs47l85.o
obj-$(CONFIG_SND_SOC_CS47L90) += snd-soc-cs47l90.o
obj-$(CONFIG_SND_SOC_CS53L30) += snd-soc-cs53l30.o
obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
obj-$(CONFIG_SND_SOC_CX2072X) += snd-soc-cx2072x.o
obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o
obj-$(CONFIG_SND_SOC_DA7218) += snd-soc-da7218.o
@@ -366,6 +377,7 @@ obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
obj-$(CONFIG_SND_SOC_LM49453) += snd-soc-lm49453.o
obj-$(CONFIG_SND_SOC_LOCHNAGAR_SC) += snd-soc-lochnagar-sc.o
obj-$(CONFIG_SND_SOC_MADERA) += snd-soc-madera.o
obj-$(CONFIG_SND_SOC_MAX9759) += snd-soc-max9759.o
obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o
obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
@@ -415,7 +427,9 @@ obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o
obj-$(CONFIG_SND_SOC_RK3328) += snd-soc-rk3328.o
obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o
obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o
obj-$(CONFIG_SND_SOC_RT1011) += snd-soc-rt1011.o
obj-$(CONFIG_SND_SOC_RT1305) += snd-soc-rt1305.o
obj-$(CONFIG_SND_SOC_RT1308) += snd-soc-rt1308.o
obj-$(CONFIG_SND_SOC_RT274) += snd-soc-rt274.o
obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o
obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o

파일 보기

@@ -413,6 +413,48 @@ static struct snd_soc_dai_driver ad193x_no_adc_dai = {
.ops = &ad193x_dai_ops,
};
struct ad193x_reg_default {
unsigned int reg;
unsigned int val;
};
/* codec register values to set after reset */
static void ad193x_reg_default_init(struct ad193x_priv *ad193x)
{
const struct ad193x_reg_default reg_init[] = {
{ 0, 0x99 }, /* PLL_CLK_CTRL0: pll input: mclki/xi 12.288Mhz */
{ 1, 0x04 }, /* PLL_CLK_CTRL1: no on-chip Vref */
{ 2, 0x40 }, /* DAC_CTRL0: TDM mode */
{ 3, 0x00 }, /* DAC_CTRL1: reset */
{ 4, 0x1A }, /* DAC_CTRL2: 48kHz de-emphasis, unmute dac */
{ 5, 0x00 }, /* DAC_CHNL_MUTE: unmute DAC channels */
{ 6, 0x00 }, /* DAC_L1_VOL: no attenuation */
{ 7, 0x00 }, /* DAC_R1_VOL: no attenuation */
{ 8, 0x00 }, /* DAC_L2_VOL: no attenuation */
{ 9, 0x00 }, /* DAC_R2_VOL: no attenuation */
{ 10, 0x00 }, /* DAC_L3_VOL: no attenuation */
{ 11, 0x00 }, /* DAC_R3_VOL: no attenuation */
{ 12, 0x00 }, /* DAC_L4_VOL: no attenuation */
{ 13, 0x00 }, /* DAC_R4_VOL: no attenuation */
};
const struct ad193x_reg_default reg_adc_init[] = {
{ 14, 0x03 }, /* ADC_CTRL0: high-pass filter enable */
{ 15, 0x43 }, /* ADC_CTRL1: sata delay=1, adc aux mode */
{ 16, 0x00 }, /* ADC_CTRL2: reset */
};
int i;
for (i = 0; i < ARRAY_SIZE(reg_init); i++)
regmap_write(ad193x->regmap, reg_init[i].reg, reg_init[i].val);
if (ad193x_has_adc(ad193x)) {
for (i = 0; i < ARRAY_SIZE(reg_adc_init); i++) {
regmap_write(ad193x->regmap, reg_adc_init[i].reg,
reg_adc_init[i].val);
}
}
}
static int ad193x_component_probe(struct snd_soc_component *component)
{
struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component);
@@ -420,25 +462,7 @@ static int ad193x_component_probe(struct snd_soc_component *component)
int num, ret;
/* default setting for ad193x */
/* unmute dac channels */
regmap_write(ad193x->regmap, AD193X_DAC_CHNL_MUTE, 0x0);
/* de-emphasis: 48kHz, powedown dac */
regmap_write(ad193x->regmap, AD193X_DAC_CTRL2, 0x1A);
/* dac in tdm mode */
regmap_write(ad193x->regmap, AD193X_DAC_CTRL0, 0x40);
/* adc only */
if (ad193x_has_adc(ad193x)) {
/* high-pass filter enable */
regmap_write(ad193x->regmap, AD193X_ADC_CTRL0, 0x3);
/* sata delay=1, adc aux mode */
regmap_write(ad193x->regmap, AD193X_ADC_CTRL1, 0x43);
}
/* pll input: mclki/xi */
regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */
regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL1, 0x04);
ad193x_reg_default_init(ad193x);
/* adc only */
if (ad193x_has_adc(ad193x)) {

파일 보기

@@ -400,14 +400,8 @@ static int ak4118_i2c_probe(struct i2c_client *i2c,
return ret;
}
return snd_soc_register_component(&i2c->dev, &soc_component_drv_ak4118,
&ak4118_dai, 1);
}
static int ak4118_i2c_remove(struct i2c_client *i2c)
{
snd_soc_unregister_component(&i2c->dev);
return 0;
return devm_snd_soc_register_component(&i2c->dev,
&soc_component_drv_ak4118, &ak4118_dai, 1);
}
static const struct of_device_id ak4118_of_match[] = {
@@ -429,7 +423,6 @@ static struct i2c_driver ak4118_i2c_driver = {
},
.id_table = ak4118_id_table,
.probe = ak4118_i2c_probe,
.remove = ak4118_i2c_remove,
};
module_i2c_driver(ak4118_i2c_driver);

파일 보기

@@ -413,7 +413,7 @@ static int cros_ec_codec_platform_probe(struct platform_device *pd)
platform_set_drvdata(pd, codec_data);
return snd_soc_register_component(dev, &cros_ec_component_driver,
return devm_snd_soc_register_component(dev, &cros_ec_component_driver,
cros_ec_dai, ARRAY_SIZE(cros_ec_dai));
}

파일 보기

@@ -14,6 +14,7 @@
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/gpio/consumer.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <sound/pcm_params.h>
@@ -45,6 +46,7 @@ struct cs42xx8_priv {
bool slave_mode;
unsigned long sysclk;
u32 tx_channels;
struct gpio_desc *gpiod_reset;
};
/* -127.5dB to 0dB with step of 0.5dB */
@@ -467,6 +469,13 @@ int cs42xx8_probe(struct device *dev, struct regmap *regmap)
return -EINVAL;
}
cs42xx8->gpiod_reset = devm_gpiod_get_optional(dev, "reset",
GPIOD_OUT_HIGH);
if (IS_ERR(cs42xx8->gpiod_reset))
return PTR_ERR(cs42xx8->gpiod_reset);
gpiod_set_value_cansleep(cs42xx8->gpiod_reset, 0);
cs42xx8->clk = devm_clk_get(dev, "mclk");
if (IS_ERR(cs42xx8->clk)) {
dev_err(dev, "failed to get the clock: %ld\n",
@@ -547,6 +556,8 @@ static int cs42xx8_runtime_resume(struct device *dev)
return ret;
}
gpiod_set_value_cansleep(cs42xx8->gpiod_reset, 0);
ret = regulator_bulk_enable(ARRAY_SIZE(cs42xx8->supplies),
cs42xx8->supplies);
if (ret) {
@@ -586,6 +597,8 @@ static int cs42xx8_runtime_suspend(struct device *dev)
regulator_bulk_disable(ARRAY_SIZE(cs42xx8->supplies),
cs42xx8->supplies);
gpiod_set_value_cansleep(cs42xx8->gpiod_reset, 1);
clk_disable_unprepare(cs42xx8->clk);
return 0;

1777
sound/soc/codecs/cs47l35.c Normal file

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Load Diff

2730
sound/soc/codecs/cs47l85.c Normal file

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Load Diff

2653
sound/soc/codecs/cs47l90.c Normal file

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Load Diff

1725
sound/soc/codecs/cx2072x.c Normal file

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Load Diff

314
sound/soc/codecs/cx2072x.h Normal file
파일 보기

@@ -0,0 +1,314 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* ALSA SoC CX20721/CX20723 codec driver
*
* Copyright: (C) 2017 Conexant Systems, Inc.
* Author: Simon Ho, <Simon.ho@conexant.com>
*/
#ifndef __CX2072X_H__
#define __CX2072X_H__
#define CX2072X_MCLK_PLL 1
#define CX2072X_MCLK_EXTERNAL_PLL 1
#define CX2072X_MCLK_INTERNAL_OSC 2
/*#define CX2072X_RATES SNDRV_PCM_RATE_8000_192000*/
#define CX2072X_RATES_DSP SNDRV_PCM_RATE_48000
#define CX2072X_REG_MAX 0x8a3c
#define CX2072X_VENDOR_ID 0x0200
#define CX2072X_REVISION_ID 0x0208
#define CX2072X_CURRENT_BCLK_FREQUENCY 0x00dc
#define CX2072X_AFG_POWER_STATE 0x0414
#define CX2072X_UM_RESPONSE 0x0420
#define CX2072X_GPIO_DATA 0x0454
#define CX2072X_GPIO_ENABLE 0x0458
#define CX2072X_GPIO_DIRECTION 0x045c
#define CX2072X_GPIO_WAKE 0x0460
#define CX2072X_GPIO_UM_ENABLE 0x0464
#define CX2072X_GPIO_STICKY_MASK 0x0468
#define CX2072X_AFG_FUNCTION_RESET 0x07fc
#define CX2072X_DAC1_CONVERTER_FORMAT 0x43c8
#define CX2072X_DAC1_AMP_GAIN_RIGHT 0x41c0
#define CX2072X_DAC1_AMP_GAIN_LEFT 0x41e0
#define CX2072X_DAC1_POWER_STATE 0x4014
#define CX2072X_DAC1_CONVERTER_STREAM_CHANNEL 0x4018
#define CX2072X_DAC1_EAPD_ENABLE 0x4030
#define CX2072X_DAC2_CONVERTER_FORMAT 0x47c8
#define CX2072X_DAC2_AMP_GAIN_RIGHT 0x45c0
#define CX2072X_DAC2_AMP_GAIN_LEFT 0x45e0
#define CX2072X_DAC2_POWER_STATE 0x4414
#define CX2072X_DAC2_CONVERTER_STREAM_CHANNEL 0x4418
#define CX2072X_ADC1_CONVERTER_FORMAT 0x4fc8
#define CX2072X_ADC1_AMP_GAIN_RIGHT_0 0x4d80
#define CX2072X_ADC1_AMP_GAIN_LEFT_0 0x4da0
#define CX2072X_ADC1_AMP_GAIN_RIGHT_1 0x4d84
#define CX2072X_ADC1_AMP_GAIN_LEFT_1 0x4da4
#define CX2072X_ADC1_AMP_GAIN_RIGHT_2 0x4d88
#define CX2072X_ADC1_AMP_GAIN_LEFT_2 0x4da8
#define CX2072X_ADC1_AMP_GAIN_RIGHT_3 0x4d8c
#define CX2072X_ADC1_AMP_GAIN_LEFT_3 0x4dac
#define CX2072X_ADC1_AMP_GAIN_RIGHT_4 0x4d90
#define CX2072X_ADC1_AMP_GAIN_LEFT_4 0x4db0
#define CX2072X_ADC1_AMP_GAIN_RIGHT_5 0x4d94
#define CX2072X_ADC1_AMP_GAIN_LEFT_5 0x4db4
#define CX2072X_ADC1_AMP_GAIN_RIGHT_6 0x4d98
#define CX2072X_ADC1_AMP_GAIN_LEFT_6 0x4db8
#define CX2072X_ADC1_CONNECTION_SELECT_CONTROL 0x4c04
#define CX2072X_ADC1_POWER_STATE 0x4c14
#define CX2072X_ADC1_CONVERTER_STREAM_CHANNEL 0x4c18
#define CX2072X_ADC2_CONVERTER_FORMAT 0x53c8
#define CX2072X_ADC2_AMP_GAIN_RIGHT_0 0x5180
#define CX2072X_ADC2_AMP_GAIN_LEFT_0 0x51a0
#define CX2072X_ADC2_AMP_GAIN_RIGHT_1 0x5184
#define CX2072X_ADC2_AMP_GAIN_LEFT_1 0x51a4
#define CX2072X_ADC2_AMP_GAIN_RIGHT_2 0x5188
#define CX2072X_ADC2_AMP_GAIN_LEFT_2 0x51a8
#define CX2072X_ADC2_CONNECTION_SELECT_CONTROL 0x5004
#define CX2072X_ADC2_POWER_STATE 0x5014
#define CX2072X_ADC2_CONVERTER_STREAM_CHANNEL 0x5018
#define CX2072X_PORTA_CONNECTION_SELECT_CTRL 0x5804
#define CX2072X_PORTA_POWER_STATE 0x5814
#define CX2072X_PORTA_PIN_CTRL 0x581c
#define CX2072X_PORTA_UNSOLICITED_RESPONSE 0x5820
#define CX2072X_PORTA_PIN_SENSE 0x5824
#define CX2072X_PORTA_EAPD_BTL 0x5830
#define CX2072X_PORTB_POWER_STATE 0x6014
#define CX2072X_PORTB_PIN_CTRL 0x601c
#define CX2072X_PORTB_UNSOLICITED_RESPONSE 0x6020
#define CX2072X_PORTB_PIN_SENSE 0x6024
#define CX2072X_PORTB_EAPD_BTL 0x6030
#define CX2072X_PORTB_GAIN_RIGHT 0x6180
#define CX2072X_PORTB_GAIN_LEFT 0x61a0
#define CX2072X_PORTC_POWER_STATE 0x6814
#define CX2072X_PORTC_PIN_CTRL 0x681c
#define CX2072X_PORTC_GAIN_RIGHT 0x6980
#define CX2072X_PORTC_GAIN_LEFT 0x69a0
#define CX2072X_PORTD_POWER_STATE 0x6414
#define CX2072X_PORTD_PIN_CTRL 0x641c
#define CX2072X_PORTD_UNSOLICITED_RESPONSE 0x6420
#define CX2072X_PORTD_PIN_SENSE 0x6424
#define CX2072X_PORTD_GAIN_RIGHT 0x6580
#define CX2072X_PORTD_GAIN_LEFT 0x65a0
#define CX2072X_PORTE_CONNECTION_SELECT_CTRL 0x7404
#define CX2072X_PORTE_POWER_STATE 0x7414
#define CX2072X_PORTE_PIN_CTRL 0x741c
#define CX2072X_PORTE_UNSOLICITED_RESPONSE 0x7420
#define CX2072X_PORTE_PIN_SENSE 0x7424
#define CX2072X_PORTE_EAPD_BTL 0x7430
#define CX2072X_PORTE_GAIN_RIGHT 0x7580
#define CX2072X_PORTE_GAIN_LEFT 0x75a0
#define CX2072X_PORTF_POWER_STATE 0x7814
#define CX2072X_PORTF_PIN_CTRL 0x781c
#define CX2072X_PORTF_UNSOLICITED_RESPONSE 0x7820
#define CX2072X_PORTF_PIN_SENSE 0x7824
#define CX2072X_PORTF_GAIN_RIGHT 0x7980
#define CX2072X_PORTF_GAIN_LEFT 0x79a0
#define CX2072X_PORTG_POWER_STATE 0x5c14
#define CX2072X_PORTG_PIN_CTRL 0x5c1c
#define CX2072X_PORTG_CONNECTION_SELECT_CTRL 0x5c04
#define CX2072X_PORTG_EAPD_BTL 0x5c30
#define CX2072X_PORTM_POWER_STATE 0x8814
#define CX2072X_PORTM_PIN_CTRL 0x881c
#define CX2072X_PORTM_CONNECTION_SELECT_CTRL 0x8804
#define CX2072X_PORTM_EAPD_BTL 0x8830
#define CX2072X_MIXER_POWER_STATE 0x5414
#define CX2072X_MIXER_GAIN_RIGHT_0 0x5580
#define CX2072X_MIXER_GAIN_LEFT_0 0x55a0
#define CX2072X_MIXER_GAIN_RIGHT_1 0x5584
#define CX2072X_MIXER_GAIN_LEFT_1 0x55a4
#define CX2072X_EQ_ENABLE_BYPASS 0x6d00
#define CX2072X_EQ_B0_COEFF 0x6d02
#define CX2072X_EQ_B1_COEFF 0x6d04
#define CX2072X_EQ_B2_COEFF 0x6d06
#define CX2072X_EQ_A1_COEFF 0x6d08
#define CX2072X_EQ_A2_COEFF 0x6d0a
#define CX2072X_EQ_G_COEFF 0x6d0c
#define CX2072X_EQ_BAND 0x6d0d
#define CX2072X_SPKR_DRC_ENABLE_STEP 0x6d10
#define CX2072X_SPKR_DRC_CONTROL 0x6d14
#define CX2072X_SPKR_DRC_TEST 0x6d18
#define CX2072X_DIGITAL_BIOS_TEST0 0x6d80
#define CX2072X_DIGITAL_BIOS_TEST2 0x6d84
#define CX2072X_I2SPCM_CONTROL1 0x6e00
#define CX2072X_I2SPCM_CONTROL2 0x6e04
#define CX2072X_I2SPCM_CONTROL3 0x6e08
#define CX2072X_I2SPCM_CONTROL4 0x6e0c
#define CX2072X_I2SPCM_CONTROL5 0x6e10
#define CX2072X_I2SPCM_CONTROL6 0x6e18
#define CX2072X_UM_INTERRUPT_CRTL_E 0x6e14
#define CX2072X_CODEC_TEST2 0x7108
#define CX2072X_CODEC_TEST9 0x7124
#define CX2072X_CODEC_TESTXX 0x7290
#define CX2072X_CODEC_TEST20 0x7310
#define CX2072X_CODEC_TEST24 0x731c
#define CX2072X_CODEC_TEST26 0x7328
#define CX2072X_ANALOG_TEST3 0x718c
#define CX2072X_ANALOG_TEST4 0x7190
#define CX2072X_ANALOG_TEST5 0x7194
#define CX2072X_ANALOG_TEST6 0x7198
#define CX2072X_ANALOG_TEST7 0x719c
#define CX2072X_ANALOG_TEST8 0x71a0
#define CX2072X_ANALOG_TEST9 0x71a4
#define CX2072X_ANALOG_TEST10 0x71a8
#define CX2072X_ANALOG_TEST11 0x71ac
#define CX2072X_ANALOG_TEST12 0x71b0
#define CX2072X_ANALOG_TEST13 0x71b4
#define CX2072X_DIGITAL_TEST0 0x7200
#define CX2072X_DIGITAL_TEST1 0x7204
#define CX2072X_DIGITAL_TEST11 0x722c
#define CX2072X_DIGITAL_TEST12 0x7230
#define CX2072X_DIGITAL_TEST15 0x723c
#define CX2072X_DIGITAL_TEST16 0x7080
#define CX2072X_DIGITAL_TEST17 0x7084
#define CX2072X_DIGITAL_TEST18 0x7088
#define CX2072X_DIGITAL_TEST19 0x708c
#define CX2072X_DIGITAL_TEST20 0x7090
/* not used in the current code, for future extensions (if any) */
#define CX2072X_MAX_EQ_BAND 7
#define CX2072X_MAX_EQ_COEFF 11
#define CX2072X_MAX_DRC_REGS 9
#define CX2072X_MIC_EQ_COEFF 10
#define CX2072X_PLBK_EQ_BAND_NUM 7
#define CX2072X_PLBK_EQ_COEF_LEN 11
#define CX2072X_PLBK_DRC_PARM_LEN 9
#define CX2072X_CLASSD_AMP_LEN 6
/* DAI interfae type */
#define CX2072X_DAI_HIFI 1
#define CX2072X_DAI_DSP 2
#define CX2072X_DAI_DSP_PWM 3 /* 4 ch, including mic and AEC */
enum cx2072x_reg_sample_size {
CX2072X_SAMPLE_SIZE_8_BITS = 0,
CX2072X_SAMPLE_SIZE_16_BITS = 1,
CX2072X_SAMPLE_SIZE_24_BITS = 2,
CX2072X_SAMPLE_SIZE_RESERVED = 3,
};
union cx2072x_reg_i2spcm_ctrl_reg1 {
struct {
u32 rx_data_one_line:1;
u32 rx_ws_pol:1;
u32 rx_ws_wid:7;
u32 rx_frm_len:5;
u32 rx_sa_size:2;
u32 tx_data_one_line:1;
u32 tx_ws_pol:1;
u32 tx_ws_wid:7;
u32 tx_frm_len:5;
u32 tx_sa_size:2;
} r;
u32 ulval;
};
union cx2072x_reg_i2spcm_ctrl_reg2 {
struct {
u32 tx_en_ch1:1;
u32 tx_en_ch2:1;
u32 tx_en_ch3:1;
u32 tx_en_ch4:1;
u32 tx_en_ch5:1;
u32 tx_en_ch6:1;
u32 tx_slot_1:5;
u32 tx_slot_2:5;
u32 tx_slot_3:5;
u32 tx_slot_4:5;
u32 res:1;
u32 tx_data_neg_bclk:1;
u32 tx_master:1;
u32 tx_tri_n:1;
u32 tx_endian_sel:1;
u32 tx_dstart_dly:1;
} r;
u32 ulval;
};
union cx2072x_reg_i2spcm_ctrl_reg3 {
struct {
u32 rx_en_ch1:1;
u32 rx_en_ch2:1;
u32 rx_en_ch3:1;
u32 rx_en_ch4:1;
u32 rx_en_ch5:1;
u32 rx_en_ch6:1;
u32 rx_slot_1:5;
u32 rx_slot_2:5;
u32 rx_slot_3:5;
u32 rx_slot_4:5;
u32 res:1;
u32 rx_data_neg_bclk:1;
u32 rx_master:1;
u32 rx_tri_n:1;
u32 rx_endian_sel:1;
u32 rx_dstart_dly:1;
} r;
u32 ulval;
};
union cx2072x_reg_i2spcm_ctrl_reg4 {
struct {
u32 rx_mute:1;
u32 tx_mute:1;
u32 reserved:1;
u32 dac_34_independent:1;
u32 dac_bclk_lrck_share:1;
u32 bclk_lrck_share_en:1;
u32 reserved2:2;
u32 rx_last_dac_ch_en:1;
u32 rx_last_dac_ch:3;
u32 tx_last_adc_ch_en:1;
u32 tx_last_adc_ch:3;
u32 rx_slot_5:5;
u32 rx_slot_6:5;
u32 reserved3:6;
} r;
u32 ulval;
};
union cx2072x_reg_i2spcm_ctrl_reg5 {
struct {
u32 tx_slot_5:5;
u32 reserved:3;
u32 tx_slot_6:5;
u32 reserved2:3;
u32 reserved3:8;
u32 i2s_pcm_clk_div:7;
u32 i2s_pcm_clk_div_chan_en:1;
} r;
u32 ulval;
};
union cx2072x_reg_i2spcm_ctrl_reg6 {
struct {
u32 reserved:5;
u32 rx_pause_cycles:3;
u32 rx_pause_start_pos:8;
u32 reserved2:5;
u32 tx_pause_cycles:3;
u32 tx_pause_start_pos:8;
} r;
u32 ulval;
};
union cx2072x_reg_digital_bios_test2 {
struct {
u32 pull_down_eapd:2;
u32 input_en_eapd_pad:1;
u32 push_pull_mode:1;
u32 eapd_pad_output_driver:2;
u32 pll_source:1;
u32 i2s_bclk_en:1;
u32 i2s_bclk_invert:1;
u32 pll_ref_clock:1;
u32 class_d_shield_clk:1;
u32 audio_pll_bypass_mode:1;
u32 reserved:4;
} r;
u32 ulval;
};
#endif /* __CX2072X_H__ */

파일 보기

@@ -1890,6 +1890,12 @@ static void hdmi_codec_remove(struct snd_soc_component *component)
{
struct hdac_hdmi_priv *hdmi = snd_soc_component_get_drvdata(component);
struct hdac_device *hdev = hdmi->hdev;
int ret;
ret = snd_hdac_acomp_register_notifier(hdev->bus, NULL);
if (ret < 0)
dev_err(&hdev->dev, "notifier unregister failed: err: %d\n",
ret);
pm_runtime_disable(&hdev->dev);
}
@@ -2113,6 +2119,7 @@ static int hdac_hdmi_runtime_suspend(struct device *dev)
return -EIO;
}
snd_hdac_codec_link_down(hdev);
snd_hdac_ext_bus_link_put(bus, hlink);
snd_hdac_display_power(bus, hdev->addr, false);
@@ -2139,6 +2146,7 @@ static int hdac_hdmi_runtime_resume(struct device *dev)
}
snd_hdac_ext_bus_link_get(bus, hlink);
snd_hdac_codec_link_up(hdev);
snd_hdac_display_power(bus, hdev->addr, true);

파일 보기

@@ -270,13 +270,10 @@ static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = {
struct hdmi_codec_priv {
struct hdmi_codec_pdata hcd;
struct snd_soc_dai_driver *daidrv;
struct hdmi_codec_daifmt daifmt[2];
struct mutex current_stream_lock;
struct snd_pcm_substream *current_stream;
uint8_t eld[MAX_ELD_BYTES];
struct snd_pcm_chmap *chmap_info;
unsigned int chmap_idx;
struct mutex lock;
};
static const struct snd_soc_dapm_widget hdmi_widgets[] = {
@@ -384,44 +381,22 @@ static int hdmi_codec_chmap_ctl_get(struct snd_kcontrol *kcontrol,
return 0;
}
static int hdmi_codec_new_stream(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
int ret = 0;
mutex_lock(&hcp->current_stream_lock);
if (!hcp->current_stream) {
hcp->current_stream = substream;
} else if (hcp->current_stream != substream) {
dev_err(dai->dev, "Only one simultaneous stream supported!\n");
ret = -EINVAL;
}
mutex_unlock(&hcp->current_stream_lock);
return ret;
}
static int hdmi_codec_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
int ret = 0;
dev_dbg(dai->dev, "%s()\n", __func__);
ret = hdmi_codec_new_stream(substream, dai);
if (ret)
return ret;
ret = mutex_trylock(&hcp->lock);
if (!ret) {
dev_err(dai->dev, "Only one simultaneous stream supported!\n");
return -EINVAL;
}
if (hcp->hcd.ops->audio_startup) {
ret = hcp->hcd.ops->audio_startup(dai->dev->parent, hcp->hcd.data);
if (ret) {
mutex_lock(&hcp->current_stream_lock);
hcp->current_stream = NULL;
mutex_unlock(&hcp->current_stream_lock);
return ret;
}
if (ret)
goto err;
}
if (hcp->hcd.ops->get_eld) {
@@ -431,17 +406,18 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream,
if (!ret) {
ret = snd_pcm_hw_constraint_eld(substream->runtime,
hcp->eld);
if (ret) {
mutex_lock(&hcp->current_stream_lock);
hcp->current_stream = NULL;
mutex_unlock(&hcp->current_stream_lock);
return ret;
}
if (ret)
goto err;
}
/* Select chmap supported */
hdmi_codec_eld_chmap(hcp);
}
return 0;
err:
/* Release the exclusive lock on error */
mutex_unlock(&hcp->lock);
return ret;
}
static void hdmi_codec_shutdown(struct snd_pcm_substream *substream,
@@ -449,16 +425,10 @@ static void hdmi_codec_shutdown(struct snd_pcm_substream *substream,
{
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
dev_dbg(dai->dev, "%s()\n", __func__);
WARN_ON(hcp->current_stream != substream);
hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data);
mutex_lock(&hcp->current_stream_lock);
hcp->current_stream = NULL;
mutex_unlock(&hcp->current_stream_lock);
mutex_unlock(&hcp->lock);
}
static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
@@ -466,6 +436,7 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *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 = {
.iec = {
.status = { 0 },
@@ -510,30 +481,27 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
hp.channels = params_channels(params);
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,
unsigned int fmt)
static int hdmi_codec_i2s_set_fmt(struct snd_soc_dai *dai,
unsigned int fmt)
{
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
struct hdmi_codec_daifmt cf = { 0 };
struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
dev_dbg(dai->dev, "%s()\n", __func__);
if (dai->id == DAI_ID_SPDIF)
return 0;
/* Reset daifmt */
memset(cf, 0, sizeof(*cf));
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM:
cf.bit_clk_master = 1;
cf.frame_clk_master = 1;
cf->bit_clk_master = 1;
cf->frame_clk_master = 1;
break;
case SND_SOC_DAIFMT_CBS_CFM:
cf.frame_clk_master = 1;
cf->frame_clk_master = 1;
break;
case SND_SOC_DAIFMT_CBM_CFS:
cf.bit_clk_master = 1;
cf->bit_clk_master = 1;
break;
case SND_SOC_DAIFMT_CBS_CFS:
break;
@@ -545,43 +513,41 @@ static int hdmi_codec_set_fmt(struct snd_soc_dai *dai,
case SND_SOC_DAIFMT_NB_NF:
break;
case SND_SOC_DAIFMT_NB_IF:
cf.frame_clk_inv = 1;
cf->frame_clk_inv = 1;
break;
case SND_SOC_DAIFMT_IB_NF:
cf.bit_clk_inv = 1;
cf->bit_clk_inv = 1;
break;
case SND_SOC_DAIFMT_IB_IF:
cf.frame_clk_inv = 1;
cf.bit_clk_inv = 1;
cf->frame_clk_inv = 1;
cf->bit_clk_inv = 1;
break;
}
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
cf.fmt = HDMI_I2S;
cf->fmt = HDMI_I2S;
break;
case SND_SOC_DAIFMT_DSP_A:
cf.fmt = HDMI_DSP_A;
cf->fmt = HDMI_DSP_A;
break;
case SND_SOC_DAIFMT_DSP_B:
cf.fmt = HDMI_DSP_B;
cf->fmt = HDMI_DSP_B;
break;
case SND_SOC_DAIFMT_RIGHT_J:
cf.fmt = HDMI_RIGHT_J;
cf->fmt = HDMI_RIGHT_J;
break;
case SND_SOC_DAIFMT_LEFT_J:
cf.fmt = HDMI_LEFT_J;
cf->fmt = HDMI_LEFT_J;
break;
case SND_SOC_DAIFMT_AC97:
cf.fmt = HDMI_AC97;
cf->fmt = HDMI_AC97;
break;
default:
dev_err(dai->dev, "Invalid DAI interface format\n");
return -EINVAL;
}
hcp->daifmt[dai->id] = cf;
return 0;
}
@@ -589,8 +555,6 @@ static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute)
{
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
dev_dbg(dai->dev, "%s()\n", __func__);
if (hcp->hcd.ops->digital_mute)
return hcp->hcd.ops->digital_mute(dai->dev->parent,
hcp->hcd.data, mute);
@@ -598,14 +562,20 @@ static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute)
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,
.shutdown = hdmi_codec_shutdown,
.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,
};
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 |\
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
@@ -648,8 +618,6 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
};
int ret;
dev_dbg(dai->dev, "%s()\n", __func__);
ret = snd_pcm_add_chmap_ctls(rtd->pcm, SNDRV_PCM_STREAM_PLAYBACK,
NULL, drv->playback.channels_max, 0,
&hcp->chmap_info);
@@ -675,20 +643,52 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
static int hdmi_dai_probe(struct snd_soc_dai *dai)
{
struct snd_soc_dapm_context *dapm;
struct hdmi_codec_daifmt *daifmt;
struct snd_soc_dapm_route route = {
.sink = "TX",
.source = dai->driver->playback.stream_name,
};
int ret;
dapm = snd_soc_component_get_dapm(dai->component);
ret = snd_soc_dapm_add_routes(dapm, &route, 1);
if (ret)
return ret;
return snd_soc_dapm_add_routes(dapm, &route, 1);
daifmt = kzalloc(sizeof(*daifmt), GFP_KERNEL);
if (!daifmt)
return -ENOMEM;
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 = {
.name = "i2s-hifi",
.id = DAI_ID_I2S,
.probe = hdmi_dai_probe,
.remove = hdmi_codec_dai_remove,
.playback = {
.stream_name = "I2S Playback",
.channels_min = 2,
@@ -697,14 +697,15 @@ static const struct snd_soc_dai_driver hdmi_i2s_dai = {
.formats = I2S_FORMATS,
.sig_bits = 24,
},
.ops = &hdmi_dai_ops,
.ops = &hdmi_codec_i2s_dai_ops,
.pcm_new = hdmi_codec_pcm_new,
};
static const struct snd_soc_dai_driver hdmi_spdif_dai = {
.name = "spdif-hifi",
.id = DAI_ID_SPDIF,
.probe = hdmi_dai_probe,
.probe = hdmi_dai_spdif_probe,
.remove = hdmi_codec_dai_remove,
.playback = {
.stream_name = "SPDIF Playback",
.channels_min = 2,
@@ -712,7 +713,7 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = {
.rates = HDMI_RATES,
.formats = SPDIF_FORMATS,
},
.ops = &hdmi_dai_ops,
.ops = &hdmi_codec_spdif_dai_ops,
.pcm_new = hdmi_codec_pcm_new,
};
@@ -741,13 +742,12 @@ static const struct snd_soc_component_driver hdmi_driver = {
static int hdmi_codec_probe(struct platform_device *pdev)
{
struct hdmi_codec_pdata *hcd = pdev->dev.platform_data;
struct snd_soc_dai_driver *daidrv;
struct device *dev = &pdev->dev;
struct hdmi_codec_priv *hcp;
int dai_count, i = 0;
int ret;
dev_dbg(dev, "%s()\n", __func__);
if (!hcd) {
dev_err(dev, "%s: No platform data\n", __func__);
return -EINVAL;
@@ -765,29 +765,25 @@ static int hdmi_codec_probe(struct platform_device *pdev)
return -ENOMEM;
hcp->hcd = *hcd;
mutex_init(&hcp->current_stream_lock);
mutex_init(&hcp->lock);
hcp->daidrv = devm_kcalloc(dev, dai_count, sizeof(*hcp->daidrv),
GFP_KERNEL);
if (!hcp->daidrv)
daidrv = devm_kcalloc(dev, dai_count, sizeof(*daidrv), GFP_KERNEL);
if (!daidrv)
return -ENOMEM;
if (hcd->i2s) {
hcp->daidrv[i] = hdmi_i2s_dai;
hcp->daidrv[i].playback.channels_max =
hcd->max_i2s_channels;
daidrv[i] = hdmi_i2s_dai;
daidrv[i].playback.channels_max = hcd->max_i2s_channels;
i++;
}
if (hcd->spdif) {
hcp->daidrv[i] = hdmi_spdif_dai;
hcp->daifmt[DAI_ID_SPDIF].fmt = HDMI_SPDIF;
}
if (hcd->spdif)
daidrv[i] = hdmi_spdif_dai;
dev_set_drvdata(dev, hcp);
ret = devm_snd_soc_register_component(dev, &hdmi_driver, hcp->daidrv,
dai_count);
ret = devm_snd_soc_register_component(dev, &hdmi_driver, daidrv,
dai_count);
if (ret) {
dev_err(dev, "%s: snd_soc_register_component() failed (%d)\n",
__func__, ret);

4177
sound/soc/codecs/madera.c Normal file

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Load Diff

442
sound/soc/codecs/madera.h Normal file
파일 보기

@@ -0,0 +1,442 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Cirrus Logic Madera class codecs common support
*
* Copyright (C) 2015-2018 Cirrus Logic, Inc. and
* Cirrus Logic International Semiconductor Ltd.
*/
#ifndef ASOC_MADERA_H
#define ASOC_MADERA_H
#include <linux/completion.h>
#include <sound/soc.h>
#include <sound/madera-pdata.h>
#include "wm_adsp.h"
#define MADERA_FLL1_REFCLK 1
#define MADERA_FLL2_REFCLK 2
#define MADERA_FLL3_REFCLK 3
#define MADERA_FLLAO_REFCLK 4
#define MADERA_FLL1_SYNCCLK 5
#define MADERA_FLL2_SYNCCLK 6
#define MADERA_FLL3_SYNCCLK 7
#define MADERA_FLLAO_SYNCCLK 8
#define MADERA_FLL_SRC_NONE -1
#define MADERA_FLL_SRC_MCLK1 0
#define MADERA_FLL_SRC_MCLK2 1
#define MADERA_FLL_SRC_SLIMCLK 3
#define MADERA_FLL_SRC_FLL1 4
#define MADERA_FLL_SRC_FLL2 5
#define MADERA_FLL_SRC_AIF1BCLK 8
#define MADERA_FLL_SRC_AIF2BCLK 9
#define MADERA_FLL_SRC_AIF3BCLK 10
#define MADERA_FLL_SRC_AIF4BCLK 11
#define MADERA_FLL_SRC_AIF1LRCLK 12
#define MADERA_FLL_SRC_AIF2LRCLK 13
#define MADERA_FLL_SRC_AIF3LRCLK 14
#define MADERA_FLL_SRC_AIF4LRCLK 15
#define MADERA_CLK_SYSCLK_1 1
#define MADERA_CLK_ASYNCCLK_1 2
#define MADERA_CLK_OPCLK 3
#define MADERA_CLK_ASYNC_OPCLK 4
#define MADERA_CLK_SYSCLK_2 5
#define MADERA_CLK_SYSCLK_3 6
#define MADERA_CLK_ASYNCCLK_2 7
#define MADERA_CLK_DSPCLK 8
#define MADERA_CLK_SRC_MCLK1 0x0
#define MADERA_CLK_SRC_MCLK2 0x1
#define MADERA_CLK_SRC_FLL1 0x4
#define MADERA_CLK_SRC_FLL2 0x5
#define MADERA_CLK_SRC_FLL3 0x6
#define MADERA_CLK_SRC_FLLAO_HI 0x7
#define MADERA_CLK_SRC_FLL1_DIV6 0x7
#define MADERA_CLK_SRC_AIF1BCLK 0x8
#define MADERA_CLK_SRC_AIF2BCLK 0x9
#define MADERA_CLK_SRC_AIF3BCLK 0xA
#define MADERA_CLK_SRC_AIF4BCLK 0xB
#define MADERA_CLK_SRC_FLLAO 0xF
#define MADERA_MIXER_VOL_MASK 0x00FE
#define MADERA_MIXER_VOL_SHIFT 1
#define MADERA_MIXER_VOL_WIDTH 7
#define MADERA_DOM_GRP_FX 0
#define MADERA_DOM_GRP_ASRC1 1
#define MADERA_DOM_GRP_ASRC2 2
#define MADERA_DOM_GRP_ISRC1 3
#define MADERA_DOM_GRP_ISRC2 4
#define MADERA_DOM_GRP_ISRC3 5
#define MADERA_DOM_GRP_ISRC4 6
#define MADERA_DOM_GRP_OUT 7
#define MADERA_DOM_GRP_SPD 8
#define MADERA_DOM_GRP_DSP1 9
#define MADERA_DOM_GRP_DSP2 10
#define MADERA_DOM_GRP_DSP3 11
#define MADERA_DOM_GRP_DSP4 12
#define MADERA_DOM_GRP_DSP5 13
#define MADERA_DOM_GRP_DSP6 14
#define MADERA_DOM_GRP_DSP7 15
#define MADERA_DOM_GRP_AIF1 16
#define MADERA_DOM_GRP_AIF2 17
#define MADERA_DOM_GRP_AIF3 18
#define MADERA_DOM_GRP_AIF4 19
#define MADERA_DOM_GRP_SLIMBUS 20
#define MADERA_DOM_GRP_PWM 21
#define MADERA_DOM_GRP_DFC 22
#define MADERA_N_DOM_GRPS 23
#define MADERA_MAX_DAI 11
#define MADERA_MAX_ADSP 7
#define MADERA_NUM_MIXER_INPUTS 148
struct madera;
struct wm_adsp;
struct madera_voice_trigger_info {
/** Which core triggered, 1-based (1 = DSP1, ...) */
int core_num;
};
struct madera_dai_priv {
int clk;
struct snd_pcm_hw_constraint_list constraint;
};
struct madera_priv {
struct wm_adsp adsp[MADERA_MAX_ADSP];
struct madera *madera;
struct device *dev;
int sysclk;
int asyncclk;
int dspclk;
struct madera_dai_priv dai[MADERA_MAX_DAI];
int num_inputs;
unsigned int in_pending;
unsigned int out_up_pending;
unsigned int out_up_delay;
unsigned int out_down_pending;
unsigned int out_down_delay;
unsigned int adsp_rate_cache[MADERA_MAX_ADSP];
struct mutex rate_lock;
int tdm_width[MADERA_MAX_AIF];
int tdm_slots[MADERA_MAX_AIF];
int domain_group_ref[MADERA_N_DOM_GRPS];
};
struct madera_fll_cfg {
int n;
unsigned int theta;
unsigned int lambda;
int refdiv;
int fratio;
int gain;
int alt_gain;
};
struct madera_fll {
struct madera *madera;
int id;
unsigned int base;
unsigned int fout;
int sync_src;
unsigned int sync_freq;
int ref_src;
unsigned int ref_freq;
struct madera_fll_cfg ref_cfg;
};
struct madera_enum {
struct soc_enum mixer_enum;
int val;
};
extern const unsigned int madera_ana_tlv[];
extern const unsigned int madera_eq_tlv[];
extern const unsigned int madera_digital_tlv[];
extern const unsigned int madera_noise_tlv[];
extern const unsigned int madera_ng_tlv[];
extern const unsigned int madera_mixer_tlv[];
extern const char * const madera_mixer_texts[MADERA_NUM_MIXER_INPUTS];
extern const unsigned int madera_mixer_values[MADERA_NUM_MIXER_INPUTS];
#define MADERA_GAINMUX_CONTROLS(name, base) \
SOC_SINGLE_RANGE_TLV(name " Input Volume", base + 1, \
MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
madera_mixer_tlv)
#define MADERA_MIXER_CONTROLS(name, base) \
SOC_SINGLE_RANGE_TLV(name " Input 1 Volume", base + 1, \
MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
madera_mixer_tlv), \
SOC_SINGLE_RANGE_TLV(name " Input 2 Volume", base + 3, \
MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
madera_mixer_tlv), \
SOC_SINGLE_RANGE_TLV(name " Input 3 Volume", base + 5, \
MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
madera_mixer_tlv), \
SOC_SINGLE_RANGE_TLV(name " Input 4 Volume", base + 7, \
MADERA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
madera_mixer_tlv)
#define MADERA_MUX_ENUM_DECL(name, reg) \
SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL( \
name, reg, 0, 0xff, madera_mixer_texts, madera_mixer_values)
#define MADERA_MUX_CTL_DECL(name) \
const struct snd_kcontrol_new name##_mux = \
SOC_DAPM_ENUM("Route", name##_enum)
#define MADERA_MUX_ENUMS(name, base_reg) \
static MADERA_MUX_ENUM_DECL(name##_enum, base_reg); \
static MADERA_MUX_CTL_DECL(name)
#define MADERA_MIXER_ENUMS(name, base_reg) \
MADERA_MUX_ENUMS(name##_in1, base_reg); \
MADERA_MUX_ENUMS(name##_in2, base_reg + 2); \
MADERA_MUX_ENUMS(name##_in3, base_reg + 4); \
MADERA_MUX_ENUMS(name##_in4, base_reg + 6)
#define MADERA_DSP_AUX_ENUMS(name, base_reg) \
MADERA_MUX_ENUMS(name##_aux1, base_reg); \
MADERA_MUX_ENUMS(name##_aux2, base_reg + 8); \
MADERA_MUX_ENUMS(name##_aux3, base_reg + 16); \
MADERA_MUX_ENUMS(name##_aux4, base_reg + 24); \
MADERA_MUX_ENUMS(name##_aux5, base_reg + 32); \
MADERA_MUX_ENUMS(name##_aux6, base_reg + 40)
#define MADERA_MUX(name, ctrl) \
SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
#define MADERA_MUX_WIDGETS(name, name_str) \
MADERA_MUX(name_str " Input 1", &name##_mux)
#define MADERA_MIXER_WIDGETS(name, name_str) \
MADERA_MUX(name_str " Input 1", &name##_in1_mux), \
MADERA_MUX(name_str " Input 2", &name##_in2_mux), \
MADERA_MUX(name_str " Input 3", &name##_in3_mux), \
MADERA_MUX(name_str " Input 4", &name##_in4_mux), \
SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
#define MADERA_DSP_WIDGETS(name, name_str) \
MADERA_MIXER_WIDGETS(name##L, name_str "L"), \
MADERA_MIXER_WIDGETS(name##R, name_str "R"), \
MADERA_MUX(name_str " Aux 1", &name##_aux1_mux), \
MADERA_MUX(name_str " Aux 2", &name##_aux2_mux), \
MADERA_MUX(name_str " Aux 3", &name##_aux3_mux), \
MADERA_MUX(name_str " Aux 4", &name##_aux4_mux), \
MADERA_MUX(name_str " Aux 5", &name##_aux5_mux), \
MADERA_MUX(name_str " Aux 6", &name##_aux6_mux)
#define MADERA_MUX_ROUTES(widget, name) \
{ widget, NULL, name " Input 1" }, \
MADERA_MIXER_INPUT_ROUTES(name " Input 1")
#define MADERA_MIXER_ROUTES(widget, name) \
{ widget, NULL, name " Mixer" }, \
{ name " Mixer", NULL, name " Input 1" }, \
{ name " Mixer", NULL, name " Input 2" }, \
{ name " Mixer", NULL, name " Input 3" }, \
{ name " Mixer", NULL, name " Input 4" }, \
MADERA_MIXER_INPUT_ROUTES(name " Input 1"), \
MADERA_MIXER_INPUT_ROUTES(name " Input 2"), \
MADERA_MIXER_INPUT_ROUTES(name " Input 3"), \
MADERA_MIXER_INPUT_ROUTES(name " Input 4")
#define MADERA_DSP_ROUTES(name) \
{ name, NULL, name " Preloader"}, \
{ name " Preload", NULL, name " Preloader"}, \
{ name, NULL, "SYSCLK"}, \
{ name, NULL, "DSPCLK"}, \
{ name, NULL, name " Aux 1" }, \
{ name, NULL, name " Aux 2" }, \
{ name, NULL, name " Aux 3" }, \
{ name, NULL, name " Aux 4" }, \
{ name, NULL, name " Aux 5" }, \
{ name, NULL, name " Aux 6" }, \
MADERA_MIXER_INPUT_ROUTES(name " Aux 1"), \
MADERA_MIXER_INPUT_ROUTES(name " Aux 2"), \
MADERA_MIXER_INPUT_ROUTES(name " Aux 3"), \
MADERA_MIXER_INPUT_ROUTES(name " Aux 4"), \
MADERA_MIXER_INPUT_ROUTES(name " Aux 5"), \
MADERA_MIXER_INPUT_ROUTES(name " Aux 6"), \
MADERA_MIXER_ROUTES(name, name "L"), \
MADERA_MIXER_ROUTES(name, name "R")
#define MADERA_RATE_ENUM(xname, xenum) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
.info = snd_soc_info_enum_double, \
.get = snd_soc_get_enum_double, .put = madera_rate_put, \
.private_value = (unsigned long)&xenum }
#define MADERA_EQ_CONTROL(xname, xbase) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \
.put = madera_eq_coeff_put, .private_value = \
((unsigned long)&(struct soc_bytes) { .base = xbase, \
.num_regs = 20, .mask = ~MADERA_EQ1_B1_MODE }) }
#define MADERA_LHPF_CONTROL(xname, xbase) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_bytes_info, .get = snd_soc_bytes_get, \
.put = madera_lhpf_coeff_put, .private_value = \
((unsigned long)&(struct soc_bytes) { .base = xbase, \
.num_regs = 1 }) }
#define MADERA_RATES SNDRV_PCM_RATE_KNOT
#define MADERA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
#define MADERA_OSR_ENUM_SIZE 5
#define MADERA_SYNC_RATE_ENUM_SIZE 3
#define MADERA_ASYNC_RATE_ENUM_SIZE 2
#define MADERA_RATE_ENUM_SIZE \
(MADERA_SYNC_RATE_ENUM_SIZE + MADERA_ASYNC_RATE_ENUM_SIZE)
#define MADERA_SAMPLE_RATE_ENUM_SIZE 16
#define MADERA_DFC_TYPE_ENUM_SIZE 5
#define MADERA_DFC_WIDTH_ENUM_SIZE 5
extern const struct snd_soc_dai_ops madera_dai_ops;
extern const struct snd_soc_dai_ops madera_simple_dai_ops;
extern const struct snd_kcontrol_new madera_inmux[];
extern const struct snd_kcontrol_new madera_inmode[];
extern const char * const madera_rate_text[MADERA_RATE_ENUM_SIZE];
extern const unsigned int madera_rate_val[MADERA_RATE_ENUM_SIZE];
extern const struct soc_enum madera_sample_rate[];
extern const struct soc_enum madera_isrc_fsl[];
extern const struct soc_enum madera_isrc_fsh[];
extern const struct soc_enum madera_asrc1_rate[];
extern const struct soc_enum madera_asrc2_rate[];
extern const struct soc_enum madera_dfc_width[];
extern const struct soc_enum madera_dfc_type[];
extern const struct soc_enum madera_in_vi_ramp;
extern const struct soc_enum madera_in_vd_ramp;
extern const struct soc_enum madera_out_vi_ramp;
extern const struct soc_enum madera_out_vd_ramp;
extern const struct soc_enum madera_lhpf1_mode;
extern const struct soc_enum madera_lhpf2_mode;
extern const struct soc_enum madera_lhpf3_mode;
extern const struct soc_enum madera_lhpf4_mode;
extern const struct soc_enum madera_ng_hold;
extern const struct soc_enum madera_in_hpf_cut_enum;
extern const struct soc_enum madera_in_dmic_osr[];
extern const struct soc_enum madera_output_anc_src[];
extern const struct soc_enum madera_anc_input_src[];
extern const struct soc_enum madera_anc_ng_enum;
extern const struct snd_kcontrol_new madera_dsp_trigger_output_mux[];
extern const struct snd_kcontrol_new madera_drc_activity_output_mux[];
extern const struct snd_kcontrol_new madera_adsp_rate_controls[];
int madera_dfc_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int madera_lp_mode_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int madera_out1_demux_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int madera_out1_demux_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int madera_rate_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int madera_eq_coeff_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int madera_lhpf_coeff_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int madera_sysclk_ev(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
int madera_spk_ev(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
int madera_in_ev(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
int madera_out_ev(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
int madera_hp_ev(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
int madera_anc_ev(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
int madera_domain_clk_ev(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol,
int event);
int madera_set_adsp_clk(struct madera_priv *priv, int dsp_num,
unsigned int freq);
int madera_set_sysclk(struct snd_soc_component *component, int clk_id,
int source, unsigned int freq, int dir);
int madera_init_fll(struct madera *madera, int id, int base,
struct madera_fll *fll);
int madera_set_fll_refclk(struct madera_fll *fll, int source,
unsigned int fref, unsigned int fout);
int madera_set_fll_syncclk(struct madera_fll *fll, int source,
unsigned int fref, unsigned int fout);
int madera_set_fll_ao_refclk(struct madera_fll *fll, int source,
unsigned int fin, unsigned int fout);
int madera_core_init(struct madera_priv *priv);
int madera_core_free(struct madera_priv *priv);
int madera_init_overheat(struct madera_priv *priv);
int madera_free_overheat(struct madera_priv *priv);
int madera_init_inputs(struct snd_soc_component *component);
int madera_init_outputs(struct snd_soc_component *component, int n_mono_routes);
int madera_init_bus_error_irq(struct madera_priv *priv, int dsp_num,
irq_handler_t handler);
void madera_free_bus_error_irq(struct madera_priv *priv, int dsp_num);
int madera_init_dai(struct madera_priv *priv, int dai);
int madera_set_output_mode(struct snd_soc_component *component, int output,
bool differential);
/* Following functions are for use by machine drivers */
static inline int madera_register_notifier(struct snd_soc_component *component,
struct notifier_block *nb)
{
struct madera_priv *priv = snd_soc_component_get_drvdata(component);
struct madera *madera = priv->madera;
return blocking_notifier_chain_register(&madera->notifier, nb);
}
static inline int
madera_unregister_notifier(struct snd_soc_component *component,
struct notifier_block *nb)
{
struct madera_priv *priv = snd_soc_component_get_drvdata(component);
struct madera *madera = priv->madera;
return blocking_notifier_chain_unregister(&madera->notifier, nb);
}
#endif

파일 보기

@@ -19,24 +19,42 @@
#include <sound/soc-dai.h>
#include <sound/soc-dapm.h>
struct max98357a_priv {
struct delayed_work enable_sdmode_work;
struct gpio_desc *sdmode;
unsigned int sdmode_delay;
};
static void max98357a_enable_sdmode_work(struct work_struct *work)
{
struct max98357a_priv *max98357a =
container_of(work, struct max98357a_priv,
enable_sdmode_work.work);
gpiod_set_value(max98357a->sdmode, 1);
}
static int max98357a_daiops_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
{
struct gpio_desc *sdmode = snd_soc_dai_get_drvdata(dai);
struct max98357a_priv *max98357a = snd_soc_dai_get_drvdata(dai);
if (!sdmode)
if (!max98357a->sdmode)
return 0;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
gpiod_set_value(sdmode, 1);
queue_delayed_work(system_power_efficient_wq,
&max98357a->enable_sdmode_work,
msecs_to_jiffies(max98357a->sdmode_delay));
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
gpiod_set_value(sdmode, 0);
cancel_delayed_work_sync(&max98357a->enable_sdmode_work);
gpiod_set_value(max98357a->sdmode, 0);
break;
}
@@ -51,21 +69,7 @@ static const struct snd_soc_dapm_route max98357a_dapm_routes[] = {
{"Speaker", NULL, "HiFi Playback"},
};
static int max98357a_component_probe(struct snd_soc_component *component)
{
struct gpio_desc *sdmode;
sdmode = devm_gpiod_get_optional(component->dev, "sdmode", GPIOD_OUT_LOW);
if (IS_ERR(sdmode))
return PTR_ERR(sdmode);
snd_soc_component_set_drvdata(component, sdmode);
return 0;
}
static const struct snd_soc_component_driver max98357a_component_driver = {
.probe = max98357a_component_probe,
.dapm_widgets = max98357a_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(max98357a_dapm_widgets),
.dapm_routes = max98357a_dapm_routes,
@@ -104,16 +108,39 @@ static struct snd_soc_dai_driver max98357a_dai_driver = {
static int max98357a_platform_probe(struct platform_device *pdev)
{
struct max98357a_priv *max98357a;
int ret;
max98357a = devm_kzalloc(&pdev->dev, sizeof(*max98357a), GFP_KERNEL);
if (!max98357a)
return -ENOMEM;
max98357a->sdmode = devm_gpiod_get_optional(&pdev->dev,
"sdmode", GPIOD_OUT_LOW);
if (IS_ERR(max98357a->sdmode))
return PTR_ERR(max98357a->sdmode);
ret = device_property_read_u32(&pdev->dev, "sdmode-delay",
&max98357a->sdmode_delay);
if (ret) {
max98357a->sdmode_delay = 0;
dev_dbg(&pdev->dev,
"no optional property 'sdmode-delay' found, default: no delay\n");
}
dev_set_drvdata(&pdev->dev, max98357a);
INIT_DELAYED_WORK(&max98357a->enable_sdmode_work,
max98357a_enable_sdmode_work);
return devm_snd_soc_register_component(&pdev->dev,
&max98357a_component_driver,
&max98357a_dai_driver, 1);
}
static int max98357a_platform_remove(struct platform_device *pdev)
{
return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id max98357a_device_id[] = {
{ .compatible = "maxim,max98357a" },
@@ -137,7 +164,6 @@ static struct platform_driver max98357a_platform_driver = {
.acpi_match_table = ACPI_PTR(max98357a_acpi_match),
},
.probe = max98357a_platform_probe,
.remove = max98357a_platform_remove,
};
module_platform_driver(max98357a_platform_driver);

파일 보기

@@ -187,6 +187,43 @@
#define MSM8916_WCD_DIGITAL_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
SNDRV_PCM_FMTBIT_S32_LE)
/* Codec supports 2 IIR filters */
enum {
IIR1 = 0,
IIR2,
IIR_MAX,
};
/* Codec supports 5 bands */
enum {
BAND1 = 0,
BAND2,
BAND3,
BAND4,
BAND5,
BAND_MAX,
};
#define WCD_IIR_FILTER_SIZE (sizeof(u32)*BAND_MAX)
#define WCD_IIR_FILTER_CTL(xname, iidx, bidx) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = wcd_iir_filter_info, \
.get = msm8x16_wcd_get_iir_band_audio_mixer, \
.put = msm8x16_wcd_put_iir_band_audio_mixer, \
.private_value = (unsigned long)&(struct wcd_iir_filter_ctl) { \
.iir_idx = iidx, \
.band_idx = bidx, \
.bytes_ext = {.max = WCD_IIR_FILTER_SIZE, }, \
} \
}
struct wcd_iir_filter_ctl {
unsigned int iir_idx;
unsigned int band_idx;
struct soc_bytes_ext bytes_ext;
};
struct msm8916_wcd_digital_priv {
struct clk *ahbclk, *mclk;
};
@@ -298,6 +335,161 @@ static SOC_ENUM_SINGLE_DECL(rx2_dcb_cutoff_enum, LPASS_CDC_RX2_B4_CTL, 0,
static SOC_ENUM_SINGLE_DECL(rx3_dcb_cutoff_enum, LPASS_CDC_RX3_B4_CTL, 0,
dc_blocker_cutoff_text);
static int msm8x16_wcd_codec_set_iir_gain(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_component *component =
snd_soc_dapm_to_component(w->dapm);
int value = 0, reg = 0;
switch (event) {
case SND_SOC_DAPM_POST_PMU:
if (w->shift == 0)
reg = LPASS_CDC_IIR1_GAIN_B1_CTL;
else if (w->shift == 1)
reg = LPASS_CDC_IIR2_GAIN_B1_CTL;
value = snd_soc_component_read32(component, reg);
snd_soc_component_write(component, reg, value);
break;
default:
break;
}
return 0;
}
static uint32_t get_iir_band_coeff(struct snd_soc_component *component,
int iir_idx, int band_idx,
int coeff_idx)
{
uint32_t value = 0;
/* Address does not automatically update if reading */
snd_soc_component_write(component,
(LPASS_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
((band_idx * BAND_MAX + coeff_idx)
* sizeof(uint32_t)) & 0x7F);
value |= snd_soc_component_read32(component,
(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx));
snd_soc_component_write(component,
(LPASS_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
((band_idx * BAND_MAX + coeff_idx)
* sizeof(uint32_t) + 1) & 0x7F);
value |= (snd_soc_component_read32(component,
(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx)) << 8);
snd_soc_component_write(component,
(LPASS_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
((band_idx * BAND_MAX + coeff_idx)
* sizeof(uint32_t) + 2) & 0x7F);
value |= (snd_soc_component_read32(component,
(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx)) << 16);
snd_soc_component_write(component,
(LPASS_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
((band_idx * BAND_MAX + coeff_idx)
* sizeof(uint32_t) + 3) & 0x7F);
/* Mask bits top 2 bits since they are reserved */
value |= ((snd_soc_component_read32(component,
(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx)) & 0x3f) << 24);
return value;
}
static int msm8x16_wcd_get_iir_band_audio_mixer(
struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component =
snd_soc_kcontrol_component(kcontrol);
struct wcd_iir_filter_ctl *ctl =
(struct wcd_iir_filter_ctl *)kcontrol->private_value;
struct soc_bytes_ext *params = &ctl->bytes_ext;
int iir_idx = ctl->iir_idx;
int band_idx = ctl->band_idx;
u32 coeff[BAND_MAX];
coeff[0] = get_iir_band_coeff(component, iir_idx, band_idx, 0);
coeff[1] = get_iir_band_coeff(component, iir_idx, band_idx, 1);
coeff[2] = get_iir_band_coeff(component, iir_idx, band_idx, 2);
coeff[3] = get_iir_band_coeff(component, iir_idx, band_idx, 3);
coeff[4] = get_iir_band_coeff(component, iir_idx, band_idx, 4);
memcpy(ucontrol->value.bytes.data, &coeff[0], params->max);
return 0;
}
static void set_iir_band_coeff(struct snd_soc_component *component,
int iir_idx, int band_idx,
uint32_t value)
{
snd_soc_component_write(component,
(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx),
(value & 0xFF));
snd_soc_component_write(component,
(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx),
(value >> 8) & 0xFF);
snd_soc_component_write(component,
(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx),
(value >> 16) & 0xFF);
/* Mask top 2 bits, 7-8 are reserved */
snd_soc_component_write(component,
(LPASS_CDC_IIR1_COEF_B2_CTL + 64 * iir_idx),
(value >> 24) & 0x3F);
}
static int msm8x16_wcd_put_iir_band_audio_mixer(
struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component =
snd_soc_kcontrol_component(kcontrol);
struct wcd_iir_filter_ctl *ctl =
(struct wcd_iir_filter_ctl *)kcontrol->private_value;
struct soc_bytes_ext *params = &ctl->bytes_ext;
int iir_idx = ctl->iir_idx;
int band_idx = ctl->band_idx;
u32 coeff[BAND_MAX];
memcpy(&coeff[0], ucontrol->value.bytes.data, params->max);
/* Mask top bit it is reserved */
/* Updates addr automatically for each B2 write */
snd_soc_component_write(component,
(LPASS_CDC_IIR1_COEF_B1_CTL + 64 * iir_idx),
(band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
set_iir_band_coeff(component, iir_idx, band_idx, coeff[0]);
set_iir_band_coeff(component, iir_idx, band_idx, coeff[1]);
set_iir_band_coeff(component, iir_idx, band_idx, coeff[2]);
set_iir_band_coeff(component, iir_idx, band_idx, coeff[3]);
set_iir_band_coeff(component, iir_idx, band_idx, coeff[4]);
return 0;
}
static int wcd_iir_filter_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *ucontrol)
{
struct wcd_iir_filter_ctl *ctl =
(struct wcd_iir_filter_ctl *)kcontrol->private_value;
struct soc_bytes_ext *params = &ctl->bytes_ext;
ucontrol->type = SNDRV_CTL_ELEM_TYPE_BYTES;
ucontrol->count = params->max;
return 0;
}
static const struct snd_kcontrol_new msm8916_wcd_digital_snd_controls[] = {
SOC_SINGLE_S8_TLV("RX1 Digital Volume", LPASS_CDC_RX1_VOL_CTL_B2_CTL,
-128, 127, digital_gain),
@@ -322,6 +514,44 @@ static const struct snd_kcontrol_new msm8916_wcd_digital_snd_controls[] = {
SOC_SINGLE("RX1 Mute Switch", LPASS_CDC_RX1_B6_CTL, 0, 1, 0),
SOC_SINGLE("RX2 Mute Switch", LPASS_CDC_RX2_B6_CTL, 0, 1, 0),
SOC_SINGLE("RX3 Mute Switch", LPASS_CDC_RX3_B6_CTL, 0, 1, 0),
SOC_SINGLE("IIR1 Band1 Switch", LPASS_CDC_IIR1_CTL, 0, 1, 0),
SOC_SINGLE("IIR1 Band2 Switch", LPASS_CDC_IIR1_CTL, 1, 1, 0),
SOC_SINGLE("IIR1 Band3 Switch", LPASS_CDC_IIR1_CTL, 2, 1, 0),
SOC_SINGLE("IIR1 Band4 Switch", LPASS_CDC_IIR1_CTL, 3, 1, 0),
SOC_SINGLE("IIR1 Band5 Switch", LPASS_CDC_IIR1_CTL, 4, 1, 0),
SOC_SINGLE("IIR2 Band1 Switch", LPASS_CDC_IIR2_CTL, 0, 1, 0),
SOC_SINGLE("IIR2 Band2 Switch", LPASS_CDC_IIR2_CTL, 1, 1, 0),
SOC_SINGLE("IIR2 Band3 Switch", LPASS_CDC_IIR2_CTL, 2, 1, 0),
SOC_SINGLE("IIR2 Band4 Switch", LPASS_CDC_IIR2_CTL, 3, 1, 0),
SOC_SINGLE("IIR2 Band5 Switch", LPASS_CDC_IIR2_CTL, 4, 1, 0),
WCD_IIR_FILTER_CTL("IIR1 Band1", IIR1, BAND1),
WCD_IIR_FILTER_CTL("IIR1 Band2", IIR1, BAND2),
WCD_IIR_FILTER_CTL("IIR1 Band3", IIR1, BAND3),
WCD_IIR_FILTER_CTL("IIR1 Band4", IIR1, BAND4),
WCD_IIR_FILTER_CTL("IIR1 Band5", IIR1, BAND5),
WCD_IIR_FILTER_CTL("IIR2 Band1", IIR2, BAND1),
WCD_IIR_FILTER_CTL("IIR2 Band2", IIR2, BAND2),
WCD_IIR_FILTER_CTL("IIR2 Band3", IIR2, BAND3),
WCD_IIR_FILTER_CTL("IIR2 Band4", IIR2, BAND4),
WCD_IIR_FILTER_CTL("IIR2 Band5", IIR2, BAND5),
SOC_SINGLE_SX_TLV("IIR1 INP1 Volume", LPASS_CDC_IIR1_GAIN_B1_CTL,
0, -84, 40, digital_gain),
SOC_SINGLE_SX_TLV("IIR1 INP2 Volume", LPASS_CDC_IIR1_GAIN_B2_CTL,
0, -84, 40, digital_gain),
SOC_SINGLE_SX_TLV("IIR1 INP3 Volume", LPASS_CDC_IIR1_GAIN_B3_CTL,
0, -84, 40, digital_gain),
SOC_SINGLE_SX_TLV("IIR1 INP4 Volume", LPASS_CDC_IIR1_GAIN_B4_CTL,
0, -84, 40, digital_gain),
SOC_SINGLE_SX_TLV("IIR2 INP1 Volume", LPASS_CDC_IIR2_GAIN_B1_CTL,
0, -84, 40, digital_gain),
SOC_SINGLE_SX_TLV("IIR2 INP2 Volume", LPASS_CDC_IIR2_GAIN_B2_CTL,
0, -84, 40, digital_gain),
SOC_SINGLE_SX_TLV("IIR2 INP3 Volume", LPASS_CDC_IIR2_GAIN_B3_CTL,
0, -84, 40, digital_gain),
SOC_SINGLE_SX_TLV("IIR2 INP4 Volume", LPASS_CDC_IIR2_GAIN_B4_CTL,
0, -84, 40, digital_gain),
};
static int msm8916_wcd_digital_enable_interpolator(
@@ -448,6 +678,24 @@ static int msm8916_wcd_digital_enable_dmic(struct snd_soc_dapm_widget *w,
return 0;
}
static const char * const iir_inp1_text[] = {
"ZERO", "DEC1", "DEC2", "RX1", "RX2", "RX3"
};
static const struct soc_enum iir1_inp1_mux_enum =
SOC_ENUM_SINGLE(LPASS_CDC_CONN_EQ1_B1_CTL,
0, 6, iir_inp1_text);
static const struct soc_enum iir2_inp1_mux_enum =
SOC_ENUM_SINGLE(LPASS_CDC_CONN_EQ2_B1_CTL,
0, 6, iir_inp1_text);
static const struct snd_kcontrol_new iir1_inp1_mux =
SOC_DAPM_ENUM("IIR1 INP1 Mux", iir1_inp1_mux_enum);
static const struct snd_kcontrol_new iir2_inp1_mux =
SOC_DAPM_ENUM("IIR2 INP1 Mux", iir2_inp1_mux_enum);
static const struct snd_soc_dapm_widget msm8916_wcd_digital_dapm_widgets[] = {
/*RX stuff */
SND_SOC_DAPM_AIF_IN("I2S RX1", NULL, 0, SND_SOC_NOPM, 0, 0),
@@ -534,6 +782,15 @@ static const struct snd_soc_dapm_widget msm8916_wcd_digital_dapm_widgets[] = {
SND_SOC_DAPM_MIC("Digital Mic1", NULL),
SND_SOC_DAPM_MIC("Digital Mic2", NULL),
/* Sidetone */
SND_SOC_DAPM_MUX("IIR1 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir1_inp1_mux),
SND_SOC_DAPM_PGA_E("IIR1", LPASS_CDC_CLK_SD_CTL, 0, 0, NULL, 0,
msm8x16_wcd_codec_set_iir_gain, SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_MUX("IIR2 INP1 MUX", SND_SOC_NOPM, 0, 0, &iir2_inp1_mux),
SND_SOC_DAPM_PGA_E("IIR2", LPASS_CDC_CLK_SD_CTL, 1, 0, NULL, 0,
msm8x16_wcd_codec_set_iir_gain, SND_SOC_DAPM_POST_PMU),
};
static int msm8916_wcd_digital_get_clks(struct platform_device *pdev,
@@ -708,10 +965,14 @@ static const struct snd_soc_dapm_route msm8916_wcd_digital_audio_map[] = {
{"RX1 MIX1 INP1", "RX1", "I2S RX1"},
{"RX1 MIX1 INP1", "RX2", "I2S RX2"},
{"RX1 MIX1 INP1", "RX3", "I2S RX3"},
{"RX1 MIX1 INP1", "IIR1", "IIR1"},
{"RX1 MIX1 INP1", "IIR2", "IIR2"},
{"RX1 MIX1 INP2", "RX1", "I2S RX1"},
{"RX1 MIX1 INP2", "RX2", "I2S RX2"},
{"RX1 MIX1 INP2", "RX3", "I2S RX3"},
{"RX1 MIX1 INP2", "IIR1", "IIR1"},
{"RX1 MIX1 INP2", "IIR2", "IIR2"},
{"RX1 MIX1 INP3", "RX1", "I2S RX1"},
{"RX1 MIX1 INP3", "RX2", "I2S RX2"},
@@ -728,10 +989,14 @@ static const struct snd_soc_dapm_route msm8916_wcd_digital_audio_map[] = {
{"RX2 MIX1 INP1", "RX1", "I2S RX1"},
{"RX2 MIX1 INP1", "RX2", "I2S RX2"},
{"RX2 MIX1 INP1", "RX3", "I2S RX3"},
{"RX2 MIX1 INP1", "IIR1", "IIR1"},
{"RX2 MIX1 INP1", "IIR2", "IIR2"},
{"RX2 MIX1 INP2", "RX1", "I2S RX1"},
{"RX2 MIX1 INP2", "RX2", "I2S RX2"},
{"RX2 MIX1 INP2", "RX3", "I2S RX3"},
{"RX2 MIX1 INP1", "IIR1", "IIR1"},
{"RX2 MIX1 INP1", "IIR2", "IIR2"},
{"RX2 MIX1 INP3", "RX1", "I2S RX1"},
{"RX2 MIX1 INP3", "RX2", "I2S RX2"},
@@ -748,10 +1013,27 @@ static const struct snd_soc_dapm_route msm8916_wcd_digital_audio_map[] = {
{"RX3 MIX1 INP1", "RX1", "I2S RX1"},
{"RX3 MIX1 INP1", "RX2", "I2S RX2"},
{"RX3 MIX1 INP1", "RX3", "I2S RX3"},
{"RX3 MIX1 INP1", "IIR1", "IIR1"},
{"RX3 MIX1 INP1", "IIR2", "IIR2"},
{"RX3 MIX1 INP2", "RX1", "I2S RX1"},
{"RX3 MIX1 INP2", "RX2", "I2S RX2"},
{"RX3 MIX1 INP2", "RX3", "I2S RX3"},
{"RX3 MIX1 INP2", "IIR1", "IIR1"},
{"RX3 MIX1 INP2", "IIR2", "IIR2"},
{"RX1 MIX2 INP1", "IIR1", "IIR1"},
{"RX2 MIX2 INP1", "IIR1", "IIR1"},
{"RX1 MIX2 INP1", "IIR2", "IIR2"},
{"RX2 MIX2 INP1", "IIR2", "IIR2"},
{"IIR1", NULL, "IIR1 INP1 MUX"},
{"IIR1 INP1 MUX", "DEC1", "DEC1 MUX"},
{"IIR1 INP1 MUX", "DEC2", "DEC2 MUX"},
{"IIR2", NULL, "IIR2 INP1 MUX"},
{"IIR2 INP1 MUX", "DEC1", "DEC1 MUX"},
{"IIR2 INP1 MUX", "DEC2", "DEC2 MUX"},
{"RX3 MIX1 INP3", "RX1", "I2S RX1"},
{"RX3 MIX1 INP3", "RX2", "I2S RX2"},

파일 보기

@@ -828,6 +828,24 @@ static int nau8822_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_component *component = dai->component;
struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component);
int val_len = 0, val_rate = 0;
unsigned int ctrl_val, bclk_fs, bclk_div;
/* make BCLK and LRC divide configuration if the codec as master. */
snd_soc_component_read(component, NAU8822_REG_CLOCKING, &ctrl_val);
if (ctrl_val & NAU8822_CLK_MASTER) {
/* get the bclk and fs ratio */
bclk_fs = snd_soc_params_to_bclk(params) / params_rate(params);
if (bclk_fs <= 32)
bclk_div = NAU8822_BCLKDIV_8;
else if (bclk_fs <= 64)
bclk_div = NAU8822_BCLKDIV_4;
else if (bclk_fs <= 128)
bclk_div = NAU8822_BCLKDIV_2;
else
return -EINVAL;
snd_soc_component_update_bits(component, NAU8822_REG_CLOCKING,
NAU8822_BCLKSEL_MASK, bclk_div);
}
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:

파일 보기

@@ -107,10 +107,17 @@
/* NAU8822_REG_CLOCKING (0x6) */
#define NAU8822_CLKIOEN_MASK 0x1
#define NAU8822_CLK_MASTER 0x1
#define NAU8822_CLK_SLAVE 0x0
#define NAU8822_MCLKSEL_SFT 5
#define NAU8822_MCLKSEL_MASK (0x7 << 5)
#define NAU8822_BCLKSEL_SFT 2
#define NAU8822_BCLKSEL_MASK (0x7 << 2)
#define NAU8822_BCLKDIV_1 (0x0 << 2)
#define NAU8822_BCLKDIV_2 (0x1 << 2)
#define NAU8822_BCLKDIV_4 (0x2 << 2)
#define NAU8822_BCLKDIV_8 (0x3 << 2)
#define NAU8822_BCLKDIV_16 (0x4 << 2)
#define NAU8822_CLKM_MASK (0x1 << 8)
#define NAU8822_CLKM_MCLK (0x0 << 8)
#define NAU8822_CLKM_PLL (0x1 << 8)

파일 보기

@@ -53,6 +53,9 @@ struct pcm3168a_priv {
unsigned long sysclk;
unsigned int adc_fmt;
unsigned int dac_fmt;
int tdm_slots;
u32 tdm_mask[2];
int slot_width;
};
static const char *const pcm3168a_roll_off[] = { "Sharp", "Slow" };
@@ -384,6 +387,47 @@ static int pcm3168a_set_dai_fmt_adc(struct snd_soc_dai *dai,
return pcm3168a_set_dai_fmt(dai, format, false);
}
static int pcm3168a_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
unsigned int rx_mask, int slots,
int slot_width)
{
struct snd_soc_component *component = dai->component;
struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
if (tx_mask >= (1<<slots) || rx_mask >= (1<<slots)) {
dev_err(component->dev,
"Bad tdm mask tx: 0x%08x rx: 0x%08x slots %d\n",
tx_mask, rx_mask, slots);
return -EINVAL;
}
if (slot_width &&
(slot_width != 16 && slot_width != 24 && slot_width != 32 )) {
dev_err(component->dev, "Unsupported slot_width %d\n",
slot_width);
return -EINVAL;
}
if (pcm3168a->tdm_slots && pcm3168a->tdm_slots != slots) {
dev_err(component->dev, "Not matching slots %d vs %d\n",
pcm3168a->tdm_slots, slots);
return -EINVAL;
}
if (pcm3168a->slot_width && pcm3168a->slot_width != slot_width) {
dev_err(component->dev, "Not matching slot_width %d vs %d\n",
pcm3168a->slot_width, slot_width);
return -EINVAL;
}
pcm3168a->tdm_slots = slots;
pcm3168a->slot_width = slot_width;
pcm3168a->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = tx_mask;
pcm3168a->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = rx_mask;
return 0;
}
static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -393,11 +437,10 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
bool tx, master_mode;
u32 val, mask, shift, reg;
unsigned int rate, fmt, ratio, max_ratio;
unsigned int chan;
int i, min_frame_size;
unsigned int tdm_slots;
int i, slot_width;
rate = params_rate(params);
chan = params_channels(params);
ratio = pcm3168a->sysclk / rate;
@@ -428,30 +471,46 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
min_frame_size = params_width(params) * 2;
switch (min_frame_size) {
case 32:
if (pcm3168a->slot_width)
slot_width = pcm3168a->slot_width;
else
slot_width = params_width(params);
switch (slot_width) {
case 16:
if (master_mode || (fmt != PCM3168A_FMT_RIGHT_J)) {
dev_err(component->dev, "32-bit frames are supported only for slave mode using right justified\n");
dev_err(component->dev, "16-bit slots are supported only for slave mode using right justified\n");
return -EINVAL;
}
fmt = PCM3168A_FMT_RIGHT_J_16;
break;
case 48:
case 24:
if (master_mode || (fmt & PCM3168A_FMT_DSP_MASK)) {
dev_err(component->dev, "48-bit frames not supported in master mode, or slave mode using DSP\n");
dev_err(component->dev, "24-bit slots not supported in master mode, or slave mode using DSP\n");
return -EINVAL;
}
break;
case 64:
case 32:
break;
default:
dev_err(component->dev, "unsupported frame size: %d\n", min_frame_size);
dev_err(component->dev, "unsupported frame size: %d\n", slot_width);
return -EINVAL;
}
/* for TDM */
if (chan > 2) {
if (pcm3168a->tdm_slots)
tdm_slots = pcm3168a->tdm_slots;
else
tdm_slots = params_channels(params);
/*
* Switch the codec to TDM mode when more than 2 TDM slots are needed
* for the stream.
* If pcm3168a->tdm_slots is not set or set to more than 2 (8/6 usually)
* then DIN1/DOUT1 is used in TDM mode.
* If pcm3168a->tdm_slots is set to 2 then DIN1/2/3/4 and DOUT1/2/3 is
* used in normal mode, no need to switch to TDM modes.
*/
if (tdm_slots > 2) {
switch (fmt) {
case PCM3168A_FMT_I2S:
case PCM3168A_FMT_DSP_A:
@@ -551,14 +610,16 @@ static const struct snd_soc_dai_ops pcm3168a_dac_dai_ops = {
.set_fmt = pcm3168a_set_dai_fmt_dac,
.set_sysclk = pcm3168a_set_dai_sysclk,
.hw_params = pcm3168a_hw_params,
.digital_mute = pcm3168a_digital_mute
.digital_mute = pcm3168a_digital_mute,
.set_tdm_slot = pcm3168a_set_tdm_slot,
};
static const struct snd_soc_dai_ops pcm3168a_adc_dai_ops = {
.startup = pcm3168a_startup,
.set_fmt = pcm3168a_set_dai_fmt_adc,
.set_sysclk = pcm3168a_set_dai_sysclk,
.hw_params = pcm3168a_hw_params
.hw_params = pcm3168a_hw_params,
.set_tdm_slot = pcm3168a_set_tdm_slot,
};
static struct snd_soc_dai_driver pcm3168a_dais[] = {

2244
sound/soc/codecs/rt1011.c Normal file

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다. Load Diff

672
sound/soc/codecs/rt1011.h Normal file
파일 보기

@@ -0,0 +1,672 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* rt1011.h -- RT1011 ALSA SoC amplifier component driver header
*
* Copyright(c) 2019 Realtek Semiconductor Corp.
*/
#ifndef _RT1011_H_
#define _RT1011_H_
#define RT1011_DEVICE_ID_NUM 0x1011
#define RT1011_RESET 0x0000
#define RT1011_CLK_1 0x0002
#define RT1011_CLK_2 0x0004
#define RT1011_CLK_3 0x0006
#define RT1011_CLK_4 0x0008
#define RT1011_PLL_1 0x000a
#define RT1011_PLL_2 0x000c
#define RT1011_SRC_1 0x000e
#define RT1011_SRC_2 0x0010
#define RT1011_SRC_3 0x0012
#define RT1011_CLK_DET 0x0020
#define RT1011_SIL_DET 0x0022
#define RT1011_PRIV_INDEX 0x006a
#define RT1011_PRIV_DATA 0x006c
#define RT1011_CUSTOMER_ID 0x0076
#define RT1011_FM_VER 0x0078
#define RT1011_VERSION_ID 0x007a
#define RT1011_VENDOR_ID 0x007c
#define RT1011_DEVICE_ID 0x007d
#define RT1011_DUM_RW_0 0x00f0
#define RT1011_DUM_YUN 0x00f2
#define RT1011_DUM_RW_1 0x00f3
#define RT1011_DUM_RO 0x00f4
#define RT1011_MAN_I2C_DEV 0x0100
#define RT1011_DAC_SET_1 0x0102
#define RT1011_DAC_SET_2 0x0104
#define RT1011_DAC_SET_3 0x0106
#define RT1011_ADC_SET 0x0107
#define RT1011_ADC_SET_1 0x0108
#define RT1011_ADC_SET_2 0x010a
#define RT1011_ADC_SET_3 0x010c
#define RT1011_ADC_SET_4 0x010e
#define RT1011_ADC_SET_5 0x0110
#define RT1011_TDM_TOTAL_SET 0x0111
#define RT1011_TDM1_SET_TCON 0x0112
#define RT1011_TDM1_SET_1 0x0114
#define RT1011_TDM1_SET_2 0x0116
#define RT1011_TDM1_SET_3 0x0118
#define RT1011_TDM1_SET_4 0x011a
#define RT1011_TDM1_SET_5 0x011c
#define RT1011_TDM2_SET_1 0x011e
#define RT1011_TDM2_SET_2 0x0120
#define RT1011_TDM2_SET_3 0x0122
#define RT1011_TDM2_SET_4 0x0124
#define RT1011_TDM2_SET_5 0x0126
#define RT1011_PWM_CAL 0x0200
#define RT1011_MIXER_1 0x0300
#define RT1011_MIXER_2 0x0302
#define RT1011_ADRC_LIMIT 0x0310
#define RT1011_A_PRO 0x0311
#define RT1011_A_TIMING_1 0x0313
#define RT1011_A_TIMING_2 0x0314
#define RT1011_A_TEMP_SEN 0x0316
#define RT1011_SPK_VOL_DET_1 0x0319
#define RT1011_SPK_VOL_DET_2 0x031a
#define RT1011_SPK_VOL_TEST_OUT 0x031b
#define RT1011_VBAT_VOL_DET_1 0x031c
#define RT1011_VBAT_VOL_DET_2 0x031d
#define RT1011_VBAT_TEST_OUT_1 0x031e
#define RT1011_VBAT_TEST_OUT_2 0x031f
#define RT1011_VBAT_PROTECTION 0x0320
#define RT1011_VBAT_DET 0x0321
#define RT1011_POWER_1 0x0322
#define RT1011_POWER_2 0x0324
#define RT1011_POWER_3 0x0326
#define RT1011_POWER_4 0x0328
#define RT1011_POWER_5 0x0329
#define RT1011_POWER_6 0x032a
#define RT1011_POWER_7 0x032b
#define RT1011_POWER_8 0x032c
#define RT1011_POWER_9 0x032d
#define RT1011_CLASS_D_POS 0x032e
#define RT1011_BOOST_CON_1 0x0330
#define RT1011_BOOST_CON_2 0x0332
#define RT1011_ANALOG_CTRL 0x0334
#define RT1011_POWER_SEQ 0x0340
#define RT1011_SHORT_CIRCUIT_DET_1 0x0508
#define RT1011_SHORT_CIRCUIT_DET_2 0x050a
#define RT1011_SPK_TEMP_PROTECT_0 0x050c
#define RT1011_SPK_TEMP_PROTECT_1 0x050d
#define RT1011_SPK_TEMP_PROTECT_2 0x050e
#define RT1011_SPK_TEMP_PROTECT_3 0x050f
#define RT1011_SPK_TEMP_PROTECT_4 0x0510
#define RT1011_SPK_TEMP_PROTECT_5 0x0511
#define RT1011_SPK_TEMP_PROTECT_6 0x0512
#define RT1011_SPK_TEMP_PROTECT_7 0x0516
#define RT1011_SPK_TEMP_PROTECT_8 0x0517
#define RT1011_SPK_TEMP_PROTECT_9 0x0518
#define RT1011_SPK_PRO_DC_DET_1 0x0519
#define RT1011_SPK_PRO_DC_DET_2 0x051a
#define RT1011_SPK_PRO_DC_DET_3 0x051b
#define RT1011_SPK_PRO_DC_DET_4 0x051c
#define RT1011_SPK_PRO_DC_DET_5 0x051d
#define RT1011_SPK_PRO_DC_DET_6 0x051e
#define RT1011_SPK_PRO_DC_DET_7 0x051f
#define RT1011_SPK_PRO_DC_DET_8 0x0520
#define RT1011_SPL_1 0x0521
#define RT1011_SPL_2 0x0522
#define RT1011_SPL_3 0x0524
#define RT1011_SPL_4 0x0526
#define RT1011_THER_FOLD_BACK_1 0x0528
#define RT1011_THER_FOLD_BACK_2 0x052a
#define RT1011_EXCUR_PROTECT_1 0x0530
#define RT1011_EXCUR_PROTECT_2 0x0532
#define RT1011_EXCUR_PROTECT_3 0x0534
#define RT1011_EXCUR_PROTECT_4 0x0535
#define RT1011_BAT_GAIN_1 0x0536
#define RT1011_BAT_GAIN_2 0x0538
#define RT1011_BAT_GAIN_3 0x053a
#define RT1011_BAT_GAIN_4 0x053c
#define RT1011_BAT_GAIN_5 0x053d
#define RT1011_BAT_GAIN_6 0x053e
#define RT1011_BAT_GAIN_7 0x053f
#define RT1011_BAT_GAIN_8 0x0540
#define RT1011_BAT_GAIN_9 0x0541
#define RT1011_BAT_GAIN_10 0x0542
#define RT1011_BAT_GAIN_11 0x0543
#define RT1011_BAT_RT_THMAX_1 0x0544
#define RT1011_BAT_RT_THMAX_2 0x0545
#define RT1011_BAT_RT_THMAX_3 0x0546
#define RT1011_BAT_RT_THMAX_4 0x0547
#define RT1011_BAT_RT_THMAX_5 0x0548
#define RT1011_BAT_RT_THMAX_6 0x0549
#define RT1011_BAT_RT_THMAX_7 0x054a
#define RT1011_BAT_RT_THMAX_8 0x054b
#define RT1011_BAT_RT_THMAX_9 0x054c
#define RT1011_BAT_RT_THMAX_10 0x054d
#define RT1011_BAT_RT_THMAX_11 0x054e
#define RT1011_BAT_RT_THMAX_12 0x054f
#define RT1011_SPREAD_SPECTURM 0x0568
#define RT1011_PRO_GAIN_MODE 0x056a
#define RT1011_RT_DRC_CROSS 0x0600
#define RT1011_RT_DRC_HB_1 0x0611
#define RT1011_RT_DRC_HB_2 0x0612
#define RT1011_RT_DRC_HB_3 0x0613
#define RT1011_RT_DRC_HB_4 0x0614
#define RT1011_RT_DRC_HB_5 0x0615
#define RT1011_RT_DRC_HB_6 0x0616
#define RT1011_RT_DRC_HB_7 0x0617
#define RT1011_RT_DRC_HB_8 0x0618
#define RT1011_RT_DRC_BB_1 0x0621
#define RT1011_RT_DRC_BB_2 0x0622
#define RT1011_RT_DRC_BB_3 0x0623
#define RT1011_RT_DRC_BB_4 0x0624
#define RT1011_RT_DRC_BB_5 0x0625
#define RT1011_RT_DRC_BB_6 0x0626
#define RT1011_RT_DRC_BB_7 0x0627
#define RT1011_RT_DRC_BB_8 0x0628
#define RT1011_RT_DRC_POS_1 0x0631
#define RT1011_RT_DRC_POS_2 0x0632
#define RT1011_RT_DRC_POS_3 0x0633
#define RT1011_RT_DRC_POS_4 0x0634
#define RT1011_RT_DRC_POS_5 0x0635
#define RT1011_RT_DRC_POS_6 0x0636
#define RT1011_RT_DRC_POS_7 0x0637
#define RT1011_RT_DRC_POS_8 0x0638
#define RT1011_CROSS_BQ_SET_1 0x0702
#define RT1011_CROSS_BQ_SET_2 0x0704
#define RT1011_BQ_SET_0 0x0706
#define RT1011_BQ_SET_1 0x0708
#define RT1011_BQ_SET_2 0x070a
#define RT1011_BQ_PRE_GAIN_28_16 0x0710
#define RT1011_BQ_PRE_GAIN_15_0 0x0711
#define RT1011_BQ_POST_GAIN_28_16 0x0712
#define RT1011_BQ_POST_GAIN_15_0 0x0713
#define RT1011_BQ_H0_28_16 0x0720
#define RT1011_BQ_A2_15_0 0x0729
#define RT1011_BQ_1_H0_28_16 0x0730
#define RT1011_BQ_1_A2_15_0 0x0739
#define RT1011_BQ_2_H0_28_16 0x0740
#define RT1011_BQ_2_A2_15_0 0x0749
#define RT1011_BQ_3_H0_28_16 0x0750
#define RT1011_BQ_3_A2_15_0 0x0759
#define RT1011_BQ_4_H0_28_16 0x0760
#define RT1011_BQ_4_A2_15_0 0x0769
#define RT1011_BQ_5_H0_28_16 0x0770
#define RT1011_BQ_5_A2_15_0 0x0779
#define RT1011_BQ_6_H0_28_16 0x0780
#define RT1011_BQ_6_A2_15_0 0x0789
#define RT1011_BQ_7_H0_28_16 0x0790
#define RT1011_BQ_7_A2_15_0 0x0799
#define RT1011_BQ_8_H0_28_16 0x07a0
#define RT1011_BQ_8_A2_15_0 0x07a9
#define RT1011_BQ_9_H0_28_16 0x07b0
#define RT1011_BQ_9_A2_15_0 0x07b9
#define RT1011_BQ_10_H0_28_16 0x07c0
#define RT1011_BQ_10_A2_15_0 0x07c9
#define RT1011_TEST_PAD_STATUS 0x1000
#define RT1011_SYSTEM_RESET_1 0x1007
#define RT1011_SYSTEM_RESET_2 0x1008
#define RT1011_SYSTEM_RESET_3 0x1009
#define RT1011_ADCDAT_OUT_SOURCE 0x100D
#define RT1011_PLL_INTERNAL_SET 0x1010
#define RT1011_TEST_OUT_1 0x1020
#define RT1011_TEST_OUT_3 0x1024
#define RT1011_DC_CALIB_CLASSD_1 0x1200
#define RT1011_DC_CALIB_CLASSD_2 0x1202
#define RT1011_DC_CALIB_CLASSD_3 0x1204
#define RT1011_DC_CALIB_CLASSD_5 0x1208
#define RT1011_DC_CALIB_CLASSD_6 0x120a
#define RT1011_DC_CALIB_CLASSD_7 0x120c
#define RT1011_DC_CALIB_CLASSD_8 0x120e
#define RT1011_DC_CALIB_CLASSD_10 0x1212
#define RT1011_CLASSD_INTERNAL_SET_1 0x1300
#define RT1011_CLASSD_INTERNAL_SET_3 0x1304
#define RT1011_CLASSD_INTERNAL_SET_8 0x130c
#define RT1011_VREF_LV_1 0x131a
#define RT1011_SMART_BOOST_TIMING_1 0x1322
#define RT1011_SMART_BOOST_TIMING_36 0x1349
#define RT1011_SINE_GEN_REG_1 0x1500
#define RT1011_SINE_GEN_REG_2 0x1502
#define RT1011_SINE_GEN_REG_3 0x1504
#define RT1011_STP_INITIAL_RS_TEMP 0x1510
#define RT1011_STP_CALIB_RS_TEMP 0x152a
#define RT1011_INIT_RECIPROCAL_REG_24_16 0x1538
#define RT1011_INIT_RECIPROCAL_REG_15_0 0x1539
#define RT1011_STP_ALPHA_RECIPROCAL_MSB 0x153e
#define RT1011_SPK_RESISTANCE_1 0x1544
#define RT1011_SPK_RESISTANCE_2 0x1546
#define RT1011_SPK_THERMAL 0x1548
#define RT1011_STP_OTP_TH 0x1552
#define RT1011_ALC_BK_GAIN_O 0x1554
#define RT1011_ALC_BK_GAIN_O_PRE 0x1556
#define RT1011_SPK_DC_O_23_16 0x155a
#define RT1011_SPK_DC_O_15_0 0x155c
#define RT1011_INIT_RECIPROCAL_SYN_24_16 0x1560
#define RT1011_INIT_RECIPROCAL_SYN_15_0 0x1562
#define RT1011_STP_BQ_1_A1_L_28_16 0x1570
#define RT1011_STP_BQ_1_H0_R_15_0 0x1583
#define RT1011_STP_BQ_2_A1_L_28_16 0x1590
#define RT1011_SPK_EXCURSION_23_16 0x15be
#define RT1011_SPK_EXCURSION_15_0 0x15bf
#define RT1011_SEP_MAIN_OUT_23_16 0x15c0
#define RT1011_SEP_MAIN_OUT_15_0 0x15c1
#define RT1011_SEP_RE_REG_15_0 0x15f9
#define RT1011_DRC_CF_PARAMS_1 0x1600
#define RT1011_DRC_CF_PARAMS_12 0x160b
#define RT1011_ALC_DRC_HB_INTERNAL_1 0x1611
#define RT1011_ALC_DRC_HB_INTERNAL_5 0x1615
#define RT1011_ALC_DRC_HB_INTERNAL_6 0x1616
#define RT1011_ALC_DRC_HB_INTERNAL_7 0x1617
#define RT1011_ALC_DRC_BB_INTERNAL_1 0x1621
#define RT1011_ALC_DRC_BB_INTERNAL_5 0x1625
#define RT1011_ALC_DRC_BB_INTERNAL_6 0x1626
#define RT1011_ALC_DRC_BB_INTERNAL_7 0x1627
#define RT1011_ALC_DRC_POS_INTERNAL_1 0x1631
#define RT1011_ALC_DRC_POS_INTERNAL_5 0x1635
#define RT1011_ALC_DRC_POS_INTERNAL_6 0x1636
#define RT1011_ALC_DRC_POS_INTERNAL_7 0x1637
#define RT1011_ALC_DRC_POS_INTERNAL_8 0x1638
#define RT1011_ALC_DRC_POS_INTERNAL_9 0x163a
#define RT1011_ALC_DRC_POS_INTERNAL_10 0x163c
#define RT1011_ALC_DRC_POS_INTERNAL_11 0x163e
#define RT1011_BQ_1_PARAMS_CHECK_5 0x1648
#define RT1011_BQ_2_PARAMS_CHECK_1 0x1650
#define RT1011_BQ_2_PARAMS_CHECK_5 0x1658
#define RT1011_BQ_3_PARAMS_CHECK_1 0x1660
#define RT1011_BQ_3_PARAMS_CHECK_5 0x1668
#define RT1011_BQ_4_PARAMS_CHECK_1 0x1670
#define RT1011_BQ_4_PARAMS_CHECK_5 0x1678
#define RT1011_BQ_5_PARAMS_CHECK_1 0x1680
#define RT1011_BQ_5_PARAMS_CHECK_5 0x1688
#define RT1011_BQ_6_PARAMS_CHECK_1 0x1690
#define RT1011_BQ_6_PARAMS_CHECK_5 0x1698
#define RT1011_BQ_7_PARAMS_CHECK_1 0x1700
#define RT1011_BQ_7_PARAMS_CHECK_5 0x1708
#define RT1011_BQ_8_PARAMS_CHECK_1 0x1710
#define RT1011_BQ_8_PARAMS_CHECK_5 0x1718
#define RT1011_BQ_9_PARAMS_CHECK_1 0x1720
#define RT1011_BQ_9_PARAMS_CHECK_5 0x1728
#define RT1011_BQ_10_PARAMS_CHECK_1 0x1730
#define RT1011_BQ_10_PARAMS_CHECK_5 0x1738
#define RT1011_IRQ_1 0x173a
#define RT1011_PART_NUMBER_EFUSE 0x173e
#define RT1011_EFUSE_CONTROL_1 0x17bb
#define RT1011_EFUSE_CONTROL_2 0x17bd
#define RT1011_EFUSE_MATCH_DONE 0x17cb
#define RT1011_EFUSE_ADC_OFFSET_18_16 0x17e5
#define RT1011_EFUSE_ADC_OFFSET_15_0 0x17e7
#define RT1011_EFUSE_DAC_OFFSET_G0_20_16 0x17e9
#define RT1011_EFUSE_DAC_OFFSET_G0_15_0 0x17eb
#define RT1011_EFUSE_DAC_OFFSET_G1_20_16 0x17ed
#define RT1011_EFUSE_DAC_OFFSET_G1_15_0 0x17ef
#define RT1011_EFUSE_READ_R0_3_15_0 0x1803
#define RT1011_MAX_REG 0x1803
#define RT1011_REG_DISP_LEN 23
/* CLOCK-2 (0x0004) */
#define RT1011_FS_SYS_PRE_MASK (0x3 << 14)
#define RT1011_FS_SYS_PRE_SFT 14
#define RT1011_FS_SYS_PRE_MCLK (0x0 << 14)
#define RT1011_FS_SYS_PRE_BCLK (0x1 << 14)
#define RT1011_FS_SYS_PRE_PLL1 (0x2 << 14)
#define RT1011_FS_SYS_PRE_RCCLK (0x3 << 14)
#define RT1011_PLL1_SRC_MASK (0x1 << 13)
#define RT1011_PLL1_SRC_SFT 13
#define RT1011_PLL1_SRC_PLL2 (0x0 << 13)
#define RT1011_PLL1_SRC_BCLK (0x1 << 13)
#define RT1011_PLL2_SRC_MASK (0x1 << 12)
#define RT1011_PLL2_SRC_SFT 12
#define RT1011_PLL2_SRC_MCLK (0x0 << 12)
#define RT1011_PLL2_SRC_RCCLK (0x1 << 12)
#define RT1011_PLL2_SRC_DIV_MASK (0x3 << 10)
#define RT1011_PLL2_SRC_DIV_SFT 10
#define RT1011_SRCIN_DIV_MASK (0x3 << 8)
#define RT1011_SRCIN_DIV_SFT 8
#define RT1011_FS_SYS_DIV_MASK (0x7 << 4)
#define RT1011_FS_SYS_DIV_SFT 4
/* PLL-1 (0x000a) */
#define RT1011_PLL1_QM_MASK (0xf << 12)
#define RT1011_PLL1_QM_SFT 12
#define RT1011_PLL1_BPM_MASK (0x1 << 11)
#define RT1011_PLL1_BPM_SFT 11
#define RT1011_PLL1_BPM (0x1 << 11)
#define RT1011_PLL1_QN_MASK (0x1ff << 0)
#define RT1011_PLL1_QN_SFT 0
/* PLL-2 (0x000c) */
#define RT1011_PLL2_BPK_MASK (0x1 << 5)
#define RT1011_PLL2_BPK_SFT 5
#define RT1011_PLL2_BPK (0x1 << 5)
#define RT1011_PLL2_QK_MASK (0x1f << 0)
#define RT1011_PLL2_QK_SFT 0
/* Clock Detect (0x0020) */
#define RT1011_EN_MCLK_DET_MASK (0x1 << 15)
#define RT1011_EN_MCLK_DET_SFT 15
#define RT1011_EN_MCLK_DET (0x1 << 15)
/* DAC Setting-2 (0x0104) */
#define RT1011_EN_CKGEN_DAC_MASK (0x1 << 13)
#define RT1011_EN_CKGEN_DAC_SFT 13
#define RT1011_EN_CKGEN_DAC (0x1 << 13)
/* DAC Setting-3 (0x0106) */
#define RT1011_DA_MUTE_EN_MASK (0x1 << 15)
#define RT1011_DA_MUTE_EN_SFT 15
/* ADC Setting-5 (0x0110) */
#define RT1011_AD_EN_CKGEN_ADC_MASK (0x1 << 9)
#define RT1011_AD_EN_CKGEN_ADC_SFT 9
#define RT1011_AD_EN_CKGEN_ADC (0x1 << 9)
/* TDM Total Setting (0x0111) */
#define RT1011_I2S_TDM_MS_MASK (0x1 << 14)
#define RT1011_I2S_TDM_MS_SFT 14
#define RT1011_I2S_TDM_MS_S (0x0 << 14)
#define RT1011_I2S_TDM_MS_M (0x1 << 14)
#define RT1011_I2S_TX_DL_MASK (0x7 << 8)
#define RT1011_I2S_TX_DL_SFT 8
#define RT1011_I2S_TX_DL_16B (0x0 << 8)
#define RT1011_I2S_TX_DL_20B (0x1 << 8)
#define RT1011_I2S_TX_DL_24B (0x2 << 8)
#define RT1011_I2S_TX_DL_32B (0x3 << 8)
#define RT1011_I2S_TX_DL_8B (0x4 << 8)
#define RT1011_I2S_RX_DL_MASK (0x7 << 5)
#define RT1011_I2S_RX_DL_SFT 5
#define RT1011_I2S_RX_DL_16B (0x0 << 5)
#define RT1011_I2S_RX_DL_20B (0x1 << 5)
#define RT1011_I2S_RX_DL_24B (0x2 << 5)
#define RT1011_I2S_RX_DL_32B (0x3 << 5)
#define RT1011_I2S_RX_DL_8B (0x4 << 5)
#define RT1011_ADCDAT1_PIN_CONFIG (0x1 << 4)
#define RT1011_ADCDAT1_OUTPUT (0x0 << 4)
#define RT1011_ADCDAT1_INPUT (0x1 << 4)
#define RT1011_ADCDAT2_PIN_CONFIG (0x1 << 3)
#define RT1011_ADCDAT2_OUTPUT (0x0 << 3)
#define RT1011_ADCDAT2_INPUT (0x1 << 3)
#define RT1011_I2S_TDM_DF_MASK (0x7 << 0)
#define RT1011_I2S_TDM_DF_SFT 0
#define RT1011_I2S_TDM_DF_I2S (0x0)
#define RT1011_I2S_TDM_DF_LEFT (0x1)
#define RT1011_I2S_TDM_DF_PCM_A (0x2)
#define RT1011_I2S_TDM_DF_PCM_B (0x3)
#define RT1011_I2S_TDM_DF_PCM_A_N (0x6)
#define RT1011_I2S_TDM_DF_PCM_B_N (0x7)
/* TDM_tcon Setting (0x0112) */
#define RT1011_TCON_DF_MASK (0x7 << 13)
#define RT1011_TCON_DF_SFT 13
#define RT1011_TCON_DF_I2S (0x0 << 13)
#define RT1011_TCON_DF_LEFT (0x1 << 13)
#define RT1011_TCON_DF_PCM_A (0x2 << 13)
#define RT1011_TCON_DF_PCM_B (0x3 << 13)
#define RT1011_TCON_DF_PCM_A_N (0x6 << 13)
#define RT1011_TCON_DF_PCM_B_N (0x7 << 13)
#define RT1011_TCON_BCLK_SEL_MASK (0x3 << 10)
#define RT1011_TCON_BCLK_SEL_SFT 10
#define RT1011_TCON_BCLK_SEL_32FS (0x0 << 10)
#define RT1011_TCON_BCLK_SEL_64FS (0x1 << 10)
#define RT1011_TCON_BCLK_SEL_128FS (0x2 << 10)
#define RT1011_TCON_BCLK_SEL_256FS (0x3 << 10)
#define RT1011_TCON_CH_LEN_MASK (0x3 << 5)
#define RT1011_TCON_CH_LEN_SFT 5
#define RT1011_TCON_CH_LEN_16B (0x0 << 5)
#define RT1011_TCON_CH_LEN_20B (0x1 << 5)
#define RT1011_TCON_CH_LEN_24B (0x2 << 5)
#define RT1011_TCON_CH_LEN_32B (0x3 << 5)
#define RT1011_TCON_BCLK_MST_MASK (0x1 << 4)
#define RT1011_TCON_BCLK_MST_SFT 4
#define RT1011_TCON_BCLK_MST_INV (0x1 << 4)
/* TDM1 Setting-1 (0x0114) */
#define RT1011_TDM_INV_BCLK_MASK (0x1 << 15)
#define RT1011_TDM_INV_BCLK_SFT 15
#define RT1011_TDM_INV_BCLK (0x1 << 15)
#define RT1011_I2S_CH_TX_MASK (0x3 << 10)
#define RT1011_I2S_CH_TX_SFT 10
#define RT1011_I2S_TX_2CH (0x0 << 10)
#define RT1011_I2S_TX_4CH (0x1 << 10)
#define RT1011_I2S_TX_6CH (0x2 << 10)
#define RT1011_I2S_TX_8CH (0x3 << 10)
#define RT1011_I2S_CH_RX_MASK (0x3 << 8)
#define RT1011_I2S_CH_RX_SFT 8
#define RT1011_I2S_RX_2CH (0x0 << 8)
#define RT1011_I2S_RX_4CH (0x1 << 8)
#define RT1011_I2S_RX_6CH (0x2 << 8)
#define RT1011_I2S_RX_8CH (0x3 << 8)
#define RT1011_I2S_LR_CH_SEL_MASK (0x1 << 7)
#define RT1011_I2S_LR_CH_SEL_SFT 7
#define RT1011_I2S_LEFT_CH_SEL (0x0 << 7)
#define RT1011_I2S_RIGHT_CH_SEL (0x1 << 7)
#define RT1011_I2S_CH_TX_LEN_MASK (0x7 << 4)
#define RT1011_I2S_CH_TX_LEN_SFT 4
#define RT1011_I2S_CH_TX_LEN_16B (0x0 << 4)
#define RT1011_I2S_CH_TX_LEN_20B (0x1 << 4)
#define RT1011_I2S_CH_TX_LEN_24B (0x2 << 4)
#define RT1011_I2S_CH_TX_LEN_32B (0x3 << 4)
#define RT1011_I2S_CH_TX_LEN_8B (0x4 << 4)
#define RT1011_I2S_CH_RX_LEN_MASK (0x7 << 0)
#define RT1011_I2S_CH_RX_LEN_SFT 0
#define RT1011_I2S_CH_RX_LEN_16B (0x0 << 0)
#define RT1011_I2S_CH_RX_LEN_20B (0x1 << 0)
#define RT1011_I2S_CH_RX_LEN_24B (0x2 << 0)
#define RT1011_I2S_CH_RX_LEN_32B (0x3 << 0)
#define RT1011_I2S_CH_RX_LEN_8B (0x4 << 0)
/* TDM1 Setting-2 (0x0116) */
#define RT1011_TDM_I2S_DOCK_ADCDAT_LEN_1_MASK (0x7 << 13)
#define RT1011_TDM_I2S_DOCK_ADCDAT_2CH (0x1 << 13)
#define RT1011_TDM_I2S_DOCK_ADCDAT_4CH (0x3 << 13)
#define RT1011_TDM_I2S_DOCK_ADCDAT_6CH (0x5 << 13)
#define RT1011_TDM_I2S_DOCK_ADCDAT_8CH (0x7 << 13)
#define RT1011_TDM_I2S_DOCK_EN_1_MASK (0x1 << 3)
#define RT1011_TDM_I2S_DOCK_EN_1_SFT 3
#define RT1011_TDM_I2S_DOCK_EN_1 (0x1 << 3)
/* TDM2 Setting-2 (0x0120) */
#define RT1011_TDM_I2S_DOCK_ADCDAT_LEN_2_MASK (0x7 << 13)
#define RT1011_TDM_I2S_DOCK_EN_2_MASK (0x1 << 3)
#define RT1011_TDM_I2S_DOCK_EN_2_SFT 3
#define RT1011_TDM_I2S_DOCK_EN_2 (0x1 << 3)
/* MIXER 1 (0x0300) */
#define RT1011_MIXER_MUTE_MIX_I_MASK (0x1 << 15)
#define RT1011_MIXER_MUTE_MIX_I_SFT 15
#define RT1011_MIXER_MUTE_MIX_I (0x1 << 15)
#define RT1011_MIXER_MUTE_SUM_I_MASK (0x1 << 14)
#define RT1011_MIXER_MUTE_SUM_I_SFT 14
#define RT1011_MIXER_MUTE_SUM_I (0x1 << 14)
#define RT1011_MIXER_MUTE_MIX_V_MASK (0x1 << 7)
#define RT1011_MIXER_MUTE_MIX_V_SFT 7
#define RT1011_MIXER_MUTE_MIX_V (0x1 << 7)
#define RT1011_MIXER_MUTE_SUM_V_MASK (0x1 << 6)
#define RT1011_MIXER_MUTE_SUM_V_SFT 6
#define RT1011_MIXER_MUTE_SUM_V (0x1 << 6)
/* Analog Temperature Sensor (0x0316) */
#define RT1011_POW_TEMP_REG (0x1 << 2)
#define RT1011_POW_TEMP_REG_BIT 2
/* POWER-1 (0x0322) */
#define RT1011_POW_LDO2 (0x1 << 15)
#define RT1011_POW_LDO2_BIT 15
#define RT1011_POW_DAC (0x1 << 14)
#define RT1011_POW_DAC_BIT 14
#define RT1011_POW_CLK12M (0x1 << 13)
#define RT1011_POW_CLK12M_BIT 13
#define RT1011_POW_TEMP (0x1 << 12)
#define RT1011_POW_TEMP_BIT 12
#define RT1011_POW_ISENSE_SPK (0x1 << 7)
#define RT1011_POW_ISENSE_SPK_BIT 7
#define RT1011_POW_LPF_SPK (0x1 << 6)
#define RT1011_POW_LPF_SPK_BIT 6
#define RT1011_POW_VSENSE_SPK (0x1 << 5)
#define RT1011_POW_VSENSE_SPK_BIT 5
#define RT1011_POW_TWO_BATTERY_SPK (0x1 << 4)
#define RT1011_POW_TWO_BATTERY_SPK_BIT 4
/* POWER-2 (0x0324) */
#define RT1011_PLLEN (0x1 << 2)
#define RT1011_PLLEN_BIT 2
#define RT1011_POW_BG (0x1 << 1)
#define RT1011_POW_BG_BIT 1
#define RT1011_POW_BG_MBIAS_LV (0x1 << 0)
#define RT1011_POW_BG_MBIAS_LV_BIT 0
/* POWER-3 (0x0326) */
#define RT1011_POW_DET_SPKVDD (0x1 << 15)
#define RT1011_POW_DET_SPKVDD_BIT 15
#define RT1011_POW_DET_VBAT (0x1 << 14)
#define RT1011_POW_DET_VBAT_BIT 14
#define RT1011_POW_FC (0x1 << 13)
#define RT1011_POW_FC_BIT 13
#define RT1011_POW_MBIAS_LV (0x1 << 12)
#define RT1011_POW_MBIAS_LV_BIT 12
#define RT1011_POW_ADC_I (0x1 << 11)
#define RT1011_POW_ADC_I_BIT 11
#define RT1011_POW_ADC_V (0x1 << 10)
#define RT1011_POW_ADC_V_BIT 10
#define RT1011_POW_ADC_T (0x1 << 9)
#define RT1011_POW_ADC_T_BIT 9
#define RT1011_POWD_ADC_T (0x1 << 8)
#define RT1011_POWD_ADC_T_BIT 8
#define RT1011_POW_MIX_I (0x1 << 7)
#define RT1011_POW_MIX_I_BIT 7
#define RT1011_POW_MIX_V (0x1 << 6)
#define RT1011_POW_MIX_V_BIT 6
#define RT1011_POW_SUM_I (0x1 << 5)
#define RT1011_POW_SUM_I_BIT 5
#define RT1011_POW_SUM_V (0x1 << 4)
#define RT1011_POW_SUM_V_BIT 4
#define RT1011_POW_MIX_T (0x1 << 2)
#define RT1011_POW_MIX_T_BIT 2
#define RT1011_BYPASS_MIX_T (0x1 << 1)
#define RT1011_BYPASS_MIX_T_BIT 1
#define RT1011_POW_VREF_LV (0x1 << 0)
#define RT1011_POW_VREF_LV_BIT 0
/* POWER-4 (0x0328) */
#define RT1011_POW_EN_SWR (0x1 << 12)
#define RT1011_POW_EN_SWR_BIT 12
#define RT1011_POW_EN_PASS_BGOK_SWR (0x1 << 10)
#define RT1011_POW_EN_PASS_BGOK_SWR_BIT 10
#define RT1011_POW_EN_PASS_VPOK_SWR (0x1 << 9)
#define RT1011_POW_EN_PASS_VPOK_SWR_BIT 9
/* POWER-9 (0x032d) */
#define RT1011_POW_SDB_REG_MASK (0x1 << 9)
#define RT1011_POW_SDB_REG_BIT 9
#define RT1011_POW_SDB_REG (0x1 << 9)
#define RT1011_POW_SEL_SDB_MODE_MASK (0x1 << 6)
#define RT1011_POW_SEL_SDB_MODE_BIT 6
#define RT1011_POW_SEL_SDB_MODE (0x1 << 6)
#define RT1011_POW_MNL_SDB_MASK (0x1 << 5)
#define RT1011_POW_MNL_SDB_BIT 5
#define RT1011_POW_MNL_SDB (0x1 << 5)
/* SPK Protection-Temperature Protection (0x050c) */
#define RT1011_STP_EN_MASK (0x1 << 15)
#define RT1011_STP_EN_BIT 15
#define RT1011_STP_EN (0x1 << 15)
#define RT1011_STP_RS_CLB_EN_MASK (0x1 << 14)
#define RT1011_STP_RS_CLB_EN_BIT 14
#define RT1011_STP_RS_CLB_EN (0x1 << 14)
/* SPK Protection-Temperature Protection-4 (0x0510) */
#define RT1011_STP_R0_SELECT_MASK (0x3 << 6)
#define RT1011_STP_R0_SELECT_EFUSE (0x0 << 6)
#define RT1011_STP_R0_SELECT_START_VAL (0x1 << 6)
#define RT1011_STP_R0_SELECT_REG (0x2 << 6)
#define RT1011_STP_R0_SELECT_FORCE_ZERO (0x3 << 6)
/* SPK Protection-Temperature Protection-6 (0x0512) */
#define RT1011_STP_R0_EN_MASK (0x1 << 7)
#define RT1011_STP_R0_EN_BIT 7
#define RT1011_STP_R0_EN (0x1 << 7)
#define RT1011_STP_T0_EN_MASK (0x1 << 6)
#define RT1011_STP_T0_EN_BIT 6
#define RT1011_STP_T0_EN (0x1 << 6)
/* ClassD Internal Setting-1 (0x1300) */
#define RT1011_DRIVER_READY_SPK (0x1 << 12)
#define RT1011_DRIVER_READY_SPK_BIT 12
#define RT1011_RECV_MODE_SPK_MASK (0x1 << 5)
#define RT1011_SPK_MODE (0x0 << 5)
#define RT1011_RECV_MODE (0x1 << 5)
#define RT1011_RECV_MODE_SPK_BIT 5
/* ClassD Internal Setting-3 (0x1304) */
#define RT1011_REG_GAIN_CLASSD_RI_SPK_MASK (0x7 << 12)
#define RT1011_REG_GAIN_CLASSD_RI_410K (0x0 << 12)
#define RT1011_REG_GAIN_CLASSD_RI_95K (0x1 << 12)
#define RT1011_REG_GAIN_CLASSD_RI_82P5K (0x2 << 12)
#define RT1011_REG_GAIN_CLASSD_RI_72P5K (0x3 << 12)
#define RT1011_REG_GAIN_CLASSD_RI_62P5K (0x4 << 12)
/* ClassD Internal Setting-8 (0x130c) */
#define RT1011_TM_PORPVDD_SPK (0x1 << 1)
#define RT1011_TM_PORPVDD_SPK_BIT 1
/* SPK Protection-Temperature Protection-SINE_GEN_REG-1 (0x1500) */
#define RT1011_STP_SIN_GEN_EN_MASK (0x1 << 13)
#define RT1011_STP_SIN_GEN_EN (0x1 << 13)
#define RT1011_STP_SIN_GEN_EN_BIT 13
/* System Clock Source */
enum {
RT1011_FS_SYS_PRE_S_MCLK,
RT1011_FS_SYS_PRE_S_BCLK,
RT1011_FS_SYS_PRE_S_PLL1,
RT1011_FS_SYS_PRE_S_RCCLK, /* 12M Hz */
};
/* PLL Source 1/2 */
enum {
RT1011_PLL1_S_BCLK,
RT1011_PLL2_S_MCLK,
RT1011_PLL2_S_RCCLK, /* 12M Hz */
};
enum {
RT1011_AIF1,
RT1011_AIFS
};
/* BiQual & DRC related settings */
#define RT1011_BQ_DRC_NUM 128
struct rt1011_bq_drc_params {
unsigned short val;
unsigned short reg;
#ifdef CONFIG_64BIT
unsigned int reserved;
#endif
};
enum {
RT1011_ADVMODE_INITIAL_SET,
RT1011_ADVMODE_SEP_BQ_COEFF,
RT1011_ADVMODE_EQ_BQ_COEFF,
RT1011_ADVMODE_BQ_UI_COEFF,
RT1011_ADVMODE_SMARTBOOST_COEFF,
RT1011_ADVMODE_NUM,
};
struct rt1011_priv {
struct snd_soc_component *component;
struct regmap *regmap;
struct work_struct cali_work;
struct rt1011_bq_drc_params **bq_drc_params;
int sysclk;
int sysclk_src;
int lrck;
int bclk;
int id;
int pll_src;
int pll_in;
int pll_out;
int bq_drc_set;
unsigned int r0_reg;
int recv_spk_mode;
};
#endif /* end of _RT1011_H_ */

898
sound/soc/codecs/rt1308.c Executable file
파일 보기

@@ -0,0 +1,898 @@
/*
* rt1308.c -- RT1308 ALSA SoC amplifier component driver
*
* Copyright 2019 Realtek Semiconductor Corp.
* Author: Derek Fang <derek.fang@realtek.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/of_gpio.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>
#include <linux/firmware.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
#include "rl6231.h"
#include "rt1308.h"
static const struct reg_sequence init_list[] = {
{ RT1308_I2C_I2S_SDW_SET, 0x01014005 },
{ RT1308_CLASS_D_SET_2, 0x227f5501 },
{ RT1308_PADS_1, 0x50150505 },
{ RT1308_VREF, 0x18100000 },
{ RT1308_IV_SENSE, 0x87010000 },
{ RT1308_DUMMY_REG, 0x00000200 },
{ RT1308_SIL_DET, 0x61c30000 },
{ RT1308_DC_CAL_2, 0x00ffff00 },
{ RT1308_CLK_DET, 0x01000000 },
{ RT1308_POWER_STATUS, 0x00800000 },
{ RT1308_DAC_SET, 0xafaf0700 },
};
#define RT1308_INIT_REG_LEN ARRAY_SIZE(init_list)
struct rt1308_priv {
struct snd_soc_component *component;
struct regmap *regmap;
int sysclk;
int sysclk_src;
int lrck;
int bclk;
int master;
int pll_src;
int pll_in;
int pll_out;
};
static const struct reg_default rt1308_reg[] = {
{ 0x01, 0x1f3f5f00 },
{ 0x02, 0x07000000 },
{ 0x03, 0x80003e00 },
{ 0x04, 0x80800600 },
{ 0x05, 0x0aaa1a0a },
{ 0x06, 0x52000000 },
{ 0x07, 0x00000000 },
{ 0x08, 0x00600000 },
{ 0x09, 0xe1030000 },
{ 0x0a, 0x00000000 },
{ 0x0b, 0x30000000 },
{ 0x0c, 0x7fff7000 },
{ 0x10, 0xffff0700 },
{ 0x11, 0x0a000000 },
{ 0x12, 0x60040000 },
{ 0x13, 0x00000000 },
{ 0x14, 0x0f300000 },
{ 0x15, 0x00000022 },
{ 0x16, 0x02000000 },
{ 0x17, 0x01004045 },
{ 0x18, 0x00000000 },
{ 0x19, 0x00000000 },
{ 0x1a, 0x80000000 },
{ 0x1b, 0x10325476 },
{ 0x1c, 0x1d1d0000 },
{ 0x20, 0xd2101300 },
{ 0x21, 0xf3ffff00 },
{ 0x22, 0x00000000 },
{ 0x23, 0x00000000 },
{ 0x24, 0x00000000 },
{ 0x25, 0x00000000 },
{ 0x26, 0x00000000 },
{ 0x27, 0x00000000 },
{ 0x28, 0x00000000 },
{ 0x29, 0x00000000 },
{ 0x2a, 0x00000000 },
{ 0x2b, 0x00000000 },
{ 0x2c, 0x00000000 },
{ 0x2d, 0x00000000 },
{ 0x2e, 0x00000000 },
{ 0x2f, 0x00000000 },
{ 0x30, 0x01000000 },
{ 0x31, 0x20025501 },
{ 0x32, 0x00000000 },
{ 0x33, 0x105a0000 },
{ 0x34, 0x10100000 },
{ 0x35, 0x2aaa52aa },
{ 0x36, 0x00c00000 },
{ 0x37, 0x20046100 },
{ 0x50, 0x10022f00 },
{ 0x51, 0x003c0000 },
{ 0x54, 0x04000000 },
{ 0x55, 0x01000000 },
{ 0x56, 0x02000000 },
{ 0x57, 0x02000000 },
{ 0x58, 0x02000000 },
{ 0x59, 0x02000000 },
{ 0x5b, 0x02000000 },
{ 0x5c, 0x00000000 },
{ 0x5d, 0x00000000 },
{ 0x5e, 0x00000000 },
{ 0x5f, 0x00000000 },
{ 0x60, 0x02000000 },
{ 0x61, 0x00000000 },
{ 0x62, 0x00000000 },
{ 0x63, 0x00000000 },
{ 0x64, 0x00000000 },
{ 0x65, 0x02000000 },
{ 0x66, 0x00000000 },
{ 0x67, 0x00000000 },
{ 0x68, 0x00000000 },
{ 0x69, 0x00000000 },
{ 0x6a, 0x02000000 },
{ 0x6c, 0x00000000 },
{ 0x6d, 0x00000000 },
{ 0x6e, 0x00000000 },
{ 0x70, 0x10EC1308 },
{ 0x71, 0x00000000 },
{ 0x72, 0x00000000 },
{ 0x73, 0x00000000 },
{ 0x74, 0x00000000 },
{ 0x75, 0x00000000 },
{ 0x76, 0x00000000 },
{ 0x77, 0x00000000 },
{ 0x78, 0x00000000 },
{ 0x79, 0x00000000 },
{ 0x7a, 0x00000000 },
{ 0x7b, 0x00000000 },
{ 0x7c, 0x00000000 },
{ 0x7d, 0x00000000 },
{ 0x7e, 0x00000000 },
{ 0x7f, 0x00020f00 },
{ 0x80, 0x00000000 },
{ 0x81, 0x00000000 },
{ 0x82, 0x00000000 },
{ 0x83, 0x00000000 },
{ 0x84, 0x00000000 },
{ 0x85, 0x00000000 },
{ 0x86, 0x00000000 },
{ 0x87, 0x00000000 },
{ 0x88, 0x00000000 },
{ 0x89, 0x00000000 },
{ 0x8a, 0x00000000 },
{ 0x8b, 0x00000000 },
{ 0x8c, 0x00000000 },
{ 0x8d, 0x00000000 },
{ 0x8e, 0x00000000 },
{ 0x90, 0x50250905 },
{ 0x91, 0x15050000 },
{ 0xa0, 0x00000000 },
{ 0xa1, 0x00000000 },
{ 0xa2, 0x00000000 },
{ 0xa3, 0x00000000 },
{ 0xa4, 0x00000000 },
{ 0xb0, 0x00000000 },
{ 0xb1, 0x00000000 },
{ 0xb2, 0x00000000 },
{ 0xb3, 0x00000000 },
{ 0xb4, 0x00000000 },
{ 0xb5, 0x00000000 },
{ 0xb6, 0x00000000 },
{ 0xb7, 0x00000000 },
{ 0xb8, 0x00000000 },
{ 0xb9, 0x00000000 },
{ 0xba, 0x00000000 },
{ 0xbb, 0x00000000 },
{ 0xc0, 0x01000000 },
{ 0xc1, 0x00000000 },
{ 0xf0, 0x00000000 },
};
static int rt1308_reg_init(struct snd_soc_component *component)
{
struct rt1308_priv *rt1308 = snd_soc_component_get_drvdata(component);
return regmap_multi_reg_write(rt1308->regmap, init_list,
RT1308_INIT_REG_LEN);
}
static bool rt1308_volatile_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case RT1308_RESET:
case RT1308_RESET_N:
case RT1308_CLK_2:
case RT1308_SIL_DET:
case RT1308_CLK_DET:
case RT1308_DC_DET:
case RT1308_DAC_SET:
case RT1308_DAC_BUF:
case RT1308_SDW_REG_RDATA:
case RT1308_DC_CAL_1:
case RT1308_PVDD_OFFSET_CTL:
case RT1308_CAL_OFFSET_DAC_PBTL:
case RT1308_CAL_OFFSET_DAC_L:
case RT1308_CAL_OFFSET_DAC_R:
case RT1308_CAL_OFFSET_PWM_L:
case RT1308_CAL_OFFSET_PWM_R:
case RT1308_CAL_PWM_VOS_ADC_L:
case RT1308_CAL_PWM_VOS_ADC_R:
case RT1308_MBIAS:
case RT1308_POWER_STATUS:
case RT1308_POWER_INT:
case RT1308_SINE_TONE_GEN_2:
case RT1308_BQ_SET:
case RT1308_BQ_PARA_UPDATE:
case RT1308_VEN_DEV_ID:
case RT1308_VERSION_ID:
case RT1308_EFUSE_1:
case RT1308_EFUSE_READ_PVDD_L:
case RT1308_EFUSE_READ_PVDD_R:
case RT1308_EFUSE_READ_PVDD_PTBL:
case RT1308_EFUSE_READ_DEV:
case RT1308_EFUSE_READ_R0:
case RT1308_EFUSE_READ_ADC_L:
case RT1308_EFUSE_READ_ADC_R:
case RT1308_EFUSE_READ_ADC_PBTL:
case RT1308_EFUSE_RESERVE:
case RT1308_EFUSE_DATA_0_MSB:
case RT1308_EFUSE_DATA_0_LSB:
case RT1308_EFUSE_DATA_1_MSB:
case RT1308_EFUSE_DATA_1_LSB:
case RT1308_EFUSE_DATA_2_MSB:
case RT1308_EFUSE_DATA_2_LSB:
case RT1308_EFUSE_DATA_3_MSB:
case RT1308_EFUSE_DATA_3_LSB:
case RT1308_EFUSE_STATUS_1:
case RT1308_EFUSE_STATUS_2:
case RT1308_DUMMY_REG:
return true;
default:
return false;
}
}
static bool rt1308_readable_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case RT1308_RESET:
case RT1308_RESET_N:
case RT1308_CLK_GATING ... RT1308_DC_DET_THRES:
case RT1308_DAC_SET ... RT1308_AD_FILTER_SET:
case RT1308_DC_CAL_1 ... RT1308_POWER_INT:
case RT1308_SINE_TONE_GEN_1:
case RT1308_SINE_TONE_GEN_2:
case RT1308_BQ_SET:
case RT1308_BQ_PARA_UPDATE:
case RT1308_BQ_PRE_VOL_L ... RT1308_BQ_POST_VOL_R:
case RT1308_BQ1_L_H0 ... RT1308_BQ2_R_A2:
case RT1308_VEN_DEV_ID:
case RT1308_VERSION_ID:
case RT1308_SPK_BOUND:
case RT1308_BQ1_EQ_L_1 ... RT1308_BQ2_EQ_R_3:
case RT1308_EFUSE_1 ... RT1308_EFUSE_RESERVE:
case RT1308_PADS_1:
case RT1308_PADS_2:
case RT1308_TEST_MODE:
case RT1308_TEST_1:
case RT1308_TEST_2:
case RT1308_TEST_3:
case RT1308_TEST_4:
case RT1308_EFUSE_DATA_0_MSB ... RT1308_EFUSE_STATUS_2:
case RT1308_TCON_1:
case RT1308_TCON_2:
case RT1308_DUMMY_REG:
case RT1308_MAX_REG:
return true;
default:
return false;
}
}
static int rt1308_classd_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_component *component =
snd_soc_dapm_to_component(w->dapm);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
msleep(30);
snd_soc_component_update_bits(component, RT1308_POWER_STATUS,
RT1308_POW_PDB_REG_BIT, RT1308_POW_PDB_REG_BIT);
msleep(40);
break;
case SND_SOC_DAPM_PRE_PMD:
snd_soc_component_update_bits(component, RT1308_POWER_STATUS,
RT1308_POW_PDB_REG_BIT, 0);
usleep_range(150000, 200000);
break;
default:
break;
}
return 0;
}
static const char * const rt1308_rx_data_ch_select[] = {
"LR",
"LL",
"RL",
"RR",
};
static SOC_ENUM_SINGLE_DECL(rt1308_rx_data_ch_enum, RT1308_DATA_PATH, 24,
rt1308_rx_data_ch_select);
static const struct snd_kcontrol_new rt1308_snd_controls[] = {
/* I2S Data Channel Selection */
SOC_ENUM("RX Channel Select", rt1308_rx_data_ch_enum),
};
static const struct snd_kcontrol_new rt1308_sto_dac_l =
SOC_DAPM_SINGLE("Switch", RT1308_DAC_SET,
RT1308_DVOL_MUTE_L_EN_SFT, 1, 1);
static const struct snd_kcontrol_new rt1308_sto_dac_r =
SOC_DAPM_SINGLE("Switch", RT1308_DAC_SET,
RT1308_DVOL_MUTE_R_EN_SFT, 1, 1);
static const struct snd_soc_dapm_widget rt1308_dapm_widgets[] = {
/* Audio Interface */
SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
/* Supply Widgets */
SND_SOC_DAPM_SUPPLY("MBIAS20U", RT1308_POWER,
RT1308_POW_MBIAS20U_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("ALDO", RT1308_POWER,
RT1308_POW_ALDO_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DBG", RT1308_POWER,
RT1308_POW_DBG_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DACL", RT1308_POWER,
RT1308_POW_DACL_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("CLK25M", RT1308_POWER,
RT1308_POW_CLK25M_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("ADC_R", RT1308_POWER,
RT1308_POW_ADC_R_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("ADC_L", RT1308_POWER,
RT1308_POW_ADC_L_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DLDO", RT1308_POWER,
RT1308_POW_DLDO_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("VREF", RT1308_POWER,
RT1308_POW_VREF_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("MIXER_R", RT1308_POWER,
RT1308_POW_MIXER_R_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("MIXER_L", RT1308_POWER,
RT1308_POW_MIXER_L_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("MBIAS4U", RT1308_POWER,
RT1308_POW_MBIAS4U_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("PLL2_LDO", RT1308_POWER,
RT1308_POW_PLL2_LDO_EN_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("PLL2B", RT1308_POWER,
RT1308_POW_PLL2B_EN_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("PLL2F", RT1308_POWER,
RT1308_POW_PLL2F_EN_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("PLL2F2", RT1308_POWER,
RT1308_POW_PLL2F2_EN_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("PLL2B2", RT1308_POWER,
RT1308_POW_PLL2B2_EN_BIT, 0, NULL, 0),
/* Digital Interface */
SND_SOC_DAPM_SUPPLY("DAC Power", RT1308_POWER,
RT1308_POW_DAC1_BIT, 0, NULL, 0),
SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_SWITCH("DAC L", SND_SOC_NOPM, 0, 0, &rt1308_sto_dac_l),
SND_SOC_DAPM_SWITCH("DAC R", SND_SOC_NOPM, 0, 0, &rt1308_sto_dac_r),
/* Output Lines */
SND_SOC_DAPM_PGA_E("CLASS D", SND_SOC_NOPM, 0, 0, NULL, 0,
rt1308_classd_event,
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_OUTPUT("SPOL"),
SND_SOC_DAPM_OUTPUT("SPOR"),
};
static const struct snd_soc_dapm_route rt1308_dapm_routes[] = {
{ "DAC", NULL, "AIF1RX" },
{ "DAC", NULL, "MBIAS20U" },
{ "DAC", NULL, "ALDO" },
{ "DAC", NULL, "DBG" },
{ "DAC", NULL, "DACL" },
{ "DAC", NULL, "CLK25M" },
{ "DAC", NULL, "ADC_R" },
{ "DAC", NULL, "ADC_L" },
{ "DAC", NULL, "DLDO" },
{ "DAC", NULL, "VREF" },
{ "DAC", NULL, "MIXER_R" },
{ "DAC", NULL, "MIXER_L" },
{ "DAC", NULL, "MBIAS4U" },
{ "DAC", NULL, "PLL2_LDO" },
{ "DAC", NULL, "PLL2B" },
{ "DAC", NULL, "PLL2F" },
{ "DAC", NULL, "PLL2F2" },
{ "DAC", NULL, "PLL2B2" },
{ "DAC L", "Switch", "DAC" },
{ "DAC R", "Switch", "DAC" },
{ "DAC L", NULL, "DAC Power" },
{ "DAC R", NULL, "DAC Power" },
{ "CLASS D", NULL, "DAC L" },
{ "CLASS D", NULL, "DAC R" },
{ "SPOL", NULL, "CLASS D" },
{ "SPOR", NULL, "CLASS D" },
};
static int rt1308_get_clk_info(int sclk, int rate)
{
int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
if (sclk <= 0 || rate <= 0)
return -EINVAL;
rate = rate << 8;
for (i = 0; i < ARRAY_SIZE(pd); i++)
if (sclk == rate * pd[i])
return i;
return -EINVAL;
}
static int rt1308_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
struct rt1308_priv *rt1308 = snd_soc_component_get_drvdata(component);
unsigned int val_len = 0, val_clk, mask_clk;
int pre_div, bclk_ms, frame_size;
rt1308->lrck = params_rate(params);
pre_div = rt1308_get_clk_info(rt1308->sysclk, rt1308->lrck);
if (pre_div < 0) {
dev_err(component->dev,
"Unsupported clock setting %d\n", rt1308->lrck);
return -EINVAL;
}
frame_size = snd_soc_params_to_frame_size(params);
if (frame_size < 0) {
dev_err(component->dev, "Unsupported frame size: %d\n",
frame_size);
return -EINVAL;
}
bclk_ms = frame_size > 32;
rt1308->bclk = rt1308->lrck * (32 << bclk_ms);
dev_dbg(component->dev, "bclk_ms is %d and pre_div is %d for iis %d\n",
bclk_ms, pre_div, dai->id);
dev_dbg(component->dev, "lrck is %dHz and pre_div is %d for iis %d\n",
rt1308->lrck, pre_div, dai->id);
switch (params_width(params)) {
case 16:
val_len |= RT1308_I2S_DL_SEL_16B;
break;
case 20:
val_len |= RT1308_I2S_DL_SEL_20B;
break;
case 24:
val_len |= RT1308_I2S_DL_SEL_24B;
break;
case 8:
val_len |= RT1308_I2S_DL_SEL_8B;
break;
default:
return -EINVAL;
}
switch (dai->id) {
case RT1308_AIF1:
mask_clk = RT1308_DIV_FS_SYS_MASK;
val_clk = pre_div << RT1308_DIV_FS_SYS_SFT;
snd_soc_component_update_bits(component,
RT1308_I2S_SET_2, RT1308_I2S_DL_SEL_MASK,
val_len);
break;
default:
dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
return -EINVAL;
}
snd_soc_component_update_bits(component, RT1308_CLK_1,
mask_clk, val_clk);
return 0;
}
static int rt1308_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
struct snd_soc_component *component = dai->component;
struct rt1308_priv *rt1308 = snd_soc_component_get_drvdata(component);
unsigned int reg_val = 0, reg1_val = 0;
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS:
rt1308->master = 0;
break;
default:
return -EINVAL;
}
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
break;
case SND_SOC_DAIFMT_LEFT_J:
reg_val |= RT1308_I2S_DF_SEL_LEFT;
break;
case SND_SOC_DAIFMT_DSP_A:
reg_val |= RT1308_I2S_DF_SEL_PCM_A;
break;
case SND_SOC_DAIFMT_DSP_B:
reg_val |= RT1308_I2S_DF_SEL_PCM_B;
break;
default:
return -EINVAL;
}
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_NB_NF:
break;
case SND_SOC_DAIFMT_IB_NF:
reg1_val |= RT1308_I2S_BCLK_INV;
break;
default:
return -EINVAL;
}
switch (dai->id) {
case RT1308_AIF1:
snd_soc_component_update_bits(component,
RT1308_I2S_SET_1, RT1308_I2S_DF_SEL_MASK,
reg_val);
snd_soc_component_update_bits(component,
RT1308_I2S_SET_2, RT1308_I2S_BCLK_MASK,
reg1_val);
break;
default:
dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
return -EINVAL;
}
return 0;
}
static int rt1308_set_component_sysclk(struct snd_soc_component *component,
int clk_id, int source, unsigned int freq, int dir)
{
struct rt1308_priv *rt1308 = snd_soc_component_get_drvdata(component);
unsigned int reg_val = 0;
if (freq == rt1308->sysclk && clk_id == rt1308->sysclk_src)
return 0;
switch (clk_id) {
case RT1308_FS_SYS_S_MCLK:
reg_val |= RT1308_SEL_FS_SYS_SRC_MCLK;
snd_soc_component_update_bits(component,
RT1308_CLK_DET, RT1308_MCLK_DET_EN_MASK,
RT1308_MCLK_DET_EN);
break;
case RT1308_FS_SYS_S_BCLK:
reg_val |= RT1308_SEL_FS_SYS_SRC_BCLK;
break;
case RT1308_FS_SYS_S_PLL:
reg_val |= RT1308_SEL_FS_SYS_SRC_PLL;
break;
case RT1308_FS_SYS_S_RCCLK:
reg_val |= RT1308_SEL_FS_SYS_SRC_RCCLK;
break;
default:
dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
return -EINVAL;
}
snd_soc_component_update_bits(component, RT1308_CLK_1,
RT1308_SEL_FS_SYS_MASK, reg_val);
rt1308->sysclk = freq;
rt1308->sysclk_src = clk_id;
dev_dbg(component->dev, "Sysclk is %dHz and clock id is %d\n",
freq, clk_id);
return 0;
}
static int rt1308_set_component_pll(struct snd_soc_component *component,
int pll_id, int source, unsigned int freq_in,
unsigned int freq_out)
{
struct rt1308_priv *rt1308 = snd_soc_component_get_drvdata(component);
struct rl6231_pll_code pll_code;
int ret;
if (source == rt1308->pll_src && freq_in == rt1308->pll_in &&
freq_out == rt1308->pll_out)
return 0;
if (!freq_in || !freq_out) {
dev_dbg(component->dev, "PLL disabled\n");
rt1308->pll_in = 0;
rt1308->pll_out = 0;
snd_soc_component_update_bits(component,
RT1308_CLK_1, RT1308_SEL_FS_SYS_MASK,
RT1308_SEL_FS_SYS_SRC_MCLK);
return 0;
}
switch (source) {
case RT1308_PLL_S_MCLK:
snd_soc_component_update_bits(component,
RT1308_CLK_2, RT1308_SEL_PLL_SRC_MASK,
RT1308_SEL_PLL_SRC_MCLK);
snd_soc_component_update_bits(component,
RT1308_CLK_DET, RT1308_MCLK_DET_EN_MASK,
RT1308_MCLK_DET_EN);
break;
case RT1308_PLL_S_BCLK:
snd_soc_component_update_bits(component,
RT1308_CLK_2, RT1308_SEL_PLL_SRC_MASK,
RT1308_SEL_PLL_SRC_BCLK);
break;
case RT1308_PLL_S_RCCLK:
snd_soc_component_update_bits(component,
RT1308_CLK_2, RT1308_SEL_PLL_SRC_MASK,
RT1308_SEL_PLL_SRC_RCCLK);
freq_in = 25000000;
break;
default:
dev_err(component->dev, "Unknown PLL Source %d\n", source);
return -EINVAL;
}
ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
if (ret < 0) {
dev_err(component->dev, "Unsupport input clock %d\n", freq_in);
return ret;
}
dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
pll_code.n_code, pll_code.k_code);
snd_soc_component_write(component, RT1308_PLL_1,
pll_code.k_code << RT1308_PLL1_K_SFT |
pll_code.m_bp << RT1308_PLL1_M_BYPASS_SFT |
(pll_code.m_bp ? 0 : pll_code.m_code) << RT1308_PLL1_M_SFT |
pll_code.n_code << RT1308_PLL1_N_SFT);
rt1308->pll_in = freq_in;
rt1308->pll_out = freq_out;
rt1308->pll_src = source;
return 0;
}
static int rt1308_probe(struct snd_soc_component *component)
{
struct rt1308_priv *rt1308 = snd_soc_component_get_drvdata(component);
rt1308->component = component;
return rt1308_reg_init(component);
}
static void rt1308_remove(struct snd_soc_component *component)
{
struct rt1308_priv *rt1308 = snd_soc_component_get_drvdata(component);
regmap_write(rt1308->regmap, RT1308_RESET, 0);
}
#ifdef CONFIG_PM
static int rt1308_suspend(struct snd_soc_component *component)
{
struct rt1308_priv *rt1308 = snd_soc_component_get_drvdata(component);
regcache_cache_only(rt1308->regmap, true);
regcache_mark_dirty(rt1308->regmap);
return 0;
}
static int rt1308_resume(struct snd_soc_component *component)
{
struct rt1308_priv *rt1308 = snd_soc_component_get_drvdata(component);
regcache_cache_only(rt1308->regmap, false);
regcache_sync(rt1308->regmap);
return 0;
}
#else
#define rt1308_suspend NULL
#define rt1308_resume NULL
#endif
#define RT1308_STEREO_RATES SNDRV_PCM_RATE_48000
#define RT1308_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_LE)
static const struct snd_soc_dai_ops rt1308_aif_dai_ops = {
.hw_params = rt1308_hw_params,
.set_fmt = rt1308_set_dai_fmt,
};
static struct snd_soc_dai_driver rt1308_dai[] = {
{
.name = "rt1308-aif",
.playback = {
.stream_name = "AIF1 Playback",
.channels_min = 1,
.channels_max = 2,
.rates = RT1308_STEREO_RATES,
.formats = RT1308_FORMATS,
},
.ops = &rt1308_aif_dai_ops,
},
};
static const struct snd_soc_component_driver soc_component_dev_rt1308 = {
.probe = rt1308_probe,
.remove = rt1308_remove,
.suspend = rt1308_suspend,
.resume = rt1308_resume,
.controls = rt1308_snd_controls,
.num_controls = ARRAY_SIZE(rt1308_snd_controls),
.dapm_widgets = rt1308_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(rt1308_dapm_widgets),
.dapm_routes = rt1308_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(rt1308_dapm_routes),
.set_sysclk = rt1308_set_component_sysclk,
.set_pll = rt1308_set_component_pll,
.use_pmdown_time = 1,
.endianness = 1,
.non_legacy_dai_naming = 1,
};
static const struct regmap_config rt1308_regmap = {
.reg_bits = 8,
.val_bits = 32,
.max_register = RT1308_MAX_REG,
.volatile_reg = rt1308_volatile_register,
.readable_reg = rt1308_readable_register,
.cache_type = REGCACHE_RBTREE,
.reg_defaults = rt1308_reg,
.num_reg_defaults = ARRAY_SIZE(rt1308_reg),
.use_single_read = true,
.use_single_write = true,
};
#ifdef CONFIG_OF
static const struct of_device_id rt1308_of_match[] = {
{ .compatible = "realtek,rt1308", },
{ },
};
MODULE_DEVICE_TABLE(of, rt1308_of_match);
#endif
#ifdef CONFIG_ACPI
static struct acpi_device_id rt1308_acpi_match[] = {
{ "10EC1308", 0, },
{ },
};
MODULE_DEVICE_TABLE(acpi, rt1308_acpi_match);
#endif
static const struct i2c_device_id rt1308_i2c_id[] = {
{ "rt1308", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, rt1308_i2c_id);
static void rt1308_efuse(struct rt1308_priv *rt1308)
{
regmap_write(rt1308->regmap, RT1308_RESET, 0);
regmap_write(rt1308->regmap, RT1308_POWER, 0xff371600);
regmap_write(rt1308->regmap, RT1308_CLK_1, 0x52100000);
regmap_write(rt1308->regmap, RT1308_I2C_I2S_SDW_SET, 0x01014005);
regmap_write(rt1308->regmap, RT1308_CLASS_D_SET_2, 0x227f5501);
regmap_write(rt1308->regmap, RT1308_PADS_1, 0x50150505);
regmap_write(rt1308->regmap, RT1308_VREF, 0x18100000);
regmap_write(rt1308->regmap, RT1308_IV_SENSE, 0x87010000);
regmap_write(rt1308->regmap, RT1308_DUMMY_REG, 0x00000200);
regmap_write(rt1308->regmap, RT1308_SIL_DET, 0x61c30000);
regmap_write(rt1308->regmap, RT1308_CLK_DET, 0x03700000);
regmap_write(rt1308->regmap, RT1308_SINE_TONE_GEN_1, 0x50022f00);
regmap_write(rt1308->regmap, RT1308_POWER_STATUS, 0x01800000);
regmap_write(rt1308->regmap, RT1308_DC_CAL_2, 0x00ffff00);
regmap_write(rt1308->regmap, RT1308_CLASS_D_SET_2, 0x607e5501);
regmap_write(rt1308->regmap, RT1308_CLK_2, 0x0060e000);
regmap_write(rt1308->regmap, RT1308_EFUSE_1, 0x04fe0f00);
msleep(100);
regmap_write(rt1308->regmap, RT1308_EFUSE_1, 0x44fe0f00);
msleep(20);
regmap_write(rt1308->regmap, RT1308_PVDD_OFFSET_CTL, 0x10000000);
regmap_write(rt1308->regmap, RT1308_POWER_STATUS, 0x00800000);
regmap_write(rt1308->regmap, RT1308_POWER, 0x0);
regmap_write(rt1308->regmap, RT1308_CLK_1, 0x52000000);
regmap_write(rt1308->regmap, RT1308_CLASS_D_SET_2, 0x227f5501);
regmap_write(rt1308->regmap, RT1308_SINE_TONE_GEN_1, 0x10022f00);
}
static int rt1308_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct rt1308_priv *rt1308;
int ret;
unsigned int val;
rt1308 = devm_kzalloc(&i2c->dev, sizeof(struct rt1308_priv),
GFP_KERNEL);
if (rt1308 == NULL)
return -ENOMEM;
i2c_set_clientdata(i2c, rt1308);
rt1308->regmap = devm_regmap_init_i2c(i2c, &rt1308_regmap);
if (IS_ERR(rt1308->regmap)) {
ret = PTR_ERR(rt1308->regmap);
dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
ret);
return ret;
}
regmap_read(rt1308->regmap, RT1308_VEN_DEV_ID, &val);
/* ignore last byte difference */
if ((val & 0xFFFFFF00) != RT1308_DEVICE_ID_NUM) {
dev_err(&i2c->dev,
"Device with ID register %x is not rt1308\n", val);
return -ENODEV;
}
rt1308_efuse(rt1308);
return devm_snd_soc_register_component(&i2c->dev,
&soc_component_dev_rt1308,
rt1308_dai, ARRAY_SIZE(rt1308_dai));
}
static void rt1308_i2c_shutdown(struct i2c_client *client)
{
struct rt1308_priv *rt1308 = i2c_get_clientdata(client);
regmap_write(rt1308->regmap, RT1308_RESET, 0);
}
static struct i2c_driver rt1308_i2c_driver = {
.driver = {
.name = "rt1308",
.of_match_table = of_match_ptr(rt1308_of_match),
.acpi_match_table = ACPI_PTR(rt1308_acpi_match),
},
.probe = rt1308_i2c_probe,
.shutdown = rt1308_i2c_shutdown,
.id_table = rt1308_i2c_id,
};
module_i2c_driver(rt1308_i2c_driver);
MODULE_DESCRIPTION("ASoC RT1308 amplifier driver");
MODULE_AUTHOR("Derek Fang <derek.fang@realtek.com>");
MODULE_LICENSE("GPL v2");

291
sound/soc/codecs/rt1308.h Executable file
파일 보기

@@ -0,0 +1,291 @@
/*
* RT1308.h -- RT1308 ALSA SoC amplifier component driver
*
* Copyright 2019 Realtek Semiconductor Corp.
* Author: Derek Fang <derek.fang@realtek.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _RT1308_H_
#define _RT1308_H_
#define RT1308_DEVICE_ID_NUM 0x10ec1300
#define RT1308_RESET 0x00
#define RT1308_RESET_N 0x01
#define RT1308_CLK_GATING 0x02
#define RT1308_PLL_1 0x03
#define RT1308_PLL_2 0x04
#define RT1308_PLL_INT 0x05
#define RT1308_CLK_1 0x06
#define RT1308_DATA_PATH 0x07
#define RT1308_CLK_2 0x08
#define RT1308_SIL_DET 0x09
#define RT1308_CLK_DET 0x0a
#define RT1308_DC_DET 0x0b
#define RT1308_DC_DET_THRES 0x0c
#define RT1308_DAC_SET 0x10
#define RT1308_SRC_SET 0x11
#define RT1308_DAC_BUF 0x12
#define RT1308_ADC_SET 0x13
#define RT1308_ADC_SET_INT 0x14
#define RT1308_I2S_SET_1 0x15
#define RT1308_I2S_SET_2 0x16
#define RT1308_I2C_I2S_SDW_SET 0x17
#define RT1308_SDW_REG_RW 0x18
#define RT1308_SDW_REG_RDATA 0x19
#define RT1308_IV_SENSE 0x1a
#define RT1308_I2S_TX_DAC_SET 0x1b
#define RT1308_AD_FILTER_SET 0x1c
#define RT1308_DC_CAL_1 0x20
#define RT1308_DC_CAL_2 0x21
#define RT1308_DC_CAL_L_OFFSET 0x22
#define RT1308_DC_CAL_R_OFFSET 0x23
#define RT1308_PVDD_OFFSET_CTL 0x24
#define RT1308_PVDD_OFFSET_L 0x25
#define RT1308_PVDD_OFFSET_R 0x26
#define RT1308_PVDD_OFFSET_PBTL 0x27
#define RT1308_PVDD_OFFSET_PVDD 0x28
#define RT1308_CAL_OFFSET_DAC_PBTL 0x29
#define RT1308_CAL_OFFSET_DAC_L 0x2a
#define RT1308_CAL_OFFSET_DAC_R 0x2b
#define RT1308_CAL_OFFSET_PWM_L 0x2c
#define RT1308_CAL_OFFSET_PWM_R 0x2d
#define RT1308_CAL_PWM_VOS_ADC_L 0x2e
#define RT1308_CAL_PWM_VOS_ADC_R 0x2f
#define RT1308_CLASS_D_SET_1 0x30
#define RT1308_CLASS_D_SET_2 0x31
#define RT1308_POWER 0x32
#define RT1308_LDO 0x33
#define RT1308_VREF 0x34
#define RT1308_MBIAS 0x35
#define RT1308_POWER_STATUS 0x36
#define RT1308_POWER_INT 0x37
#define RT1308_SINE_TONE_GEN_1 0x50
#define RT1308_SINE_TONE_GEN_2 0x51
#define RT1308_BQ_SET 0x54
#define RT1308_BQ_PARA_UPDATE 0x55
#define RT1308_BQ_PRE_VOL_L 0x56
#define RT1308_BQ_PRE_VOL_R 0x57
#define RT1308_BQ_POST_VOL_L 0x58
#define RT1308_BQ_POST_VOL_R 0x59
#define RT1308_BQ1_L_H0 0x5b
#define RT1308_BQ1_L_B1 0x5c
#define RT1308_BQ1_L_B2 0x5d
#define RT1308_BQ1_L_A1 0x5e
#define RT1308_BQ1_L_A2 0x5f
#define RT1308_BQ1_R_H0 0x60
#define RT1308_BQ1_R_B1 0x61
#define RT1308_BQ1_R_B2 0x62
#define RT1308_BQ1_R_A1 0x63
#define RT1308_BQ1_R_A2 0x64
#define RT1308_BQ2_L_H0 0x65
#define RT1308_BQ2_L_B1 0x66
#define RT1308_BQ2_L_B2 0x67
#define RT1308_BQ2_L_A1 0x68
#define RT1308_BQ2_L_A2 0x69
#define RT1308_BQ2_R_H0 0x6a
#define RT1308_BQ2_R_B1 0x6b
#define RT1308_BQ2_R_B2 0x6c
#define RT1308_BQ2_R_A1 0x6d
#define RT1308_BQ2_R_A2 0x6e
#define RT1308_VEN_DEV_ID 0x70
#define RT1308_VERSION_ID 0x71
#define RT1308_SPK_BOUND 0x72
#define RT1308_BQ1_EQ_L_1 0x73
#define RT1308_BQ1_EQ_L_2 0x74
#define RT1308_BQ1_EQ_L_3 0x75
#define RT1308_BQ1_EQ_R_1 0x76
#define RT1308_BQ1_EQ_R_2 0x77
#define RT1308_BQ1_EQ_R_3 0x78
#define RT1308_BQ2_EQ_L_1 0x79
#define RT1308_BQ2_EQ_L_2 0x7a
#define RT1308_BQ2_EQ_L_3 0x7b
#define RT1308_BQ2_EQ_R_1 0x7c
#define RT1308_BQ2_EQ_R_2 0x7d
#define RT1308_BQ2_EQ_R_3 0x7e
#define RT1308_EFUSE_1 0x7f
#define RT1308_EFUSE_2 0x80
#define RT1308_EFUSE_PROG_PVDD_L 0x81
#define RT1308_EFUSE_PROG_PVDD_R 0x82
#define RT1308_EFUSE_PROG_R0_L 0x83
#define RT1308_EFUSE_PROG_R0_R 0x84
#define RT1308_EFUSE_PROG_DEV 0x85
#define RT1308_EFUSE_READ_PVDD_L 0x86
#define RT1308_EFUSE_READ_PVDD_R 0x87
#define RT1308_EFUSE_READ_PVDD_PTBL 0x88
#define RT1308_EFUSE_READ_DEV 0x89
#define RT1308_EFUSE_READ_R0 0x8a
#define RT1308_EFUSE_READ_ADC_L 0x8b
#define RT1308_EFUSE_READ_ADC_R 0x8c
#define RT1308_EFUSE_READ_ADC_PBTL 0x8d
#define RT1308_EFUSE_RESERVE 0x8e
#define RT1308_PADS_1 0x90
#define RT1308_PADS_2 0x91
#define RT1308_TEST_MODE 0xa0
#define RT1308_TEST_1 0xa1
#define RT1308_TEST_2 0xa2
#define RT1308_TEST_3 0xa3
#define RT1308_TEST_4 0xa4
#define RT1308_EFUSE_DATA_0_MSB 0xb0
#define RT1308_EFUSE_DATA_0_LSB 0xb1
#define RT1308_EFUSE_DATA_1_MSB 0xb2
#define RT1308_EFUSE_DATA_1_LSB 0xb3
#define RT1308_EFUSE_DATA_2_MSB 0xb4
#define RT1308_EFUSE_DATA_2_LSB 0xb5
#define RT1308_EFUSE_DATA_3_MSB 0xb6
#define RT1308_EFUSE_DATA_3_LSB 0xb7
#define RT1308_EFUSE_DATA_TEST_MSB 0xb8
#define RT1308_EFUSE_DATA_TEST_LSB 0xb9
#define RT1308_EFUSE_STATUS_1 0xba
#define RT1308_EFUSE_STATUS_2 0xbb
#define RT1308_TCON_1 0xc0
#define RT1308_TCON_2 0xc1
#define RT1308_DUMMY_REG 0xf0
#define RT1308_MAX_REG 0xff
/* PLL1 M/N/K Code-1 (0x03) */
#define RT1308_PLL1_K_SFT 24
#define RT1308_PLL1_K_MASK (0x1f << 24)
#define RT1308_PLL1_M_BYPASS_MASK (0x1 << 23)
#define RT1308_PLL1_M_BYPASS_SFT 23
#define RT1308_PLL1_M_BYPASS (0x1 << 23)
#define RT1308_PLL1_M_MASK (0x3f << 16)
#define RT1308_PLL1_M_SFT 16
#define RT1308_PLL1_N_MASK (0x7f << 8)
#define RT1308_PLL1_N_SFT 8
/* CLOCK-1 (0x06) */
#define RT1308_DIV_FS_SYS_MASK (0xf << 28)
#define RT1308_DIV_FS_SYS_SFT 28
#define RT1308_SEL_FS_SYS_MASK (0x7 << 24)
#define RT1308_SEL_FS_SYS_SFT 24
#define RT1308_SEL_FS_SYS_SRC_MCLK (0x0 << 24)
#define RT1308_SEL_FS_SYS_SRC_BCLK (0x1 << 24)
#define RT1308_SEL_FS_SYS_SRC_PLL (0x2 << 24)
#define RT1308_SEL_FS_SYS_SRC_RCCLK (0x4 << 24)
/* CLOCK-2 (0x08) */
#define RT1308_DIV_PRE_PLL_MASK (0xf << 28)
#define RT1308_DIV_PRE_PLL_SFT 28
#define RT1308_SEL_PLL_SRC_MASK (0x7 << 24)
#define RT1308_SEL_PLL_SRC_SFT 24
#define RT1308_SEL_PLL_SRC_MCLK (0x0 << 24)
#define RT1308_SEL_PLL_SRC_BCLK (0x1 << 24)
#define RT1308_SEL_PLL_SRC_RCCLK (0x4 << 24)
/* Clock Detect (0x0a) */
#define RT1308_MCLK_DET_EN_MASK (0x1 << 25)
#define RT1308_MCLK_DET_EN_SFT 25
#define RT1308_MCLK_DET_EN (0x1 << 25)
#define RT1308_BCLK_DET_EN_MASK (0x1 << 24)
#define RT1308_BCLK_DET_EN_SFT 24
#define RT1308_BCLK_DET_EN (0x1 << 24)
/* DAC Setting (0x10) */
#define RT1308_DVOL_MUTE_R_EN_SFT 7
#define RT1308_DVOL_MUTE_L_EN_SFT 6
/* I2S Setting-1 (0x15) */
#define RT1308_I2S_DF_SEL_MASK (0x3 << 12)
#define RT1308_I2S_DF_SEL_SFT 12
#define RT1308_I2S_DF_SEL_I2S (0x0 << 12)
#define RT1308_I2S_DF_SEL_LEFT (0x1 << 12)
#define RT1308_I2S_DF_SEL_PCM_A (0x2 << 12)
#define RT1308_I2S_DF_SEL_PCM_B (0x3 << 12)
#define RT1308_I2S_DL_RX_SEL_MASK (0x7 << 4)
#define RT1308_I2S_DL_RX_SEL_SFT 4
#define RT1308_I2S_DL_RX_SEL_16B (0x0 << 4)
#define RT1308_I2S_DL_RX_SEL_20B (0x1 << 4)
#define RT1308_I2S_DL_RX_SEL_24B (0x2 << 4)
#define RT1308_I2S_DL_RX_SEL_32B (0x3 << 4)
#define RT1308_I2S_DL_RX_SEL_8B (0x4 << 4)
#define RT1308_I2S_DL_TX_SEL_MASK (0x7 << 0)
#define RT1308_I2S_DL_TX_SEL_SFT 0
#define RT1308_I2S_DL_TX_SEL_16B (0x0 << 0)
#define RT1308_I2S_DL_TX_SEL_20B (0x1 << 0)
#define RT1308_I2S_DL_TX_SEL_24B (0x2 << 0)
#define RT1308_I2S_DL_TX_SEL_32B (0x3 << 0)
#define RT1308_I2S_DL_TX_SEL_8B (0x4 << 0)
/* I2S Setting-2 (0x16) */
#define RT1308_I2S_DL_SEL_MASK (0x7 << 24)
#define RT1308_I2S_DL_SEL_SFT 24
#define RT1308_I2S_DL_SEL_16B (0x0 << 24)
#define RT1308_I2S_DL_SEL_20B (0x1 << 24)
#define RT1308_I2S_DL_SEL_24B (0x2 << 24)
#define RT1308_I2S_DL_SEL_32B (0x3 << 24)
#define RT1308_I2S_DL_SEL_8B (0x4 << 24)
#define RT1308_I2S_BCLK_MASK (0x1 << 14)
#define RT1308_I2S_BCLK_SFT 14
#define RT1308_I2S_BCLK_NORMAL (0x0 << 14)
#define RT1308_I2S_BCLK_INV (0x1 << 14)
/* Power Control-1 (0x32) */
#define RT1308_POW_MBIAS20U (0x1 << 31)
#define RT1308_POW_MBIAS20U_BIT 31
#define RT1308_POW_ALDO (0x1 << 30)
#define RT1308_POW_ALDO_BIT 30
#define RT1308_POW_DBG (0x1 << 29)
#define RT1308_POW_DBG_BIT 29
#define RT1308_POW_DACL (0x1 << 28)
#define RT1308_POW_DACL_BIT 28
#define RT1308_POW_DAC1 (0x1 << 27)
#define RT1308_POW_DAC1_BIT 27
#define RT1308_POW_CLK25M (0x1 << 26)
#define RT1308_POW_CLK25M_BIT 26
#define RT1308_POW_ADC_R (0x1 << 25)
#define RT1308_POW_ADC_R_BIT 25
#define RT1308_POW_ADC_L (0x1 << 24)
#define RT1308_POW_ADC_L_BIT 24
#define RT1308_POW_DLDO (0x1 << 21)
#define RT1308_POW_DLDO_BIT 21
#define RT1308_POW_VREF (0x1 << 20)
#define RT1308_POW_VREF_BIT 20
#define RT1308_POW_MIXER_R (0x1 << 18)
#define RT1308_POW_MIXER_R_BIT 18
#define RT1308_POW_MIXER_L (0x1 << 17)
#define RT1308_POW_MIXER_L_BIT 17
#define RT1308_POW_MBIAS4U (0x1 << 16)
#define RT1308_POW_MBIAS4U_BIT 16
#define RT1308_POW_PLL2_LDO_EN (0x1 << 12)
#define RT1308_POW_PLL2_LDO_EN_BIT 12
#define RT1308_POW_PLL2B_EN (0x1 << 11)
#define RT1308_POW_PLL2B_EN_BIT 11
#define RT1308_POW_PLL2F_EN (0x1 << 10)
#define RT1308_POW_PLL2F_EN_BIT 10
#define RT1308_POW_PLL2F2_EN (0x1 << 9)
#define RT1308_POW_PLL2F2_EN_BIT 9
#define RT1308_POW_PLL2B2_EN (0x1 << 8)
#define RT1308_POW_PLL2B2_EN_BIT 8
/* Power Control-2 (0x36) */
#define RT1308_POW_PDB_SRC_BIT (0x1 << 27)
#define RT1308_POW_PDB_MN_BIT (0x1 << 25)
#define RT1308_POW_PDB_REG_BIT (0x1 << 24)
/* System Clock Source */
enum {
RT1308_FS_SYS_S_MCLK,
RT1308_FS_SYS_S_BCLK,
RT1308_FS_SYS_S_PLL,
RT1308_FS_SYS_S_RCCLK, /* 25.0 MHz */
};
/* PLL Source */
enum {
RT1308_PLL_S_MCLK,
RT1308_PLL_S_BCLK,
RT1308_PLL_S_RCCLK,
};
enum {
RT1308_AIF1,
RT1308_AIFS
};
#endif /* end of _RT1308_H_ */

파일 보기

@@ -470,9 +470,7 @@ static int __maybe_unused rt5514_suspend(struct device *dev)
static int __maybe_unused rt5514_resume(struct device *dev)
{
struct snd_soc_component *component = snd_soc_lookup_component(dev, DRV_NAME);
struct rt5514_dsp *rt5514_dsp =
snd_soc_component_get_drvdata(component);
struct rt5514_dsp *rt5514_dsp = dev_get_drvdata(dev);
int irq = to_spi_device(dev)->irq;
u8 buf[8];

파일 보기

@@ -1478,7 +1478,7 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
{
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct rt5665_priv *rt5665 = snd_soc_component_get_drvdata(component);
int pd, idx = -EINVAL;
int pd, idx;
pd = rl6231_get_pre_div(rt5665->regmap,
RT5665_ADDA_CLK_1, RT5665_I2S_PD1_SFT);

파일 보기

@@ -26,6 +26,8 @@
#include "rt5677-spi.h"
#define DRV_NAME "rt5677spi"
#define RT5677_SPI_BURST_LEN 240
#define RT5677_SPI_HEADER 5
#define RT5677_SPI_FREQ 6000000
@@ -230,7 +232,7 @@ MODULE_DEVICE_TABLE(acpi, rt5677_spi_acpi_id);
static struct spi_driver rt5677_spi_driver = {
.driver = {
.name = "rt5677",
.name = DRV_NAME,
.acpi_match_table = ACPI_PTR(rt5677_spi_acpi_id),
},
.probe = rt5677_spi_probe,

파일 보기

@@ -20,6 +20,10 @@
#include <linux/firmware.h>
#include <linux/of_device.h>
#include <linux/property.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/workqueue.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -829,13 +833,13 @@ static const struct snd_kcontrol_new rt5677_snd_controls[] = {
/* DAC Digital Volume */
SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5677_DAC1_DIG_VOL,
RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 87, 0, dac_vol_tlv),
RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 127, 0, dac_vol_tlv),
SOC_DOUBLE_TLV("DAC2 Playback Volume", RT5677_DAC2_DIG_VOL,
RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 87, 0, dac_vol_tlv),
RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 127, 0, dac_vol_tlv),
SOC_DOUBLE_TLV("DAC3 Playback Volume", RT5677_DAC3_DIG_VOL,
RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 87, 0, dac_vol_tlv),
RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 127, 0, dac_vol_tlv),
SOC_DOUBLE_TLV("DAC4 Playback Volume", RT5677_DAC4_DIG_VOL,
RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 87, 0, dac_vol_tlv),
RT5677_L_VOL_SFT, RT5677_R_VOL_SFT, 127, 0, dac_vol_tlv),
/* IN1/IN2 Control */
SOC_SINGLE_TLV("IN1 Boost", RT5677_IN1, RT5677_BST_SFT1, 8, 0, bst_tlv),
@@ -2604,7 +2608,8 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY_S("I2S2 ASRC", 1, RT5677_ASRC_1, 1, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("I2S3 ASRC", 1, RT5677_ASRC_1, 2, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("I2S4 ASRC", 1, RT5677_ASRC_1, 3, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("DAC STO ASRC", 1, RT5677_ASRC_2, 14, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY_S("DAC STO ASRC", 1, RT5677_ASRC_2, 14, 0,
rt5677_filter_power_event, SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_SUPPLY_S("DAC MONO2 L ASRC", 1, RT5677_ASRC_2, 13, 0, NULL,
0),
SND_SOC_DAPM_SUPPLY_S("DAC MONO2 R ASRC", 1, RT5677_ASRC_2, 12, 0, NULL,
@@ -4617,7 +4622,6 @@ static void rt5677_gpio_config(struct rt5677_priv *rt5677, unsigned offset,
static int rt5677_to_irq(struct gpio_chip *chip, unsigned offset)
{
struct rt5677_priv *rt5677 = gpiochip_get_data(chip);
struct regmap_irq_chip_data *data = rt5677->irq_data;
int irq;
if ((rt5677->pdata.jd1_gpio == 1 && offset == RT5677_GPIO1) ||
@@ -4643,11 +4647,11 @@ static int rt5677_to_irq(struct gpio_chip *chip, unsigned offset)
return -ENXIO;
}
return regmap_irq_get_virq(data, irq);
return irq_create_mapping(rt5677->domain, irq);
}
static const struct gpio_chip rt5677_template_chip = {
.label = "rt5677",
.label = RT5677_DRV_NAME,
.owner = THIS_MODULE,
.direction_output = rt5677_gpio_direction_out,
.set = rt5677_gpio_set,
@@ -4713,37 +4717,13 @@ static int rt5677_probe(struct snd_soc_component *component)
snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
regmap_write(rt5677->regmap, RT5677_DIG_MISC, 0x0020);
regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC,
~RT5677_IRQ_DEBOUNCE_SEL_MASK, 0x0020);
regmap_write(rt5677->regmap, RT5677_PWR_DSP2, 0x0c00);
for (i = 0; i < RT5677_GPIO_NUM; i++)
rt5677_gpio_config(rt5677, i, rt5677->pdata.gpio_config[i]);
if (rt5677->irq_data) {
regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL1, 0x8000,
0x8000);
regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x0018,
0x0008);
if (rt5677->pdata.jd1_gpio)
regmap_update_bits(rt5677->regmap, RT5677_JD_CTRL1,
RT5677_SEL_GPIO_JD1_MASK,
rt5677->pdata.jd1_gpio <<
RT5677_SEL_GPIO_JD1_SFT);
if (rt5677->pdata.jd2_gpio)
regmap_update_bits(rt5677->regmap, RT5677_JD_CTRL1,
RT5677_SEL_GPIO_JD2_MASK,
rt5677->pdata.jd2_gpio <<
RT5677_SEL_GPIO_JD2_SFT);
if (rt5677->pdata.jd3_gpio)
regmap_update_bits(rt5677->regmap, RT5677_JD_CTRL1,
RT5677_SEL_GPIO_JD3_MASK,
rt5677->pdata.jd3_gpio <<
RT5677_SEL_GPIO_JD3_SFT);
}
mutex_init(&rt5677->dsp_cmd_lock);
mutex_init(&rt5677->dsp_pri_lock);
@@ -4955,6 +4935,7 @@ static struct snd_soc_dai_driver rt5677_dai[] = {
};
static const struct snd_soc_component_driver soc_component_dev_rt5677 = {
.name = RT5677_DRV_NAME,
.probe = rt5677_probe,
.remove = rt5677_remove,
.suspend = rt5677_suspend,
@@ -5016,80 +4997,202 @@ static const struct acpi_device_id rt5677_acpi_match[] = {
};
MODULE_DEVICE_TABLE(acpi, rt5677_acpi_match);
static void rt5677_read_acpi_properties(struct rt5677_priv *rt5677,
static void rt5677_read_device_properties(struct rt5677_priv *rt5677,
struct device *dev)
{
u32 val;
if (!device_property_read_u32(dev, "DCLK", &val))
rt5677->pdata.dmic2_clk_pin = val;
rt5677->pdata.in1_diff =
device_property_read_bool(dev, "IN1") ||
device_property_read_bool(dev, "realtek,in1-differential");
rt5677->pdata.in1_diff = device_property_read_bool(dev, "IN1");
rt5677->pdata.in2_diff = device_property_read_bool(dev, "IN2");
rt5677->pdata.lout1_diff = device_property_read_bool(dev, "OUT1");
rt5677->pdata.lout2_diff = device_property_read_bool(dev, "OUT2");
rt5677->pdata.lout3_diff = device_property_read_bool(dev, "OUT3");
rt5677->pdata.in2_diff =
device_property_read_bool(dev, "IN2") ||
device_property_read_bool(dev, "realtek,in2-differential");
device_property_read_u32(dev, "JD1", &rt5677->pdata.jd1_gpio);
device_property_read_u32(dev, "JD2", &rt5677->pdata.jd2_gpio);
device_property_read_u32(dev, "JD3", &rt5677->pdata.jd3_gpio);
}
rt5677->pdata.lout1_diff =
device_property_read_bool(dev, "OUT1") ||
device_property_read_bool(dev, "realtek,lout1-differential");
static void rt5677_read_device_properties(struct rt5677_priv *rt5677,
struct device *dev)
{
rt5677->pdata.in1_diff = device_property_read_bool(dev,
"realtek,in1-differential");
rt5677->pdata.in2_diff = device_property_read_bool(dev,
"realtek,in2-differential");
rt5677->pdata.lout1_diff = device_property_read_bool(dev,
"realtek,lout1-differential");
rt5677->pdata.lout2_diff = device_property_read_bool(dev,
"realtek,lout2-differential");
rt5677->pdata.lout3_diff = device_property_read_bool(dev,
"realtek,lout3-differential");
rt5677->pdata.lout2_diff =
device_property_read_bool(dev, "OUT2") ||
device_property_read_bool(dev, "realtek,lout2-differential");
rt5677->pdata.lout3_diff =
device_property_read_bool(dev, "OUT3") ||
device_property_read_bool(dev, "realtek,lout3-differential");
device_property_read_u8_array(dev, "realtek,gpio-config",
rt5677->pdata.gpio_config, RT5677_GPIO_NUM);
rt5677->pdata.gpio_config,
RT5677_GPIO_NUM);
device_property_read_u32(dev, "realtek,jd1-gpio",
&rt5677->pdata.jd1_gpio);
device_property_read_u32(dev, "realtek,jd2-gpio",
&rt5677->pdata.jd2_gpio);
device_property_read_u32(dev, "realtek,jd3-gpio",
&rt5677->pdata.jd3_gpio);
if (!device_property_read_u32(dev, "DCLK", &val) ||
!device_property_read_u32(dev, "realtek,dmic2_clk_pin", &val))
rt5677->pdata.dmic2_clk_pin = val;
if (!device_property_read_u32(dev, "JD1", &val) ||
!device_property_read_u32(dev, "realtek,jd1-gpio", &val))
rt5677->pdata.jd1_gpio = val;
if (!device_property_read_u32(dev, "JD2", &val) ||
!device_property_read_u32(dev, "realtek,jd2-gpio", &val))
rt5677->pdata.jd2_gpio = val;
if (!device_property_read_u32(dev, "JD3", &val) ||
!device_property_read_u32(dev, "realtek,jd3-gpio", &val))
rt5677->pdata.jd3_gpio = val;
}
static struct regmap_irq rt5677_irqs[] = {
struct rt5677_irq_desc {
unsigned int enable_mask;
unsigned int status_mask;
unsigned int polarity_mask;
};
static const struct rt5677_irq_desc rt5677_irq_descs[] = {
[RT5677_IRQ_JD1] = {
.reg_offset = 0,
.mask = RT5677_EN_IRQ_GPIO_JD1,
.enable_mask = RT5677_EN_IRQ_GPIO_JD1,
.status_mask = RT5677_STA_GPIO_JD1,
.polarity_mask = RT5677_INV_GPIO_JD1,
},
[RT5677_IRQ_JD2] = {
.reg_offset = 0,
.mask = RT5677_EN_IRQ_GPIO_JD2,
.enable_mask = RT5677_EN_IRQ_GPIO_JD2,
.status_mask = RT5677_STA_GPIO_JD2,
.polarity_mask = RT5677_INV_GPIO_JD2,
},
[RT5677_IRQ_JD3] = {
.reg_offset = 0,
.mask = RT5677_EN_IRQ_GPIO_JD3,
.enable_mask = RT5677_EN_IRQ_GPIO_JD3,
.status_mask = RT5677_STA_GPIO_JD3,
.polarity_mask = RT5677_INV_GPIO_JD3,
},
};
static struct regmap_irq_chip rt5677_irq_chip = {
.name = "rt5677",
.irqs = rt5677_irqs,
.num_irqs = ARRAY_SIZE(rt5677_irqs),
static irqreturn_t rt5677_irq(int unused, void *data)
{
struct rt5677_priv *rt5677 = data;
int ret = 0, loop, i, reg_irq, virq;
bool irq_fired = false;
.num_regs = 1,
.status_base = RT5677_IRQ_CTRL1,
.mask_base = RT5677_IRQ_CTRL1,
.mask_invert = 1,
mutex_lock(&rt5677->irq_lock);
/*
* Loop to handle interrupts until the last i2c read shows no pending
* irqs. The interrupt line is shared by multiple interrupt sources.
* After the regmap_read() below, a new interrupt source line may
* become high before the regmap_write() finishes, so there isn't a
* rising edge on the shared interrupt line for the new interrupt. Thus,
* the loop is needed to avoid missing irqs.
*
* A safeguard of 20 loops is used to avoid hanging in the irq handler
* if there is something wrong with the interrupt status update. The
* interrupt sources here are audio jack plug/unplug events which
* shouldn't happen at a high frequency for a long period of time.
* Empirically, more than 3 loops have never been seen.
*/
for (loop = 0; loop < 20; loop++) {
/* Read interrupt status */
ret = regmap_read(rt5677->regmap, RT5677_IRQ_CTRL1, &reg_irq);
if (ret) {
dev_err(rt5677->dev, "failed reading IRQ status: %d\n",
ret);
goto exit;
}
irq_fired = false;
for (i = 0; i < RT5677_IRQ_NUM; i++) {
if (reg_irq & rt5677_irq_descs[i].status_mask) {
irq_fired = true;
virq = irq_find_mapping(rt5677->domain, i);
if (virq)
handle_nested_irq(virq);
/* Clear the interrupt by flipping the polarity
* of the interrupt source line that fired
*/
reg_irq ^= rt5677_irq_descs[i].polarity_mask;
}
}
if (!irq_fired)
goto exit;
ret = regmap_write(rt5677->regmap, RT5677_IRQ_CTRL1, reg_irq);
if (ret) {
dev_err(rt5677->dev, "failed updating IRQ status: %d\n",
ret);
goto exit;
}
}
exit:
mutex_unlock(&rt5677->irq_lock);
if (irq_fired)
return IRQ_HANDLED;
else
return IRQ_NONE;
}
static void rt5677_irq_bus_lock(struct irq_data *data)
{
struct rt5677_priv *rt5677 = irq_data_get_irq_chip_data(data);
mutex_lock(&rt5677->irq_lock);
}
static void rt5677_irq_bus_sync_unlock(struct irq_data *data)
{
struct rt5677_priv *rt5677 = irq_data_get_irq_chip_data(data);
// Set the enable/disable bits for the jack detect IRQs.
regmap_update_bits(rt5677->regmap, RT5677_IRQ_CTRL1,
RT5677_EN_IRQ_GPIO_JD1 | RT5677_EN_IRQ_GPIO_JD2 |
RT5677_EN_IRQ_GPIO_JD3, rt5677->irq_en);
mutex_unlock(&rt5677->irq_lock);
}
static void rt5677_irq_enable(struct irq_data *data)
{
struct rt5677_priv *rt5677 = irq_data_get_irq_chip_data(data);
rt5677->irq_en |= rt5677_irq_descs[data->hwirq].enable_mask;
}
static void rt5677_irq_disable(struct irq_data *data)
{
struct rt5677_priv *rt5677 = irq_data_get_irq_chip_data(data);
rt5677->irq_en &= ~rt5677_irq_descs[data->hwirq].enable_mask;
}
static struct irq_chip rt5677_irq_chip = {
.name = "rt5677_irq_chip",
.irq_bus_lock = rt5677_irq_bus_lock,
.irq_bus_sync_unlock = rt5677_irq_bus_sync_unlock,
.irq_disable = rt5677_irq_disable,
.irq_enable = rt5677_irq_enable,
};
static int rt5677_irq_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
struct rt5677_priv *rt5677 = h->host_data;
irq_set_chip_data(virq, rt5677);
irq_set_chip(virq, &rt5677_irq_chip);
irq_set_nested_thread(virq, 1);
irq_set_noprobe(virq);
return 0;
}
static const struct irq_domain_ops rt5677_domain_ops = {
.map = rt5677_irq_map,
.xlate = irq_domain_xlate_twocell,
};
static int rt5677_init_irq(struct i2c_client *i2c)
{
int ret;
struct rt5677_priv *rt5677 = i2c_get_clientdata(i2c);
unsigned int jd_mask = 0, jd_val = 0;
if (!rt5677->pdata.jd1_gpio &&
!rt5677->pdata.jd2_gpio &&
@@ -5101,24 +5204,53 @@ static int rt5677_init_irq(struct i2c_client *i2c)
return -EINVAL;
}
ret = regmap_add_irq_chip(rt5677->regmap, i2c->irq,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 0,
&rt5677_irq_chip, &rt5677->irq_data);
mutex_init(&rt5677->irq_lock);
if (ret != 0) {
dev_err(&i2c->dev, "Failed to register IRQ chip: %d\n", ret);
return ret;
/*
* Select RC as the debounce clock so that GPIO works even when
* MCLK is gated which happens when there is no audio stream
* (SND_SOC_BIAS_OFF).
*/
regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC,
RT5677_IRQ_DEBOUNCE_SEL_MASK,
RT5677_IRQ_DEBOUNCE_SEL_RC);
/* Enable auto power on RC when GPIO states are changed */
regmap_update_bits(rt5677->regmap, RT5677_GEN_CTRL1, 0xff, 0xff);
/* Select and enable jack detection sources per platform data */
if (rt5677->pdata.jd1_gpio) {
jd_mask |= RT5677_SEL_GPIO_JD1_MASK;
jd_val |= rt5677->pdata.jd1_gpio << RT5677_SEL_GPIO_JD1_SFT;
}
if (rt5677->pdata.jd2_gpio) {
jd_mask |= RT5677_SEL_GPIO_JD2_MASK;
jd_val |= rt5677->pdata.jd2_gpio << RT5677_SEL_GPIO_JD2_SFT;
}
if (rt5677->pdata.jd3_gpio) {
jd_mask |= RT5677_SEL_GPIO_JD3_MASK;
jd_val |= rt5677->pdata.jd3_gpio << RT5677_SEL_GPIO_JD3_SFT;
}
regmap_update_bits(rt5677->regmap, RT5677_JD_CTRL1, jd_mask, jd_val);
/* Set GPIO1 pin to be IRQ output */
regmap_update_bits(rt5677->regmap, RT5677_GPIO_CTRL1,
RT5677_GPIO1_PIN_MASK, RT5677_GPIO1_PIN_IRQ);
/* Ready to listen for interrupts */
rt5677->domain = irq_domain_add_linear(i2c->dev.of_node,
RT5677_IRQ_NUM, &rt5677_domain_ops, rt5677);
if (!rt5677->domain) {
dev_err(&i2c->dev, "Failed to create IRQ domain\n");
return -ENOMEM;
}
return 0;
}
ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL, rt5677_irq,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
"rt5677", rt5677);
if (ret)
dev_err(&i2c->dev, "Failed to request IRQ: %d\n", ret);
static void rt5677_free_irq(struct i2c_client *i2c)
{
struct rt5677_priv *rt5677 = i2c_get_clientdata(i2c);
if (rt5677->irq_data)
regmap_del_irq_chip(i2c->irq, rt5677->irq_data);
return ret;
}
static int rt5677_i2c_probe(struct i2c_client *i2c)
@@ -5132,6 +5264,7 @@ static int rt5677_i2c_probe(struct i2c_client *i2c)
if (rt5677 == NULL)
return -ENOMEM;
rt5677->dev = &i2c->dev;
i2c_set_clientdata(i2c, rt5677);
if (i2c->dev.of_node) {
@@ -5140,20 +5273,18 @@ static int rt5677_i2c_probe(struct i2c_client *i2c)
match_id = of_match_device(rt5677_of_match, &i2c->dev);
if (match_id)
rt5677->type = (enum rt5677_type)match_id->data;
rt5677_read_device_properties(rt5677, &i2c->dev);
} else if (ACPI_HANDLE(&i2c->dev)) {
const struct acpi_device_id *acpi_id;
acpi_id = acpi_match_device(rt5677_acpi_match, &i2c->dev);
if (acpi_id)
rt5677->type = (enum rt5677_type)acpi_id->driver_data;
rt5677_read_acpi_properties(rt5677, &i2c->dev);
} else {
return -EINVAL;
}
rt5677_read_device_properties(rt5677, &i2c->dev);
/* pow-ldo2 and reset are optional. The codec pins may be statically
* connected on the board without gpios. If the gpio device property
* isn't specified, devm_gpiod_get_optional returns NULL.
@@ -5247,7 +5378,9 @@ static int rt5677_i2c_probe(struct i2c_client *i2c)
RT5677_MICBIAS1_CTRL_VDD_3_3V);
rt5677_init_gpio(i2c);
rt5677_init_irq(i2c);
ret = rt5677_init_irq(i2c);
if (ret)
dev_err(&i2c->dev, "Failed to initialize irq: %d\n", ret);
return devm_snd_soc_register_component(&i2c->dev,
&soc_component_dev_rt5677,
@@ -5256,7 +5389,6 @@ static int rt5677_i2c_probe(struct i2c_client *i2c)
static int rt5677_i2c_remove(struct i2c_client *i2c)
{
rt5677_free_irq(i2c);
rt5677_free_gpio(i2c);
return 0;
@@ -5264,7 +5396,7 @@ static int rt5677_i2c_remove(struct i2c_client *i2c)
static struct i2c_driver rt5677_i2c_driver = {
.driver = {
.name = "rt5677",
.name = RT5677_DRV_NAME,
.of_match_table = rt5677_of_match,
.acpi_match_table = ACPI_PTR(rt5677_acpi_match),
},

파일 보기

@@ -1453,9 +1453,37 @@
#define RT5677_I2S4_CLK_SEL_MASK (0xf)
#define RT5677_I2S4_CLK_SEL_SFT 0
/* VAD Function Control 1 (0x9c) */
#define RT5677_VAD_MIN_DUR_MASK (0x3 << 13)
#define RT5677_VAD_MIN_DUR_SFT 13
#define RT5677_VAD_ADPCM_BYPASS (1 << 10)
#define RT5677_VAD_ADPCM_BYPASS_BIT 10
#define RT5677_VAD_FG2ENC (1 << 9)
#define RT5677_VAD_FG2ENC_BIT 9
#define RT5677_VAD_BUF_OW (1 << 8)
#define RT5677_VAD_BUF_OW_BIT 8
#define RT5677_VAD_CLR_FLAG (1 << 7)
#define RT5677_VAD_CLR_FLAG_BIT 7
#define RT5677_VAD_BUF_POP (1 << 6)
#define RT5677_VAD_BUF_POP_BIT 6
#define RT5677_VAD_BUF_PUSH (1 << 5)
#define RT5677_VAD_BUF_PUSH_BIT 5
#define RT5677_VAD_DET_ENABLE (1 << 4)
#define RT5677_VAD_DET_ENABLE_BIT 4
#define RT5677_VAD_FUNC_ENABLE (1 << 3)
#define RT5677_VAD_FUNC_ENABLE_BIT 3
#define RT5677_VAD_FUNC_RESET (1 << 2)
#define RT5677_VAD_FUNC_RESET_BIT 2
/* VAD Function Control 4 (0x9f) */
#define RT5677_VAD_SRC_MASK (0x7 << 8)
#define RT5677_VAD_OUT_SRC_RATE_MASK (0x1 << 11)
#define RT5677_VAD_OUT_SRC_RATE_SFT 11
#define RT5677_VAD_OUT_SRC_MASK (0x1 << 10)
#define RT5677_VAD_OUT_SRC_SFT 10
#define RT5677_VAD_SRC_MASK (0x3 << 8)
#define RT5677_VAD_SRC_SFT 8
#define RT5677_VAD_LV_DIFF_MASK (0xff << 0)
#define RT5677_VAD_LV_DIFF_SFT 0
/* DSP InBound Control (0xa3) */
#define RT5677_IB01_SRC_MASK (0x7 << 12)
@@ -1633,6 +1661,12 @@
#define RT5677_GPIO6_P_NOR (0x0 << 0)
#define RT5677_GPIO6_P_INV (0x1 << 0)
/* General Control (0xfa) */
#define RT5677_IRQ_DEBOUNCE_SEL_MASK (0x3 << 3)
#define RT5677_IRQ_DEBOUNCE_SEL_MCLK (0x0 << 3)
#define RT5677_IRQ_DEBOUNCE_SEL_RC (0x1 << 3)
#define RT5677_IRQ_DEBOUNCE_SEL_SLIM (0x2 << 3)
/* Virtual DSP Mixer Control (0xf7 0xf8 0xf9) */
#define RT5677_DSP_IB_01_H (0x1 << 15)
#define RT5677_DSP_IB_01_H_SFT 15
@@ -1671,6 +1705,8 @@
#define RT5677_FIRMWARE1 "rt5677_dsp_fw1.bin"
#define RT5677_FIRMWARE2 "rt5677_dsp_fw2.bin"
#define RT5677_DRV_NAME "rt5677"
/* System Clock Source */
enum {
RT5677_SCLK_S_MCLK,
@@ -1710,6 +1746,7 @@ enum {
RT5677_IRQ_JD1,
RT5677_IRQ_JD2,
RT5677_IRQ_JD3,
RT5677_IRQ_NUM,
};
enum rt5677_type {
@@ -1788,6 +1825,7 @@ struct rt5677_platform_data {
struct rt5677_priv {
struct snd_soc_component *component;
struct device *dev;
struct rt5677_platform_data pdata;
struct regmap *regmap, *regmap_physical;
const struct firmware *fw1, *fw2;
@@ -1808,9 +1846,13 @@ struct rt5677_priv {
struct gpio_chip gpio_chip;
#endif
bool dsp_vad_en;
struct regmap_irq_chip_data *irq_data;
bool is_dsp_mode;
bool is_vref_slow;
/* Interrupt handling */
struct irq_domain *domain;
struct mutex irq_lock;
unsigned int irq_en;
};
int rt5677_sel_asrc_clk_src(struct snd_soc_component *component,

파일 보기

@@ -2662,15 +2662,9 @@ static int rt5682_i2c_probe(struct i2c_client *i2c,
}
return snd_soc_register_component(&i2c->dev, &soc_component_dev_rt5682,
rt5682_dai, ARRAY_SIZE(rt5682_dai));
}
static int rt5682_i2c_remove(struct i2c_client *i2c)
{
snd_soc_unregister_component(&i2c->dev);
return 0;
return devm_snd_soc_register_component(&i2c->dev,
&soc_component_dev_rt5682,
rt5682_dai, ARRAY_SIZE(rt5682_dai));
}
static void rt5682_i2c_shutdown(struct i2c_client *client)
@@ -2703,7 +2697,6 @@ static struct i2c_driver rt5682_i2c_driver = {
.acpi_match_table = ACPI_PTR(rt5682_acpi_match),
},
.probe = rt5682_i2c_probe,
.remove = rt5682_i2c_remove,
.shutdown = rt5682_i2c_shutdown,
.id_table = rt5682_i2c_id,
};

파일 보기

@@ -721,8 +721,8 @@ static const struct regmap_config tas5721_regmap_config = {
static const struct tas571x_chip tas5721_chip = {
.supply_names = tas5721_supply_names,
.num_supply_names = ARRAY_SIZE(tas5721_supply_names),
.controls = tas5711_controls,
.num_controls = ARRAY_SIZE(tas5711_controls),
.controls = tas5721_controls,
.num_controls = ARRAY_SIZE(tas5721_controls),
.regmap_config = &tas5721_regmap_config,
.vol_reg_size = 1,
};

파일 보기

@@ -321,6 +321,9 @@ static DECLARE_TLV_DB_SCALE(adc_tlv, 0, 50, 0);
*/
static DECLARE_TLV_DB_SCALE(output_stage_tlv, -5900, 50, 1);
/* Output volumes. From 0 to 9 dB in 1 dB steps */
static const DECLARE_TLV_DB_SCALE(out_tlv, 0, 100, 0);
static const struct snd_kcontrol_new aic3x_snd_controls[] = {
/* Output */
SOC_DOUBLE_R_TLV("PCM Playback Volume",
@@ -383,11 +386,17 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
DACL1_2_HPLCOM_VOL, DACR1_2_HPRCOM_VOL,
0, 118, 1, output_stage_tlv),
/* Output pin mute controls */
/* Output pin controls */
SOC_DOUBLE_R_TLV("Line Playback Volume", LLOPM_CTRL, RLOPM_CTRL, 4,
9, 0, out_tlv),
SOC_DOUBLE_R("Line Playback Switch", LLOPM_CTRL, RLOPM_CTRL, 3,
0x01, 0),
SOC_DOUBLE_R_TLV("HP Playback Volume", HPLOUT_CTRL, HPROUT_CTRL, 4,
9, 0, out_tlv),
SOC_DOUBLE_R("HP Playback Switch", HPLOUT_CTRL, HPROUT_CTRL, 3,
0x01, 0),
SOC_DOUBLE_R_TLV("HPCOM Playback Volume", HPLCOM_CTRL, HPRCOM_CTRL,
4, 9, 0, out_tlv),
SOC_DOUBLE_R("HPCOM Playback Switch", HPLCOM_CTRL, HPRCOM_CTRL, 3,
0x01, 0),
@@ -469,6 +478,9 @@ static const struct snd_kcontrol_new aic3x_mono_controls[] = {
0, 118, 1, output_stage_tlv),
SOC_SINGLE("Mono Playback Switch", MONOLOPM_CTRL, 3, 0x01, 0),
SOC_SINGLE_TLV("Mono Playback Volume", MONOLOPM_CTRL, 4, 9, 0,
out_tlv),
};
/*

파일 보기

@@ -86,11 +86,6 @@
#define WCD9335_DEC_PWR_LVL_HP 0x04
#define WCD9335_DEC_PWR_LVL_DF 0x00
#define TX_HPF_CUT_OFF_FREQ_MASK 0x60
#define CF_MIN_3DB_4HZ 0x0
#define CF_MIN_3DB_75HZ 0x1
#define CF_MIN_3DB_150HZ 0x2
#define WCD9335_SLIM_RX_CH(p) \
{.port = p + WCD9335_RX_START, .shift = p,}
@@ -2734,7 +2729,7 @@ static int wcd9335_codec_enable_dec(struct snd_soc_dapm_widget *w,
char *dec;
u8 hpf_coff_freq;
widget_name = kstrndup(w->name, 15, GFP_KERNEL);
widget_name = kmemdup_nul(w->name, 15, GFP_KERNEL);
if (!widget_name)
return -ENOMEM;

파일 보기

@@ -728,41 +728,18 @@ static void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
struct dentry *root = NULL;
int i;
if (!component->debugfs_root) {
adsp_err(dsp, "No codec debugfs root\n");
goto err;
}
root = debugfs_create_dir(dsp->name, component->debugfs_root);
if (!root)
goto err;
debugfs_create_bool("booted", 0444, root, &dsp->booted);
debugfs_create_bool("running", 0444, root, &dsp->running);
debugfs_create_x32("fw_id", 0444, root, &dsp->fw_id);
debugfs_create_x32("fw_version", 0444, root, &dsp->fw_id_version);
if (!debugfs_create_bool("booted", 0444, root, &dsp->booted))
goto err;
if (!debugfs_create_bool("running", 0444, root, &dsp->running))
goto err;
if (!debugfs_create_x32("fw_id", 0444, root, &dsp->fw_id))
goto err;
if (!debugfs_create_x32("fw_version", 0444, root, &dsp->fw_id_version))
goto err;
for (i = 0; i < ARRAY_SIZE(wm_adsp_debugfs_fops); ++i) {
if (!debugfs_create_file(wm_adsp_debugfs_fops[i].name,
0444, root, dsp,
&wm_adsp_debugfs_fops[i].fops))
goto err;
}
for (i = 0; i < ARRAY_SIZE(wm_adsp_debugfs_fops); ++i)
debugfs_create_file(wm_adsp_debugfs_fops[i].name, 0444, root,
dsp, &wm_adsp_debugfs_fops[i].fops);
dsp->debugfs_root = root;
return;
err:
debugfs_remove_recursive(root);
adsp_err(dsp, "Failed to create debugfs\n");
}
static void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp)

파일 보기

@@ -29,22 +29,28 @@
#define DRV_NAME "efika-audio-fabric"
SND_SOC_DAILINK_DEFS(analog,
DAILINK_COMP_ARRAY(COMP_CPU("mpc5200-psc-ac97.0")),
DAILINK_COMP_ARRAY(COMP_CODEC("stac9766-codec",
"stac9766-hifi-analog")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("mpc5200-pcm-audio")));
SND_SOC_DAILINK_DEFS(iec958,
DAILINK_COMP_ARRAY(COMP_CPU("mpc5200-psc-ac97.1")),
DAILINK_COMP_ARRAY(COMP_CODEC("stac9766-codec",
"stac9766-hifi-IEC958")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("mpc5200-pcm-audio")));
static struct snd_soc_dai_link efika_fabric_dai[] = {
{
.name = "AC97",
.stream_name = "AC97 Analog",
.codec_dai_name = "stac9766-hifi-analog",
.cpu_dai_name = "mpc5200-psc-ac97.0",
.platform_name = "mpc5200-pcm-audio",
.codec_name = "stac9766-codec",
SND_SOC_DAILINK_REG(analog),
},
{
.name = "AC97",
.stream_name = "AC97 IEC958",
.codec_dai_name = "stac9766-hifi-IEC958",
.cpu_dai_name = "mpc5200-psc-ac97.1",
.platform_name = "mpc5200-pcm-audio",
.codec_name = "stac9766-codec",
SND_SOC_DAILINK_REG(iec958),
},
};

파일 보기

@@ -61,13 +61,18 @@ static const struct snd_soc_ops eukrea_tlv320_snd_ops = {
.hw_params = eukrea_tlv320_hw_params,
};
SND_SOC_DAILINK_DEFS(hifi,
DAILINK_COMP_ARRAY(COMP_EMPTY()),
DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "tlv320aic23-hifi")),
DAILINK_COMP_ARRAY(COMP_EMPTY()));
static struct snd_soc_dai_link eukrea_tlv320_dai = {
.name = "tlv320aic23",
.stream_name = "TLV320AIC23",
.codec_dai_name = "tlv320aic23-hifi",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM,
.ops = &eukrea_tlv320_snd_ops,
SND_SOC_DAILINK_REG(hifi),
};
static struct snd_soc_card eukrea_tlv320 = {
@@ -104,7 +109,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
codec_np = of_parse_phandle(ssi_np, "codec-handle", 0);
if (codec_np)
eukrea_tlv320_dai.codec_of_node = codec_np;
eukrea_tlv320_dai.codecs->of_node = codec_np;
else
dev_err(&pdev->dev, "codec-handle node missing or invalid.\n");
@@ -128,12 +133,12 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
int_port--;
ext_port--;
eukrea_tlv320_dai.cpu_of_node = ssi_np;
eukrea_tlv320_dai.platform_of_node = ssi_np;
eukrea_tlv320_dai.cpus->of_node = ssi_np;
eukrea_tlv320_dai.platforms->of_node = ssi_np;
} else {
eukrea_tlv320_dai.cpu_dai_name = "imx-ssi.0";
eukrea_tlv320_dai.platform_name = "imx-ssi.0";
eukrea_tlv320_dai.codec_name = "tlv320aic23-codec.0-001a";
eukrea_tlv320_dai.cpus->dai_name = "imx-ssi.0";
eukrea_tlv320_dai.platforms->name = "imx-ssi.0";
eukrea_tlv320_dai.codecs->name = "tlv320aic23-codec.0-001a";
eukrea_tlv320.name = "cpuimx-audio";
}

파일 보기

@@ -200,32 +200,47 @@ static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
return 0;
}
SND_SOC_DAILINK_DEFS(hifi,
DAILINK_COMP_ARRAY(COMP_EMPTY()),
DAILINK_COMP_ARRAY(COMP_EMPTY()),
DAILINK_COMP_ARRAY(COMP_EMPTY()));
SND_SOC_DAILINK_DEFS(hifi_fe,
DAILINK_COMP_ARRAY(COMP_EMPTY()),
DAILINK_COMP_ARRAY(COMP_DUMMY()),
DAILINK_COMP_ARRAY(COMP_EMPTY()));
SND_SOC_DAILINK_DEFS(hifi_be,
DAILINK_COMP_ARRAY(COMP_EMPTY()),
DAILINK_COMP_ARRAY(COMP_EMPTY()),
DAILINK_COMP_ARRAY(COMP_DUMMY()));
static struct snd_soc_dai_link fsl_asoc_card_dai[] = {
/* Default ASoC DAI Link*/
{
.name = "HiFi",
.stream_name = "HiFi",
.ops = &fsl_asoc_card_ops,
SND_SOC_DAILINK_REG(hifi),
},
/* DPCM Link between Front-End and Back-End (Optional) */
{
.name = "HiFi-ASRC-FE",
.stream_name = "HiFi-ASRC-FE",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.dpcm_playback = 1,
.dpcm_capture = 1,
.dynamic = 1,
SND_SOC_DAILINK_REG(hifi_fe),
},
{
.name = "HiFi-ASRC-BE",
.stream_name = "HiFi-ASRC-BE",
.platform_name = "snd-soc-dummy",
.be_hw_params_fixup = be_hw_params_fixup,
.ops = &fsl_asoc_card_ops,
.dpcm_playback = 1,
.dpcm_capture = 1,
.no_pcm = 1,
SND_SOC_DAILINK_REG(hifi_be),
},
};
@@ -616,11 +631,11 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
}
/* Normal DAI Link */
priv->dai_link[0].cpu_of_node = cpu_np;
priv->dai_link[0].codec_dai_name = codec_dai_name;
priv->dai_link[0].cpus->of_node = cpu_np;
priv->dai_link[0].codecs->dai_name = codec_dai_name;
if (!fsl_asoc_card_is_ac97(priv))
priv->dai_link[0].codec_of_node = codec_np;
priv->dai_link[0].codecs->of_node = codec_np;
else {
u32 idx;
@@ -631,29 +646,29 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
goto asrc_fail;
}
priv->dai_link[0].codec_name =
priv->dai_link[0].codecs->name =
devm_kasprintf(&pdev->dev, GFP_KERNEL,
"ac97-codec.%u",
(unsigned int)idx);
if (!priv->dai_link[0].codec_name) {
if (!priv->dai_link[0].codecs->name) {
ret = -ENOMEM;
goto asrc_fail;
}
}
priv->dai_link[0].platform_of_node = cpu_np;
priv->dai_link[0].platforms->of_node = cpu_np;
priv->dai_link[0].dai_fmt = priv->dai_fmt;
priv->card.num_links = 1;
if (asrc_pdev) {
/* DPCM DAI Links only if ASRC exsits */
priv->dai_link[1].cpu_of_node = asrc_np;
priv->dai_link[1].platform_of_node = asrc_np;
priv->dai_link[2].codec_dai_name = codec_dai_name;
priv->dai_link[2].codec_of_node = codec_np;
priv->dai_link[2].codec_name =
priv->dai_link[0].codec_name;
priv->dai_link[2].cpu_of_node = cpu_np;
priv->dai_link[1].cpus->of_node = asrc_np;
priv->dai_link[1].platforms->of_node = asrc_np;
priv->dai_link[2].codecs->dai_name = codec_dai_name;
priv->dai_link[2].codecs->of_node = codec_np;
priv->dai_link[2].codecs->name =
priv->dai_link[0].codecs->name;
priv->dai_link[2].cpus->of_node = cpu_np;
priv->dai_link[2].dai_fmt = priv->dai_fmt;
priv->card.num_links = 3;

파일 보기

@@ -26,32 +26,15 @@
#define pair_dbg(fmt, ...) \
dev_dbg(&asrc_priv->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
/* Sample rates are aligned with that defined in pcm.h file */
static const u8 process_option[][12][2] = {
/* 8kHz 11.025kHz 16kHz 22.05kHz 32kHz 44.1kHz 48kHz 64kHz 88.2kHz 96kHz 176kHz 192kHz */
{{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 5512Hz */
{{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 8kHz */
{{0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 11025Hz */
{{1, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 16kHz */
{{1, 2}, {1, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},}, /* 22050Hz */
{{1, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0},}, /* 32kHz */
{{2, 2}, {2, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 44.1kHz */
{{2, 2}, {2, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},}, /* 48kHz */
{{2, 2}, {2, 2}, {2, 2}, {2, 1}, {1, 2}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0},}, /* 64kHz */
{{2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 88.2kHz */
{{2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},}, /* 96kHz */
{{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 176kHz */
{{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},}, /* 192kHz */
};
/* Corresponding to process_option */
static int supported_input_rate[] = {
5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200,
96000, 176400, 192000,
static unsigned int supported_asrc_rate[] = {
5512, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
64000, 88200, 96000, 128000, 176400, 192000,
};
static int supported_asrc_rate[] = {
8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000,
static struct snd_pcm_hw_constraint_list fsl_asrc_rate_constraints = {
.count = ARRAY_SIZE(supported_asrc_rate),
.list = supported_asrc_rate,
};
/**
@@ -79,6 +62,52 @@ static unsigned char output_clk_map_imx53[] = {
static unsigned char *clk_map[2];
/**
* Select the pre-processing and post-processing options
* Make sure to exclude following unsupported cases before
* calling this function:
* 1) inrate > 8.125 * outrate
* 2) inrate > 16.125 * outrate
*
* inrate: input sample rate
* outrate: output sample rate
* pre_proc: return value for pre-processing option
* post_proc: return value for post-processing option
*/
static void fsl_asrc_sel_proc(int inrate, int outrate,
int *pre_proc, int *post_proc)
{
bool post_proc_cond2;
bool post_proc_cond0;
/* select pre_proc between [0, 2] */
if (inrate * 8 > 33 * outrate)
*pre_proc = 2;
else if (inrate * 8 > 15 * outrate) {
if (inrate > 152000)
*pre_proc = 2;
else
*pre_proc = 1;
} else if (inrate < 76000)
*pre_proc = 0;
else if (inrate > 152000)
*pre_proc = 2;
else
*pre_proc = 1;
/* Condition for selection of post-processing */
post_proc_cond2 = (inrate * 15 > outrate * 16 && outrate < 56000) ||
(inrate > 56000 && outrate < 56000);
post_proc_cond0 = inrate * 23 < outrate * 8;
if (post_proc_cond2)
*post_proc = 2;
else if (post_proc_cond0)
*post_proc = 0;
else
*post_proc = 1;
}
/**
* Request ASRC pair
*
@@ -239,6 +268,7 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
u32 inrate, outrate, indiv, outdiv;
u32 clk_index[2], div[2];
int in, out, channels;
int pre_proc, post_proc;
struct clk *clk;
bool ideal;
@@ -264,11 +294,11 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
ideal = config->inclk == INCLK_NONE;
/* Validate input and output sample rates */
for (in = 0; in < ARRAY_SIZE(supported_input_rate); in++)
if (inrate == supported_input_rate[in])
for (in = 0; in < ARRAY_SIZE(supported_asrc_rate); in++)
if (inrate == supported_asrc_rate[in])
break;
if (in == ARRAY_SIZE(supported_input_rate)) {
if (in == ARRAY_SIZE(supported_asrc_rate)) {
pair_err("unsupported input sample rate: %dHz\n", inrate);
return -EINVAL;
}
@@ -282,7 +312,7 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
return -EINVAL;
}
if ((outrate >= 8000 && outrate <= 30000) &&
if ((outrate >= 5512 && outrate <= 30000) &&
(outrate > 24 * inrate || inrate > 8 * outrate)) {
pair_err("exceed supported ratio range [1/24, 8] for \
inrate/outrate: %d/%d\n", inrate, outrate);
@@ -377,11 +407,13 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
ASRCTR_IDRi_MASK(index) | ASRCTR_USRi_MASK(index),
ASRCTR_IDR(index) | ASRCTR_USR(index));
fsl_asrc_sel_proc(inrate, outrate, &pre_proc, &post_proc);
/* Apply configurations for pre- and post-processing */
regmap_update_bits(asrc_priv->regmap, REG_ASRCFG,
ASRCFG_PREMODi_MASK(index) | ASRCFG_POSTMODi_MASK(index),
ASRCFG_PREMOD(index, process_option[in][out][0]) |
ASRCFG_POSTMOD(index, process_option[in][out][1]));
ASRCFG_PREMOD(index, pre_proc) |
ASRCFG_POSTMOD(index, post_proc));
return fsl_asrc_set_ideal_ratio(pair, inrate, outrate);
}
@@ -455,7 +487,9 @@ static int fsl_asrc_dai_startup(struct snd_pcm_substream *substream,
snd_pcm_hw_constraint_step(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_CHANNELS, 2);
return 0;
return snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE, &fsl_asrc_rate_constraints);
}
static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
@@ -568,7 +602,6 @@ static int fsl_asrc_dai_probe(struct snd_soc_dai *dai)
return 0;
}
#define FSL_ASRC_RATES SNDRV_PCM_RATE_8000_192000
#define FSL_ASRC_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S20_3LE)
@@ -579,14 +612,18 @@ static struct snd_soc_dai_driver fsl_asrc_dai = {
.stream_name = "ASRC-Playback",
.channels_min = 1,
.channels_max = 10,
.rates = FSL_ASRC_RATES,
.rate_min = 5512,
.rate_max = 192000,
.rates = SNDRV_PCM_RATE_KNOT,
.formats = FSL_ASRC_FORMATS,
},
.capture = {
.stream_name = "ASRC-Capture",
.channels_min = 1,
.channels_max = 10,
.rates = FSL_ASRC_RATES,
.rate_min = 5512,
.rate_max = 192000,
.rates = SNDRV_PCM_RATE_KNOT,
.formats = FSL_ASRC_FORMATS,
},
.ops = &fsl_asrc_dai_ops,

파일 보기

@@ -9,6 +9,7 @@
#include <linux/module.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/pm_runtime.h>
#include <sound/dmaengine_pcm.h>
#include <sound/pcm_params.h>
@@ -466,30 +467,6 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
int ret;
/*
* Some platforms might use the same bit to gate all three or two of
* clocks, so keep all clocks open/close at the same time for safety
*/
ret = clk_prepare_enable(esai_priv->coreclk);
if (ret)
return ret;
if (!IS_ERR(esai_priv->spbaclk)) {
ret = clk_prepare_enable(esai_priv->spbaclk);
if (ret)
goto err_spbaclk;
}
if (!IS_ERR(esai_priv->extalclk)) {
ret = clk_prepare_enable(esai_priv->extalclk);
if (ret)
goto err_extalck;
}
if (!IS_ERR(esai_priv->fsysclk)) {
ret = clk_prepare_enable(esai_priv->fsysclk);
if (ret)
goto err_fsysclk;
}
if (!dai->active) {
/* Set synchronous mode */
@@ -506,16 +483,6 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream,
return 0;
err_fsysclk:
if (!IS_ERR(esai_priv->extalclk))
clk_disable_unprepare(esai_priv->extalclk);
err_extalck:
if (!IS_ERR(esai_priv->spbaclk))
clk_disable_unprepare(esai_priv->spbaclk);
err_spbaclk:
clk_disable_unprepare(esai_priv->coreclk);
return ret;
}
static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
@@ -576,20 +543,6 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
return 0;
}
static void fsl_esai_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
if (!IS_ERR(esai_priv->fsysclk))
clk_disable_unprepare(esai_priv->fsysclk);
if (!IS_ERR(esai_priv->extalclk))
clk_disable_unprepare(esai_priv->extalclk);
if (!IS_ERR(esai_priv->spbaclk))
clk_disable_unprepare(esai_priv->spbaclk);
clk_disable_unprepare(esai_priv->coreclk);
}
static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
@@ -658,7 +611,6 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
static const struct snd_soc_dai_ops fsl_esai_dai_ops = {
.startup = fsl_esai_startup,
.shutdown = fsl_esai_shutdown,
.trigger = fsl_esai_trigger,
.hw_params = fsl_esai_hw_params,
.set_sysclk = fsl_esai_set_dai_sysclk,
@@ -947,6 +899,10 @@ static int fsl_esai_probe(struct platform_device *pdev)
return ret;
}
pm_runtime_enable(&pdev->dev);
regcache_cache_only(esai_priv->regmap, true);
ret = imx_pcm_dma_init(pdev, IMX_ESAI_DMABUF_SIZE);
if (ret)
dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret);
@@ -954,6 +910,13 @@ static int fsl_esai_probe(struct platform_device *pdev)
return ret;
}
static int fsl_esai_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
return 0;
}
static const struct of_device_id fsl_esai_dt_ids[] = {
{ .compatible = "fsl,imx35-esai", },
{ .compatible = "fsl,vf610-esai", },
@@ -961,22 +924,35 @@ static const struct of_device_id fsl_esai_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);
#ifdef CONFIG_PM_SLEEP
static int fsl_esai_suspend(struct device *dev)
{
struct fsl_esai *esai = dev_get_drvdata(dev);
regcache_cache_only(esai->regmap, true);
regcache_mark_dirty(esai->regmap);
return 0;
}
static int fsl_esai_resume(struct device *dev)
#ifdef CONFIG_PM
static int fsl_esai_runtime_resume(struct device *dev)
{
struct fsl_esai *esai = dev_get_drvdata(dev);
int ret;
/*
* Some platforms might use the same bit to gate all three or two of
* clocks, so keep all clocks open/close at the same time for safety
*/
ret = clk_prepare_enable(esai->coreclk);
if (ret)
return ret;
if (!IS_ERR(esai->spbaclk)) {
ret = clk_prepare_enable(esai->spbaclk);
if (ret)
goto err_spbaclk;
}
if (!IS_ERR(esai->extalclk)) {
ret = clk_prepare_enable(esai->extalclk);
if (ret)
goto err_extalclk;
}
if (!IS_ERR(esai->fsysclk)) {
ret = clk_prepare_enable(esai->fsysclk);
if (ret)
goto err_fsysclk;
}
regcache_cache_only(esai->regmap, false);
/* FIFO reset for safety */
@@ -987,22 +963,59 @@ static int fsl_esai_resume(struct device *dev)
ret = regcache_sync(esai->regmap);
if (ret)
return ret;
goto err_regcache_sync;
/* FIFO reset done */
regmap_update_bits(esai->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0);
regmap_update_bits(esai->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0);
return 0;
err_regcache_sync:
if (!IS_ERR(esai->fsysclk))
clk_disable_unprepare(esai->fsysclk);
err_fsysclk:
if (!IS_ERR(esai->extalclk))
clk_disable_unprepare(esai->extalclk);
err_extalclk:
if (!IS_ERR(esai->spbaclk))
clk_disable_unprepare(esai->spbaclk);
err_spbaclk:
clk_disable_unprepare(esai->coreclk);
return ret;
}
#endif /* CONFIG_PM_SLEEP */
static int fsl_esai_runtime_suspend(struct device *dev)
{
struct fsl_esai *esai = dev_get_drvdata(dev);
regcache_cache_only(esai->regmap, true);
regcache_mark_dirty(esai->regmap);
if (!IS_ERR(esai->fsysclk))
clk_disable_unprepare(esai->fsysclk);
if (!IS_ERR(esai->extalclk))
clk_disable_unprepare(esai->extalclk);
if (!IS_ERR(esai->spbaclk))
clk_disable_unprepare(esai->spbaclk);
clk_disable_unprepare(esai->coreclk);
return 0;
}
#endif /* CONFIG_PM */
static const struct dev_pm_ops fsl_esai_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(fsl_esai_suspend, fsl_esai_resume)
SET_RUNTIME_PM_OPS(fsl_esai_runtime_suspend,
fsl_esai_runtime_resume,
NULL)
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
pm_runtime_force_resume)
};
static struct platform_driver fsl_esai_driver = {
.probe = fsl_esai_probe,
.remove = fsl_esai_remove,
.driver = {
.name = "fsl-esai-dai",
.pm = &fsl_esai_pm_ops,

파일 보기

@@ -596,15 +596,8 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream,
{
struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
struct device *dev = &sai->pdev->dev;
int ret;
ret = clk_prepare_enable(sai->bus_clk);
if (ret) {
dev_err(dev, "failed to enable bus clock: %d\n", ret);
return ret;
}
regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE,
FSL_SAI_CR3_TRCE);
@@ -621,8 +614,6 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0);
clk_disable_unprepare(sai->bus_clk);
}
static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
@@ -935,6 +926,14 @@ static int fsl_sai_runtime_suspend(struct device *dev)
{
struct fsl_sai *sai = dev_get_drvdata(dev);
if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))
clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);
if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))
clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);
clk_disable_unprepare(sai->bus_clk);
regcache_cache_only(sai->regmap, true);
regcache_mark_dirty(sai->regmap);
@@ -944,6 +943,25 @@ static int fsl_sai_runtime_suspend(struct device *dev)
static int fsl_sai_runtime_resume(struct device *dev)
{
struct fsl_sai *sai = dev_get_drvdata(dev);
int ret;
ret = clk_prepare_enable(sai->bus_clk);
if (ret) {
dev_err(dev, "failed to enable bus clock: %d\n", ret);
return ret;
}
if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK)) {
ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[1]]);
if (ret)
goto disable_bus_clk;
}
if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE)) {
ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[0]]);
if (ret)
goto disable_tx_clk;
}
regcache_cache_only(sai->regmap, false);
regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR);
@@ -951,7 +969,23 @@ static int fsl_sai_runtime_resume(struct device *dev)
usleep_range(1000, 2000);
regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
return regcache_sync(sai->regmap);
ret = regcache_sync(sai->regmap);
if (ret)
goto disable_rx_clk;
return 0;
disable_rx_clk:
if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))
clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);
disable_tx_clk:
if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))
clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);
disable_bus_clk:
clk_disable_unprepare(sai->bus_clk);
return ret;
}
#endif /* CONFIG_PM */

파일 보기

@@ -1582,9 +1582,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
}
}
ret = fsl_ssi_debugfs_create(&ssi->dbg_stats, dev);
if (ret)
goto error_asoc_register;
fsl_ssi_debugfs_create(&ssi->dbg_stats, dev);
/* Initially configures SSI registers */
fsl_ssi_hw_init(ssi);

파일 보기

@@ -270,7 +270,6 @@ struct device;
struct fsl_ssi_dbg {
struct dentry *dbg_dir;
struct dentry *dbg_stats;
struct {
unsigned int rfrc;
@@ -299,7 +298,7 @@ struct fsl_ssi_dbg {
void fsl_ssi_dbg_isr(struct fsl_ssi_dbg *ssi_dbg, u32 sisr);
int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, struct device *dev);
void fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, struct device *dev);
void fsl_ssi_debugfs_remove(struct fsl_ssi_dbg *ssi_dbg);
@@ -312,10 +311,9 @@ static inline void fsl_ssi_dbg_isr(struct fsl_ssi_dbg *stats, u32 sisr)
{
}
static inline int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg,
struct device *dev)
static inline void fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg,
struct device *dev)
{
return 0;
}
static inline void fsl_ssi_debugfs_remove(struct fsl_ssi_dbg *ssi_dbg)

파일 보기

@@ -126,25 +126,15 @@ static int fsl_ssi_stats_show(struct seq_file *s, void *unused)
DEFINE_SHOW_ATTRIBUTE(fsl_ssi_stats);
int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, struct device *dev)
void fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, struct device *dev)
{
ssi_dbg->dbg_dir = debugfs_create_dir(dev_name(dev), NULL);
if (!ssi_dbg->dbg_dir)
return -ENOMEM;
ssi_dbg->dbg_stats = debugfs_create_file("stats", 0444,
ssi_dbg->dbg_dir, ssi_dbg,
&fsl_ssi_stats_fops);
if (!ssi_dbg->dbg_stats) {
debugfs_remove(ssi_dbg->dbg_dir);
return -ENOMEM;
}
return 0;
debugfs_create_file("stats", 0444, ssi_dbg->dbg_dir, ssi_dbg,
&fsl_ssi_stats_fops);
}
void fsl_ssi_debugfs_remove(struct fsl_ssi_dbg *ssi_dbg)
{
debugfs_remove(ssi_dbg->dbg_stats);
debugfs_remove(ssi_dbg->dbg_dir);
debugfs_remove_recursive(ssi_dbg->dbg_dir);
}

파일 보기

@@ -57,7 +57,7 @@ int fsl_asoc_get_dma_channel(struct device_node *ssi_np,
of_node_put(dma_channel_np);
return ret;
}
snprintf((char *)dai->platform_name, DAI_NAME_SIZE, "%llx.%pOFn",
snprintf((char *)dai->platforms->name, DAI_NAME_SIZE, "%llx.%pOFn",
(unsigned long long) res.start, dma_channel_np);
iprop = of_get_property(dma_channel_np, "cell-index", NULL);

파일 보기

@@ -205,6 +205,15 @@ static int imx_audmix_probe(struct platform_device *pdev)
return -ENOMEM;
for (i = 0; i < num_dai; i++) {
struct snd_soc_dai_link_component *dlc;
/* for CPU/Codec/Platform x 2 */
dlc = devm_kzalloc(&pdev->dev, 6 * sizeof(*dlc), GFP_KERNEL);
if (!dlc) {
dev_err(&pdev->dev, "failed to allocate dai_link\n");
return -ENOMEM;
}
ret = of_parse_phandle_with_args(audmix_np, "dais", NULL, i,
&args);
if (ret < 0) {
@@ -231,13 +240,21 @@ static int imx_audmix_probe(struct platform_device *pdev)
dai_name, "CPU-Capture");
}
priv->dai[i].cpus = &dlc[0];
priv->dai[i].codecs = &dlc[1];
priv->dai[i].platforms = &dlc[2];
priv->dai[i].num_cpus = 1;
priv->dai[i].num_codecs = 1;
priv->dai[i].num_platforms = 1;
priv->dai[i].name = dai_name;
priv->dai[i].stream_name = "HiFi-AUDMIX-FE";
priv->dai[i].codec_dai_name = "snd-soc-dummy-dai";
priv->dai[i].codec_name = "snd-soc-dummy";
priv->dai[i].cpu_of_node = args.np;
priv->dai[i].cpu_dai_name = dev_name(&cpu_pdev->dev);
priv->dai[i].platform_of_node = args.np;
priv->dai[i].codecs->dai_name = "snd-soc-dummy-dai";
priv->dai[i].codecs->name = "snd-soc-dummy";
priv->dai[i].cpus->of_node = args.np;
priv->dai[i].cpus->dai_name = dev_name(&cpu_pdev->dev);
priv->dai[i].platforms->of_node = args.np;
priv->dai[i].dynamic = 1;
priv->dai[i].dpcm_playback = 1;
priv->dai[i].dpcm_capture = (i == 0 ? 1 : 0);
@@ -252,12 +269,20 @@ static int imx_audmix_probe(struct platform_device *pdev)
be_cp = devm_kasprintf(&pdev->dev, GFP_KERNEL,
"AUDMIX-Capture-%d", i);
priv->dai[num_dai + i].cpus = &dlc[3];
priv->dai[num_dai + i].codecs = &dlc[4];
priv->dai[num_dai + i].platforms = &dlc[5];
priv->dai[num_dai + i].num_cpus = 1;
priv->dai[num_dai + i].num_codecs = 1;
priv->dai[num_dai + i].num_platforms = 1;
priv->dai[num_dai + i].name = be_name;
priv->dai[num_dai + i].codec_dai_name = "snd-soc-dummy-dai";
priv->dai[num_dai + i].codec_name = "snd-soc-dummy";
priv->dai[num_dai + i].cpu_of_node = audmix_np;
priv->dai[num_dai + i].cpu_dai_name = be_name;
priv->dai[num_dai + i].platform_name = "snd-soc-dummy";
priv->dai[num_dai + i].codecs->dai_name = "snd-soc-dummy-dai";
priv->dai[num_dai + i].codecs->name = "snd-soc-dummy";
priv->dai[num_dai + i].cpus->of_node = audmix_np;
priv->dai[num_dai + i].cpus->dai_name = be_name;
priv->dai[num_dai + i].platforms->name = "snd-soc-dummy";
priv->dai[num_dai + i].no_pcm = 1;
priv->dai[num_dai + i].dpcm_playback = 1;
priv->dai[num_dai + i].dpcm_capture = 1;

파일 보기

@@ -141,17 +141,11 @@ static void audmux_debugfs_init(void)
char buf[20];
audmux_debugfs_root = debugfs_create_dir("audmux", NULL);
if (!audmux_debugfs_root) {
pr_warning("Failed to create AUDMUX debugfs root\n");
return;
}
for (i = 0; i < MX31_AUDMUX_PORT7_SSI_PINS_7 + 1; i++) {
snprintf(buf, sizeof(buf), "ssi%lu", i);
if (!debugfs_create_file(buf, 0444, audmux_debugfs_root,
(void *)i, &audmux_debugfs_fops))
pr_warning("Failed to create AUDMUX port %lu debugfs file\n",
i);
debugfs_create_file(buf, 0444, audmux_debugfs_root,
(void *)i, &audmux_debugfs_fops);
}
}

파일 보기

@@ -74,6 +74,7 @@ static int imx_es8328_probe(struct platform_device *pdev)
struct device_node *ssi_np = NULL, *codec_np = NULL;
struct platform_device *ssi_pdev;
struct imx_es8328_data *data;
struct snd_soc_dai_link_component *comp;
u32 int_port, ext_port;
int ret;
struct device *dev = &pdev->dev;
@@ -147,16 +148,30 @@ static int imx_es8328_probe(struct platform_device *pdev)
goto fail;
}
comp = devm_kzalloc(dev, 3 * sizeof(*comp), GFP_KERNEL);
if (!comp) {
ret = -ENOMEM;
goto fail;
}
data->dev = dev;
data->jack_gpio = of_get_named_gpio(pdev->dev.of_node, "jack-gpio", 0);
data->dai.cpus = &comp[0];
data->dai.codecs = &comp[1];
data->dai.platforms = &comp[2];
data->dai.num_cpus = 1;
data->dai.num_codecs = 1;
data->dai.num_platforms = 1;
data->dai.name = "hifi";
data->dai.stream_name = "hifi";
data->dai.codec_dai_name = "es8328-hifi-analog";
data->dai.codec_of_node = codec_np;
data->dai.cpu_of_node = ssi_np;
data->dai.platform_of_node = ssi_np;
data->dai.codecs->dai_name = "es8328-hifi-analog";
data->dai.codecs->of_node = codec_np;
data->dai.cpus->of_node = ssi_np;
data->dai.platforms->of_node = ssi_np;
data->dai.init = &imx_es8328_dai_init;
data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM;

파일 보기

@@ -46,17 +46,19 @@ static const struct snd_soc_ops imx_mc13783_hifi_ops = {
.hw_params = imx_mc13783_hifi_hw_params,
};
SND_SOC_DAILINK_DEFS(hifi,
DAILINK_COMP_ARRAY(COMP_CPU("imx-ssi.0")),
DAILINK_COMP_ARRAY(COMP_CODEC("mc13783-codec", "mc13783-hifi")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("imx-ssi.0")));
static struct snd_soc_dai_link imx_mc13783_dai_mc13783[] = {
{
.name = "MC13783",
.stream_name = "Sound",
.codec_dai_name = "mc13783-hifi",
.codec_name = "mc13783-codec",
.cpu_dai_name = "imx-ssi.0",
.platform_name = "imx-ssi.0",
.ops = &imx_mc13783_hifi_ops,
.symmetric_rates = 1,
.dai_fmt = FMT_SSI,
SND_SOC_DAILINK_REG(hifi),
},
};

파일 보기

@@ -55,6 +55,7 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
struct platform_device *ssi_pdev;
struct i2c_client *codec_dev;
struct imx_sgtl5000_data *data = NULL;
struct snd_soc_dai_link_component *comp;
int int_port, ext_port;
int ret;
@@ -122,6 +123,12 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
goto fail;
}
comp = devm_kzalloc(&pdev->dev, 3 * sizeof(*comp), GFP_KERNEL);
if (!comp) {
ret = -ENOMEM;
goto fail;
}
data->codec_clk = clk_get(&codec_dev->dev, NULL);
if (IS_ERR(data->codec_clk)) {
ret = PTR_ERR(data->codec_clk);
@@ -130,12 +137,20 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
data->clk_frequency = clk_get_rate(data->codec_clk);
data->dai.cpus = &comp[0];
data->dai.codecs = &comp[1];
data->dai.platforms = &comp[2];
data->dai.num_cpus = 1;
data->dai.num_codecs = 1;
data->dai.num_platforms = 1;
data->dai.name = "HiFi";
data->dai.stream_name = "HiFi";
data->dai.codec_dai_name = "sgtl5000";
data->dai.codec_of_node = codec_np;
data->dai.cpu_of_node = ssi_np;
data->dai.platform_of_node = ssi_np;
data->dai.codecs->dai_name = "sgtl5000";
data->dai.codecs->of_node = codec_np;
data->dai.cpus->of_node = ssi_np;
data->dai.platforms->of_node = ssi_np;
data->dai.init = &imx_sgtl5000_dai_init;
data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM;

파일 보기

@@ -15,6 +15,7 @@ static int imx_spdif_audio_probe(struct platform_device *pdev)
{
struct device_node *spdif_np, *np = pdev->dev.of_node;
struct imx_spdif_data *data;
struct snd_soc_dai_link_component *comp;
int ret = 0;
spdif_np = of_parse_phandle(np, "spdif-controller", 0);
@@ -25,17 +26,26 @@ static int imx_spdif_audio_probe(struct platform_device *pdev)
}
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
if (!data) {
comp = devm_kzalloc(&pdev->dev, 3 * sizeof(*comp), GFP_KERNEL);
if (!data || !comp) {
ret = -ENOMEM;
goto end;
}
data->dai.cpus = &comp[0];
data->dai.codecs = &comp[1];
data->dai.platforms = &comp[2];
data->dai.num_cpus = 1;
data->dai.num_codecs = 1;
data->dai.num_platforms = 1;
data->dai.name = "S/PDIF PCM";
data->dai.stream_name = "S/PDIF PCM";
data->dai.codec_dai_name = "snd-soc-dummy-dai";
data->dai.codec_name = "snd-soc-dummy";
data->dai.cpu_of_node = spdif_np;
data->dai.platform_of_node = spdif_np;
data->dai.codecs->dai_name = "snd-soc-dummy-dai";
data->dai.codecs->name = "snd-soc-dummy";
data->dai.cpus->of_node = spdif_np;
data->dai.platforms->of_node = spdif_np;
data->dai.playback_only = true;
data->dai.capture_only = true;

파일 보기

@@ -189,6 +189,7 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
struct device_node *np = ssi_pdev->dev.of_node;
struct device_node *codec_np = NULL;
struct mpc8610_hpcd_data *machine_data;
struct snd_soc_dai_link_component *comp;
int ret = -ENODEV;
const char *sprop;
const u32 *iprop;
@@ -206,14 +207,36 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
goto error_alloc;
}
machine_data->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev);
comp = devm_kzalloc(&pdev->dev, 6 * sizeof(*comp), GFP_KERNEL);
if (!comp) {
ret = -ENOMEM;
goto error_alloc;
}
machine_data->dai[0].cpus = &comp[0];
machine_data->dai[0].codecs = &comp[1];
machine_data->dai[0].platforms = &comp[2];
machine_data->dai[0].num_cpus = 1;
machine_data->dai[0].num_codecs = 1;
machine_data->dai[0].num_platforms = 1;
machine_data->dai[1].cpus = &comp[3];
machine_data->dai[1].codecs = &comp[4];
machine_data->dai[1].platforms = &comp[5];
machine_data->dai[1].num_cpus = 1;
machine_data->dai[1].num_codecs = 1;
machine_data->dai[1].num_platforms = 1;
machine_data->dai[0].cpus->dai_name = dev_name(&ssi_pdev->dev);
machine_data->dai[0].ops = &mpc8610_hpcd_ops;
/* ASoC core can match codec with device node */
machine_data->dai[0].codec_of_node = codec_np;
machine_data->dai[0].codecs->of_node = codec_np;
/* The DAI name from the codec (snd_soc_dai_driver.name) */
machine_data->dai[0].codec_dai_name = "cs4270-hifi";
machine_data->dai[0].codecs->dai_name = "cs4270-hifi";
/* We register two DAIs per SSI, one for playback and the other for
* capture. Currently, we only support codecs that have one DAI for
@@ -306,7 +329,7 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
}
/* Find the playback DMA channel to use. */
machine_data->dai[0].platform_name = machine_data->platform_name[0];
machine_data->dai[0].platforms->name = machine_data->platform_name[0];
ret = fsl_asoc_get_dma_channel(np, "fsl,playback-dma",
&machine_data->dai[0],
&machine_data->dma_channel_id[0],
@@ -317,7 +340,7 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev)
}
/* Find the capture DMA channel to use. */
machine_data->dai[1].platform_name = machine_data->platform_name[1];
machine_data->dai[1].platforms->name = machine_data->platform_name[1];
ret = fsl_asoc_get_dma_channel(np, "fsl,capture-dma",
&machine_data->dai[1],
&machine_data->dma_channel_id[1],

파일 보기

@@ -132,16 +132,19 @@ static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = {
{"IN3_L", NULL, "Mic Bias"},
};
SND_SOC_DAILINK_DEFS(hifi,
DAILINK_COMP_ARRAY(COMP_CPU("imx-ssi.0")),
DAILINK_COMP_ARRAY(COMP_CODEC("tlv320aic32x4.0-0018",
"tlv320aic32x4-hifi")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("imx-ssi.0")));
static struct snd_soc_dai_link mx27vis_aic32x4_dai = {
.name = "tlv320aic32x4",
.stream_name = "TLV320AIC32X4",
.codec_dai_name = "tlv320aic32x4-hifi",
.platform_name = "imx-ssi.0",
.codec_name = "tlv320aic32x4.0-0018",
.cpu_dai_name = "imx-ssi.0",
.dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM,
.ops = &mx27vis_aic32x4_snd_ops,
SND_SOC_DAILINK_REG(hifi),
};
static struct snd_soc_card mx27vis_aic32x4 = {

파일 보기

@@ -199,6 +199,7 @@ static int p1022_ds_probe(struct platform_device *pdev)
struct device_node *np = ssi_pdev->dev.of_node;
struct device_node *codec_np = NULL;
struct machine_data *mdata;
struct snd_soc_dai_link_component *comp;
int ret = -ENODEV;
const char *sprop;
const u32 *iprop;
@@ -216,11 +217,34 @@ static int p1022_ds_probe(struct platform_device *pdev)
goto error_put;
}
mdata->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev);
comp = devm_kzalloc(&pdev->dev, 6 * sizeof(*comp), GFP_KERNEL);
if (!comp) {
ret = -ENOMEM;
goto error_put;
}
mdata->dai[0].cpus = &comp[0];
mdata->dai[0].codecs = &comp[1];
mdata->dai[0].platforms = &comp[2];
mdata->dai[0].num_cpus = 1;
mdata->dai[0].num_codecs = 1;
mdata->dai[0].num_platforms = 1;
mdata->dai[1].cpus = &comp[3];
mdata->dai[1].codecs = &comp[4];
mdata->dai[1].platforms = &comp[5];
mdata->dai[1].num_cpus = 1;
mdata->dai[1].num_codecs = 1;
mdata->dai[1].num_platforms = 1;
mdata->dai[0].cpus->dai_name = dev_name(&ssi_pdev->dev);
mdata->dai[0].ops = &p1022_ds_ops;
/* ASoC core can match codec with device node */
mdata->dai[0].codec_of_node = codec_np;
mdata->dai[0].codecs->of_node = codec_np;
/* We register two DAIs per SSI, one for playback and the other for
* capture. We support codecs that have separate DAIs for both playback
@@ -229,8 +253,8 @@ static int p1022_ds_probe(struct platform_device *pdev)
memcpy(&mdata->dai[1], &mdata->dai[0], sizeof(struct snd_soc_dai_link));
/* The DAI names from the codec (snd_soc_dai_driver.name) */
mdata->dai[0].codec_dai_name = "wm8776-hifi-playback";
mdata->dai[1].codec_dai_name = "wm8776-hifi-capture";
mdata->dai[0].codecs->dai_name = "wm8776-hifi-playback";
mdata->dai[1].codecs->dai_name = "wm8776-hifi-capture";
/* Get the device ID */
iprop = of_get_property(np, "cell-index", NULL);
@@ -316,7 +340,7 @@ static int p1022_ds_probe(struct platform_device *pdev)
}
/* Find the playback DMA channel to use. */
mdata->dai[0].platform_name = mdata->platform_name[0];
mdata->dai[0].platforms->name = mdata->platform_name[0];
ret = fsl_asoc_get_dma_channel(np, "fsl,playback-dma", &mdata->dai[0],
&mdata->dma_channel_id[0],
&mdata->dma_id[0]);
@@ -326,7 +350,7 @@ static int p1022_ds_probe(struct platform_device *pdev)
}
/* Find the capture DMA channel to use. */
mdata->dai[1].platform_name = mdata->platform_name[1];
mdata->dai[1].platforms->name = mdata->platform_name[1];
ret = fsl_asoc_get_dma_channel(np, "fsl,capture-dma", &mdata->dai[1],
&mdata->dma_channel_id[1],
&mdata->dma_id[1]);

파일 보기

@@ -203,6 +203,7 @@ static int p1022_rdk_probe(struct platform_device *pdev)
struct device_node *np = ssi_pdev->dev.of_node;
struct device_node *codec_np = NULL;
struct machine_data *mdata;
struct snd_soc_dai_link_component *comp;
const u32 *iprop;
int ret;
@@ -219,11 +220,33 @@ static int p1022_rdk_probe(struct platform_device *pdev)
goto error_put;
}
mdata->dai[0].cpu_dai_name = dev_name(&ssi_pdev->dev);
comp = devm_kzalloc(&pdev->dev, 6 * sizeof(*comp), GFP_KERNEL);
if (!comp) {
ret = -ENOMEM;
goto error_put;
}
mdata->dai[0].cpus = &comp[0];
mdata->dai[0].codecs = &comp[1];
mdata->dai[0].platforms = &comp[2];
mdata->dai[0].num_cpus = 1;
mdata->dai[0].num_codecs = 1;
mdata->dai[0].num_platforms = 1;
mdata->dai[1].cpus = &comp[3];
mdata->dai[1].codecs = &comp[4];
mdata->dai[1].platforms = &comp[5];
mdata->dai[1].num_cpus = 1;
mdata->dai[1].num_codecs = 1;
mdata->dai[1].num_platforms = 1;
mdata->dai[0].cpus->dai_name = dev_name(&ssi_pdev->dev);
mdata->dai[0].ops = &p1022_rdk_ops;
/* ASoC core can match codec with device node */
mdata->dai[0].codec_of_node = codec_np;
mdata->dai[0].codecs->of_node = codec_np;
/*
* We register two DAIs per SSI, one for playback and the other for
@@ -233,8 +256,8 @@ static int p1022_rdk_probe(struct platform_device *pdev)
memcpy(&mdata->dai[1], &mdata->dai[0], sizeof(struct snd_soc_dai_link));
/* The DAI names from the codec (snd_soc_dai_driver.name) */
mdata->dai[0].codec_dai_name = "wm8960-hifi";
mdata->dai[1].codec_dai_name = mdata->dai[0].codec_dai_name;
mdata->dai[0].codecs->dai_name = "wm8960-hifi";
mdata->dai[1].codecs->dai_name = mdata->dai[0].codecs->dai_name;
/*
* Configure the SSI for I2S slave mode. Older device trees have
@@ -266,7 +289,7 @@ static int p1022_rdk_probe(struct platform_device *pdev)
}
/* Find the playback DMA channel to use. */
mdata->dai[0].platform_name = mdata->platform_name[0];
mdata->dai[0].platforms->name = mdata->platform_name[0];
ret = fsl_asoc_get_dma_channel(np, "fsl,playback-dma", &mdata->dai[0],
&mdata->dma_channel_id[0],
&mdata->dma_id[0]);
@@ -277,7 +300,7 @@ static int p1022_rdk_probe(struct platform_device *pdev)
}
/* Find the capture DMA channel to use. */
mdata->dai[1].platform_name = mdata->platform_name[1];
mdata->dai[1].platforms->name = mdata->platform_name[1];
ret = fsl_asoc_get_dma_channel(np, "fsl,capture-dma", &mdata->dai[1],
&mdata->dma_channel_id[1],
&mdata->dma_id[1]);

파일 보기

@@ -23,20 +23,26 @@ struct pcm030_audio_data {
struct platform_device *codec_device;
};
SND_SOC_DAILINK_DEFS(analog,
DAILINK_COMP_ARRAY(COMP_CPU("mpc5200-psc-ac97.0")),
DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-hifi")),
DAILINK_COMP_ARRAY(COMP_EMPTY()));
SND_SOC_DAILINK_DEFS(iec958,
DAILINK_COMP_ARRAY(COMP_CPU("mpc5200-psc-ac97.1")),
DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-aux")),
DAILINK_COMP_ARRAY(COMP_EMPTY()));
static struct snd_soc_dai_link pcm030_fabric_dai[] = {
{
.name = "AC97.0",
.stream_name = "AC97 Analog",
.codec_dai_name = "wm9712-hifi",
.cpu_dai_name = "mpc5200-psc-ac97.0",
.codec_name = "wm9712-codec",
SND_SOC_DAILINK_REG(analog),
},
{
.name = "AC97.1",
.stream_name = "AC97 IEC958",
.codec_dai_name = "wm9712-aux",
.cpu_dai_name = "mpc5200-psc-ac97.1",
.codec_name = "wm9712-codec",
SND_SOC_DAILINK_REG(iec958),
},
};
@@ -76,7 +82,7 @@ static int pcm030_fabric_probe(struct platform_device *op)
}
for_each_card_prelinks(card, i, dai_link)
dai_link->platform_of_node = platform_np;
dai_link->platforms->of_node = platform_np;
ret = request_module("snd-soc-wm9712");
if (ret)

파일 보기

@@ -20,15 +20,17 @@ static struct snd_soc_card imx_phycore;
static const struct snd_soc_ops imx_phycore_hifi_ops = {
};
SND_SOC_DAILINK_DEFS(hifi,
DAILINK_COMP_ARRAY(COMP_CPU("imx-ssi.0")),
DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-hifi")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("imx-ssi.0")));
static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
{
.name = "HiFi",
.stream_name = "HiFi",
.codec_dai_name = "wm9712-hifi",
.codec_name = "wm9712-codec",
.cpu_dai_name = "imx-ssi.0",
.platform_name = "imx-ssi.0",
.ops = &imx_phycore_hifi_ops,
SND_SOC_DAILINK_REG(hifi),
},
};

파일 보기

@@ -216,18 +216,20 @@ static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd)
}
SND_SOC_DAILINK_DEFS(ev1,
DAILINK_COMP_ARRAY(COMP_CPU("imx-ssi.0")),
DAILINK_COMP_ARRAY(COMP_CODEC("wm8350-codec.0-0x1a", "wm8350-hifi")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("imx-ssi.0")));
static struct snd_soc_dai_link wm1133_ev1_dai = {
.name = "WM1133-EV1",
.stream_name = "Audio",
.cpu_dai_name = "imx-ssi.0",
.codec_dai_name = "wm8350-hifi",
.platform_name = "imx-ssi.0",
.codec_name = "wm8350-codec.0-0x1a",
.init = wm1133_ev1_init,
.ops = &wm1133_ev1_ops,
.symmetric_rates = 1,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM,
SND_SOC_DAILINK_REG(ev1),
};
static struct snd_soc_card wm1133_ev1 = {

파일 보기

@@ -111,29 +111,14 @@ static int graph_get_dai_id(struct device_node *ep)
static int asoc_simple_parse_dai(struct device_node *ep,
struct snd_soc_dai_link_component *dlc,
struct device_node **dai_of_node,
const char **dai_name,
int *is_single_link)
{
struct device_node *node;
struct of_phandle_args args;
int ret;
/*
* Use snd_soc_dai_link_component instead of legacy style.
* It is only for codec, but cpu will be supported in the future.
* see
* soc-core.c :: snd_soc_init_multicodec()
*/
if (dlc) {
dai_name = &dlc->dai_name;
dai_of_node = &dlc->of_node;
}
if (!ep)
return 0;
if (!dai_name)
return 0;
node = of_graph_get_port_parent(ep);
@@ -142,11 +127,11 @@ static int asoc_simple_parse_dai(struct device_node *ep,
args.args[0] = graph_get_dai_id(ep);
args.args_count = (of_graph_get_endpoint_count(node) > 1);
ret = snd_soc_get_dai_name(&args, dai_name);
ret = snd_soc_get_dai_name(&args, &dlc->dai_name);
if (ret < 0)
return ret;
*dai_of_node = node;
dlc->of_node = node;
if (is_single_link)
*is_single_link = of_graph_get_endpoint_count(node) == 1;
@@ -207,6 +192,7 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv,
struct device_node *ports;
struct device_node *node;
struct asoc_simple_dai *dai;
struct snd_soc_dai_link_component *cpus = dai_link->cpus;
struct snd_soc_dai_link_component *codecs = dai_link->codecs;
int ret;
@@ -251,7 +237,7 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv,
ret = asoc_simple_set_dailink_name(dev, dai_link,
"fe.%s",
dai_link->cpu_dai_name);
cpus->dai_name);
if (ret < 0)
return ret;
@@ -261,9 +247,9 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv,
struct snd_soc_codec_conf *cconf;
/* FE is dummy */
dai_link->cpu_of_node = NULL;
dai_link->cpu_dai_name = "snd-soc-dummy-dai";
dai_link->cpu_name = "snd-soc-dummy";
cpus->of_node = NULL;
cpus->dai_name = "snd-soc-dummy-dai";
cpus->name = "snd-soc-dummy";
/* BE settings */
dai_link->no_pcm = 1;
@@ -383,7 +369,7 @@ static int graph_dai_link_of(struct asoc_simple_priv *priv,
ret = asoc_simple_set_dailink_name(dev, dai_link,
"%s-%s",
dai_link->cpu_dai_name,
dai_link->cpus->dai_name,
dai_link->codecs->dai_name);
if (ret < 0)
return ret;

파일 보기

@@ -159,23 +159,12 @@ static void asoc_simple_clk_disable(struct asoc_simple_dai *dai)
int asoc_simple_parse_clk(struct device *dev,
struct device_node *node,
struct device_node *dai_of_node,
struct asoc_simple_dai *simple_dai,
const char *dai_name,
struct snd_soc_dai_link_component *dlc)
{
struct clk *clk;
u32 val;
/*
* Use snd_soc_dai_link_component instead of legacy style.
* It is only for codec, but cpu will be supported in the future.
* see
* soc-core.c :: snd_soc_init_multicodec()
*/
if (dlc)
dai_of_node = dlc->of_node;
/*
* Parse dai->sysclk come from "clocks = <&xxx>"
* (if system has common clock)
@@ -190,7 +179,7 @@ int asoc_simple_parse_clk(struct device *dev,
} else if (!of_property_read_u32(node, "system-clock-frequency", &val)) {
simple_dai->sysclk = val;
} else {
clk = devm_get_clk_from_child(dev, dai_of_node, NULL);
clk = devm_get_clk_from_child(dev, dlc->of_node, NULL);
if (!IS_ERR(clk))
simple_dai->sysclk = clk_get_rate(clk);
}
@@ -359,7 +348,7 @@ void asoc_simple_canonicalize_platform(struct snd_soc_dai_link *dai_link)
{
/* Assumes platform == cpu */
if (!dai_link->platforms->of_node)
dai_link->platforms->of_node = dai_link->cpu_of_node;
dai_link->platforms->of_node = dai_link->cpus->of_node;
}
EXPORT_SYMBOL_GPL(asoc_simple_canonicalize_platform);
@@ -376,7 +365,7 @@ void asoc_simple_canonicalize_cpu(struct snd_soc_dai_link *dai_link,
* fmt_multiple_name()
*/
if (is_single_links)
dai_link->cpu_dai_name = NULL;
dai_link->cpus->dai_name = NULL;
}
EXPORT_SYMBOL_GPL(asoc_simple_canonicalize_cpu);
@@ -386,7 +375,7 @@ int asoc_simple_clean_reference(struct snd_soc_card *card)
int i;
for_each_card_prelinks(card, i, dai_link) {
of_node_put(dai_link->cpu_of_node);
of_node_put(dai_link->cpus->of_node);
of_node_put(dai_link->codecs->of_node);
}
return 0;
@@ -576,6 +565,8 @@ int asoc_simple_init_priv(struct asoc_simple_priv *priv,
* simple-card-utils.c :: asoc_simple_canonicalize_platform()
*/
for (i = 0; i < li->link; i++) {
dai_link[i].cpus = &dai_props[i].cpus;
dai_link[i].num_cpus = 1;
dai_link[i].codecs = &dai_props[i].codecs;
dai_link[i].num_codecs = 1;
dai_link[i].platforms = &dai_props[i].platforms;

파일 보기

@@ -30,8 +30,6 @@ static const struct snd_soc_ops simple_ops = {
static int asoc_simple_parse_dai(struct device_node *node,
struct snd_soc_dai_link_component *dlc,
struct device_node **dai_of_node,
const char **dai_name,
int *is_single_link)
{
struct of_phandle_args args;
@@ -40,17 +38,6 @@ static int asoc_simple_parse_dai(struct device_node *node,
if (!node)
return 0;
/*
* Use snd_soc_dai_link_component instead of legacy style.
* It is only for codec, but cpu will be supported in the future.
* see
* soc-core.c :: snd_soc_init_multicodec()
*/
if (dlc) {
dai_name = &dlc->dai_name;
dai_of_node = &dlc->of_node;
}
/*
* Get node via "sound-dai = <&phandle port>"
* it will be used as xxx_of_node on soc_bind_dai_link()
@@ -60,13 +47,11 @@ static int asoc_simple_parse_dai(struct device_node *node,
return ret;
/* Get dai->name */
if (dai_name) {
ret = snd_soc_of_get_dai_name(node, dai_name);
if (ret < 0)
return ret;
}
ret = snd_soc_of_get_dai_name(node, &dlc->dai_name);
if (ret < 0)
return ret;
*dai_of_node = args.np;
dlc->of_node = args.np;
if (is_single_link)
*is_single_link = !args.args_count;
@@ -119,6 +104,7 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv,
struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
struct asoc_simple_dai *dai;
struct snd_soc_dai_link_component *cpus = dai_link->cpus;
struct snd_soc_dai_link_component *codecs = dai_link->codecs;
struct device_node *top = dev->of_node;
struct device_node *node = of_get_parent(np);
@@ -169,7 +155,7 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv,
ret = asoc_simple_set_dailink_name(dev, dai_link,
"fe.%s",
dai_link->cpu_dai_name);
cpus->dai_name);
if (ret < 0)
return ret;
@@ -178,9 +164,9 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv,
struct snd_soc_codec_conf *cconf;
/* FE is dummy */
dai_link->cpu_of_node = NULL;
dai_link->cpu_dai_name = "snd-soc-dummy-dai";
dai_link->cpu_name = "snd-soc-dummy";
cpus->of_node = NULL;
cpus->dai_name = "snd-soc-dummy-dai";
cpus->name = "snd-soc-dummy";
/* BE settings */
dai_link->no_pcm = 1;
@@ -320,7 +306,7 @@ static int simple_dai_link_of(struct asoc_simple_priv *priv,
ret = asoc_simple_set_dailink_name(dev, dai_link,
"%s-%s",
dai_link->cpu_dai_name,
dai_link->cpus->dai_name,
dai_link->codecs->dai_name);
if (ret < 0)
goto dai_link_of_err;
@@ -607,7 +593,7 @@ static int simple_soc_probe(struct snd_soc_card *card)
return 0;
}
static int simple_probe(struct platform_device *pdev)
static int asoc_simple_probe(struct platform_device *pdev)
{
struct asoc_simple_priv *priv;
struct device *dev = &pdev->dev;
@@ -646,6 +632,7 @@ static int simple_probe(struct platform_device *pdev)
} else {
struct asoc_simple_card_info *cinfo;
struct snd_soc_dai_link_component *cpus;
struct snd_soc_dai_link_component *codecs;
struct snd_soc_dai_link_component *platform;
struct snd_soc_dai_link *dai_link = priv->dai_link;
@@ -671,6 +658,9 @@ static int simple_probe(struct platform_device *pdev)
dai_props->cpu_dai = &priv->dais[dai_idx++];
dai_props->codec_dai = &priv->dais[dai_idx++];
cpus = dai_link->cpus;
cpus->dai_name = cinfo->cpu_dai.name;
codecs = dai_link->codecs;
codecs->name = cinfo->codec;
codecs->dai_name = cinfo->codec_dai.name;
@@ -681,7 +671,6 @@ static int simple_probe(struct platform_device *pdev)
card->name = (cinfo->card) ? cinfo->card : cinfo->name;
dai_link->name = cinfo->name;
dai_link->stream_name = cinfo->name;
dai_link->cpu_dai_name = cinfo->cpu_dai.name;
dai_link->dai_fmt = cinfo->daifmt;
dai_link->init = asoc_simple_dai_init;
memcpy(dai_props->cpu_dai, &cinfo->cpu_dai,
@@ -705,7 +694,7 @@ err:
return ret;
}
static int simple_remove(struct platform_device *pdev)
static int asoc_simple_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
@@ -726,8 +715,8 @@ static struct platform_driver asoc_simple_card = {
.pm = &snd_soc_pm_ops,
.of_match_table = simple_of_match,
},
.probe = simple_probe,
.remove = simple_remove,
.probe = asoc_simple_probe,
.remove = asoc_simple_remove,
};
module_platform_driver(asoc_simple_card);

파일 보기

@@ -105,6 +105,7 @@ config SND_SST_ATOM_HIFI2_PLATFORM_ACPI
config SND_SOC_INTEL_SKYLAKE
tristate "All Skylake/SST Platforms"
depends on PCI && ACPI
depends on COMMON_CLK
select SND_SOC_INTEL_SKL
select SND_SOC_INTEL_APL
select SND_SOC_INTEL_KBL
@@ -121,6 +122,7 @@ config SND_SOC_INTEL_SKYLAKE
config SND_SOC_INTEL_SKL
tristate "Skylake Platforms"
depends on PCI && ACPI
depends on COMMON_CLK
select SND_SOC_INTEL_SKYLAKE_FAMILY
help
If you have a Intel Skylake platform with the DSP enabled
@@ -129,6 +131,7 @@ config SND_SOC_INTEL_SKL
config SND_SOC_INTEL_APL
tristate "Broxton/ApolloLake Platforms"
depends on PCI && ACPI
depends on COMMON_CLK
select SND_SOC_INTEL_SKYLAKE_FAMILY
help
If you have a Intel Broxton/ApolloLake platform with the DSP
@@ -137,6 +140,7 @@ config SND_SOC_INTEL_APL
config SND_SOC_INTEL_KBL
tristate "Kabylake Platforms"
depends on PCI && ACPI
depends on COMMON_CLK
select SND_SOC_INTEL_SKYLAKE_FAMILY
help
If you have a Intel Kabylake platform with the DSP
@@ -145,6 +149,7 @@ config SND_SOC_INTEL_KBL
config SND_SOC_INTEL_GLK
tristate "GeminiLake Platforms"
depends on PCI && ACPI
depends on COMMON_CLK
select SND_SOC_INTEL_SKYLAKE_FAMILY
help
If you have a Intel GeminiLake platform with the DSP
@@ -153,6 +158,7 @@ config SND_SOC_INTEL_GLK
config SND_SOC_INTEL_CNL
tristate "CannonLake/WhiskyLake Platforms"
depends on PCI && ACPI
depends on COMMON_CLK
select SND_SOC_INTEL_SKYLAKE_FAMILY
help
If you have a Intel CNL/WHL platform with the DSP
@@ -161,11 +167,30 @@ config SND_SOC_INTEL_CNL
config SND_SOC_INTEL_CFL
tristate "CoffeeLake Platforms"
depends on PCI && ACPI
depends on COMMON_CLK
select SND_SOC_INTEL_SKYLAKE_FAMILY
help
If you have a Intel CoffeeLake platform with the DSP
enabled in the BIOS then enable this option by saying Y or m.
config SND_SOC_INTEL_CML_H
tristate "CometLake-H Platforms"
depends on PCI && ACPI
depends on COMMON_CLK
select SND_SOC_INTEL_SKYLAKE_FAMILY
help
If you have a Intel CometLake-H platform with the DSP
enabled in the BIOS then enable this option by saying Y or m.
config SND_SOC_INTEL_CML_LP
tristate "CometLake-LP Platforms"
depends on PCI && ACPI
depends on COMMON_CLK
select SND_SOC_INTEL_SKYLAKE_FAMILY
help
If you have a Intel CometLake-LP platform with the DSP
enabled in the BIOS then enable this option by saying Y or m.
config SND_SOC_INTEL_SKYLAKE_FAMILY
tristate
select SND_SOC_INTEL_SKYLAKE_COMMON

파일 보기

@@ -28,12 +28,11 @@
#include <acpi/platform/aclinux.h>
#include <acpi/actypes.h>
#include <acpi/acpi_bus.h>
#include <asm/cpu_device_id.h>
#include <asm/iosf_mbi.h>
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
#include "../sst-mfld-platform.h"
#include "../../common/sst-dsp.h"
#include "../../common/soc-intel-quirks.h"
#include "sst.h"
/* LPE viewpoint addresses */
@@ -233,64 +232,6 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx)
return 0;
}
static int is_byt(void)
{
bool status = false;
static const struct x86_cpu_id cpu_ids[] = {
{ X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
{}
};
if (x86_match_cpu(cpu_ids))
status = true;
return status;
}
static bool is_byt_cr(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
int status = 0;
if (!is_byt())
return false;
if (iosf_mbi_available()) {
u32 bios_status;
status = iosf_mbi_read(BT_MBI_UNIT_PMC, /* 0x04 PUNIT */
MBI_REG_READ, /* 0x10 */
0x006, /* BIOS_CONFIG */
&bios_status);
if (status) {
dev_err(dev, "could not read PUNIT BIOS_CONFIG\n");
} else {
/* bits 26:27 mirror PMIC options */
bios_status = (bios_status >> 26) & 3;
if (bios_status == 1 || bios_status == 3) {
dev_info(dev, "Detected Baytrail-CR platform\n");
return true;
}
dev_info(dev, "BYT-CR not detected\n");
}
} else {
dev_info(dev, "IOSF_MBI not available, no BYT-CR detection\n");
}
if (platform_get_resource(pdev, IORESOURCE_IRQ, 5) == NULL) {
/*
* Some devices detected as BYT-T have only a single IRQ listed,
* causing platform_get_irq with index 5 to return -ENXIO.
* The correct IRQ in this case is at index 0, as on BYT-CR.
*/
dev_info(dev, "Falling back to Baytrail-CR platform\n");
return true;
}
return false;
}
static int sst_acpi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -315,7 +256,7 @@ static int sst_acpi_probe(struct platform_device *pdev)
return -ENODEV;
}
if (is_byt())
if (soc_intel_is_byt())
mach->pdata = &byt_rvp_platform_data;
else
mach->pdata = &chv_platform_data;
@@ -333,7 +274,7 @@ static int sst_acpi_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
if (is_byt_cr(pdev)) {
if (soc_intel_is_byt_cr(pdev)) {
/* override resource info */
byt_rvp_platform_data.res_info = &bytcr_res_info;
}

파일 보기

@@ -156,6 +156,18 @@ config SND_SOC_INTEL_CHT_BSW_NAU8824_MACH
Say Y or m if you have such a device. This is a recommended option.
If unsure select "N".
config SND_SOC_INTEL_BYT_CHT_CX2072X_MACH
tristate "Baytrail & Cherrytrail with CX2072X codec"
depends on I2C && ACPI
depends on X86_INTEL_LPSS || COMPILE_TEST
select SND_SOC_ACPI
select SND_SOC_CX2072X
help
This adds support for ASoC machine driver for Intel(R) Baytrail &
Cherrytrail platforms with Conexant CX2072X audio codec.
Say Y or m if you have such a device. This is a recommended option.
If unsure select "N".
config SND_SOC_INTEL_BYT_CHT_DA7213_MACH
tristate "Baytrail & Cherrytrail with DA7212/7213 codec"
depends on I2C && ACPI
@@ -388,11 +400,11 @@ if SND_SOC_SOF_HDA_COMMON || SND_SOC_SOF_BAYTRAIL
config SND_SOC_INTEL_SOF_RT5682_MACH
tristate "SOF with rt5682 codec in I2S Mode"
depends on I2C && ACPI
depends on (SND_SOC_SOF_HDA_COMMON && MFD_INTEL_LPSS) ||\
(SND_SOC_SOF_BAYTRAIL && X86_INTEL_LPSS)
depends on (SND_SOC_SOF_HDA_COMMON && (MFD_INTEL_LPSS || COMPILE_TEST)) ||\
(SND_SOC_SOF_BAYTRAIL && (X86_INTEL_LPSS || COMPILE_TEST))
select SND_SOC_RT5682
select SND_SOC_DMIC
select SND_SOC_HDAC_HDMI if SND_SOC_SOF_HDA_COMMON
select SND_SOC_HDAC_HDMI
help
This adds support for ASoC machine driver for SOF platforms
with rt5682 codec.

파일 보기

@@ -13,6 +13,7 @@ snd-soc-sst-cht-bsw-rt5672-objs := cht_bsw_rt5672.o
snd-soc-sst-cht-bsw-rt5645-objs := cht_bsw_rt5645.o
snd-soc-sst-cht-bsw-max98090_ti-objs := cht_bsw_max98090_ti.o
snd-soc-sst-cht-bsw-nau8824-objs := cht_bsw_nau8824.o
snd-soc-sst-byt-cht-cx2072x-objs := bytcht_cx2072x.o
snd-soc-sst-byt-cht-da7213-objs := bytcht_da7213.o
snd-soc-sst-byt-cht-es8316-objs := bytcht_es8316.o
snd-soc-sst-byt-cht-nocodec-objs := bytcht_nocodec.o
@@ -42,6 +43,7 @@ obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH) += snd-soc-sst-cht-bsw-rt5672.o
obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH) += snd-soc-sst-cht-bsw-rt5645.o
obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH) += snd-soc-sst-cht-bsw-max98090_ti.o
obj-$(CONFIG_SND_SOC_INTEL_CHT_BSW_NAU8824_MACH) += snd-soc-sst-cht-bsw-nau8824.o
obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_CX2072X_MACH) += snd-soc-sst-byt-cht-cx2072x.o
obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH) += snd-soc-sst-byt-cht-da7213.o
obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH) += snd-soc-sst-byt-cht-es8316.o
obj-$(CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH) += snd-soc-sst-byt-cht-nocodec.o

파일 보기

@@ -246,16 +246,24 @@ static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd)
}
/* broadwell digital audio interface glue - connects codec <--> CPU */
SND_SOC_DAILINK_DEF(dummy,
DAILINK_COMP_ARRAY(COMP_DUMMY()));
SND_SOC_DAILINK_DEF(fe,
DAILINK_COMP_ARRAY(COMP_CPU("System Pin")));
SND_SOC_DAILINK_DEF(platform,
DAILINK_COMP_ARRAY(COMP_PLATFORM("haswell-pcm-audio")));
SND_SOC_DAILINK_DEF(be,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-RT5677CE:00", "rt5677-aif1")));
static struct snd_soc_dai_link bdw_rt5677_dais[] = {
/* Front End DAI links */
{
.name = "System PCM",
.stream_name = "System Playback/Capture",
.cpu_dai_name = "System Pin",
.platform_name = "haswell-pcm-audio",
.dynamic = 1,
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
#if !IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
.init = bdw_rt5677_rtd_init,
#endif
@@ -265,6 +273,7 @@ static struct snd_soc_dai_link bdw_rt5677_dais[] = {
},
.dpcm_capture = 1,
.dpcm_playback = 1,
SND_SOC_DAILINK_REG(fe, dummy, platform),
},
/* Back End DAI links */
@@ -272,11 +281,7 @@ static struct snd_soc_dai_link bdw_rt5677_dais[] = {
/* SSP0 - Codec */
.name = "Codec",
.id = 0,
.cpu_dai_name = "snd-soc-dummy-dai",
.platform_name = "snd-soc-dummy",
.no_pcm = 1,
.codec_name = "i2c-RT5677CE:00",
.codec_dai_name = "rt5677-aif1",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
.ignore_suspend = 1,
@@ -286,6 +291,7 @@ static struct snd_soc_dai_link bdw_rt5677_dais[] = {
.dpcm_playback = 1,
.dpcm_capture = 1,
.init = bdw_rt5677_init,
SND_SOC_DAILINK_REG(dummy, be, dummy),
},
};

파일 보기

@@ -143,67 +143,72 @@ static int broadwell_rtd_init(struct snd_soc_pcm_runtime *rtd)
}
#endif
SND_SOC_DAILINK_DEF(system,
DAILINK_COMP_ARRAY(COMP_CPU("System Pin")));
SND_SOC_DAILINK_DEF(offload0,
DAILINK_COMP_ARRAY(COMP_CPU("Offload0 Pin")));
SND_SOC_DAILINK_DEF(offload1,
DAILINK_COMP_ARRAY(COMP_CPU("Offload1 Pin")));
SND_SOC_DAILINK_DEF(loopback,
DAILINK_COMP_ARRAY(COMP_CPU("Loopback Pin")));
SND_SOC_DAILINK_DEF(dummy,
DAILINK_COMP_ARRAY(COMP_DUMMY()));
SND_SOC_DAILINK_DEF(platform,
DAILINK_COMP_ARRAY(COMP_PLATFORM("haswell-pcm-audio")));
SND_SOC_DAILINK_DEF(codec,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-INT343A:00", "rt286-aif1")));
/* broadwell digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link broadwell_rt286_dais[] = {
/* Front End DAI links */
{
.name = "System PCM",
.stream_name = "System Playback/Capture",
.cpu_dai_name = "System Pin",
.platform_name = "haswell-pcm-audio",
.dynamic = 1,
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
#if !IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
.init = broadwell_rtd_init,
#endif
.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
.dpcm_playback = 1,
.dpcm_capture = 1,
SND_SOC_DAILINK_REG(system, dummy, platform),
},
{
.name = "Offload0",
.stream_name = "Offload0 Playback",
.cpu_dai_name = "Offload0 Pin",
.platform_name = "haswell-pcm-audio",
.dynamic = 1,
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
.dpcm_playback = 1,
SND_SOC_DAILINK_REG(offload0, dummy, platform),
},
{
.name = "Offload1",
.stream_name = "Offload1 Playback",
.cpu_dai_name = "Offload1 Pin",
.platform_name = "haswell-pcm-audio",
.dynamic = 1,
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
.dpcm_playback = 1,
SND_SOC_DAILINK_REG(offload1, dummy, platform),
},
{
.name = "Loopback PCM",
.stream_name = "Loopback",
.cpu_dai_name = "Loopback Pin",
.platform_name = "haswell-pcm-audio",
.dynamic = 1,
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
.dpcm_capture = 1,
SND_SOC_DAILINK_REG(loopback, dummy, platform),
},
/* Back End DAI links */
{
/* SSP0 - Codec */
.name = "Codec",
.id = 0,
.cpu_dai_name = "snd-soc-dummy-dai",
.platform_name = "snd-soc-dummy",
.no_pcm = 1,
.codec_name = "i2c-INT343A:00",
.codec_dai_name = "rt286-aif1",
.init = broadwell_rt286_codec_init,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
@@ -213,6 +218,7 @@ static struct snd_soc_dai_link broadwell_rt286_dais[] = {
.ops = &broadwell_rt286_ops,
.dpcm_playback = 1,
.dpcm_capture = 1,
SND_SOC_DAILINK_REG(dummy, codec, dummy),
},
};

파일 보기

@@ -8,7 +8,6 @@
* Intel Skylake I2S Machine driver
*/
#include <asm/cpu_device_id.h>
#include <linux/input.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -21,6 +20,7 @@
#include "../../codecs/hdac_hdmi.h"
#include "../../codecs/da7219.h"
#include "../../codecs/da7219-aad.h"
#include "../common/soc-intel-quirks.h"
#define BXT_DIALOG_CODEC_DAI "da7219-hifi"
#define BXT_MAXIM_CODEC_DAI "HiFi"
@@ -365,146 +365,181 @@ static const struct snd_soc_ops broxton_refcap_ops = {
};
/* broxton digital audio interface glue - connects codec <--> CPU */
SND_SOC_DAILINK_DEF(dummy,
DAILINK_COMP_ARRAY(COMP_DUMMY()));
SND_SOC_DAILINK_DEF(system,
DAILINK_COMP_ARRAY(COMP_CPU("System Pin")));
SND_SOC_DAILINK_DEF(system2,
DAILINK_COMP_ARRAY(COMP_CPU("System Pin2")));
SND_SOC_DAILINK_DEF(reference,
DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin")));
SND_SOC_DAILINK_DEF(dmic,
DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin")));
SND_SOC_DAILINK_DEF(hdmi1,
DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin")));
SND_SOC_DAILINK_DEF(hdmi2,
DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin")));
SND_SOC_DAILINK_DEF(hdmi3,
DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin")));
/* Back End DAI */
SND_SOC_DAILINK_DEF(ssp5_pin,
DAILINK_COMP_ARRAY(COMP_CPU("SSP5 Pin")));
SND_SOC_DAILINK_DEF(ssp5_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00",
BXT_MAXIM_CODEC_DAI)));
SND_SOC_DAILINK_DEF(ssp1_pin,
DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin")));
SND_SOC_DAILINK_DEF(ssp1_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-DLGS7219:00",
BXT_DIALOG_CODEC_DAI)));
SND_SOC_DAILINK_DEF(dmic_pin,
DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin")));
SND_SOC_DAILINK_DEF(dmic16k_pin,
DAILINK_COMP_ARRAY(COMP_CPU("DMIC16k Pin")));
SND_SOC_DAILINK_DEF(dmic_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi")));
SND_SOC_DAILINK_DEF(idisp1_pin,
DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin")));
SND_SOC_DAILINK_DEF(idisp1_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1")));
SND_SOC_DAILINK_DEF(idisp2_pin,
DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin")));
SND_SOC_DAILINK_DEF(idisp2_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2",
"intel-hdmi-hifi2")));
SND_SOC_DAILINK_DEF(idisp3_pin,
DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin")));
SND_SOC_DAILINK_DEF(idisp3_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2",
"intel-hdmi-hifi3")));
SND_SOC_DAILINK_DEF(platform,
DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:0e.0")));
static struct snd_soc_dai_link broxton_dais[] = {
/* Front End DAI links */
[BXT_DPCM_AUDIO_PB] =
{
.name = "Bxt Audio Port",
.stream_name = "Audio",
.cpu_dai_name = "System Pin",
.platform_name = "0000:00:0e.0",
.dynamic = 1,
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.nonatomic = 1,
.init = broxton_da7219_fe_init,
.trigger = {
SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
.dpcm_playback = 1,
.ops = &broxton_da7219_fe_ops,
SND_SOC_DAILINK_REG(system, dummy, platform),
},
[BXT_DPCM_AUDIO_CP] =
{
.name = "Bxt Audio Capture Port",
.stream_name = "Audio Record",
.cpu_dai_name = "System Pin",
.platform_name = "0000:00:0e.0",
.dynamic = 1,
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.nonatomic = 1,
.trigger = {
SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
.dpcm_capture = 1,
.ops = &broxton_da7219_fe_ops,
SND_SOC_DAILINK_REG(system, dummy, platform),
},
[BXT_DPCM_AUDIO_HS_PB] = {
.name = "Bxt Audio Headset Playback",
.stream_name = "Headset Playback",
.cpu_dai_name = "System Pin2",
.platform_name = "0000:00:0e.0",
.dynamic = 1,
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.nonatomic = 1,
.trigger = {
SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
.dpcm_playback = 1,
.ops = &broxton_da7219_fe_ops,
SND_SOC_DAILINK_REG(system2, dummy, platform),
},
[BXT_DPCM_AUDIO_REF_CP] =
{
.name = "Bxt Audio Reference cap",
.stream_name = "Refcap",
.cpu_dai_name = "Reference Pin",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.platform_name = "0000:00:0e.0",
.init = NULL,
.dpcm_capture = 1,
.nonatomic = 1,
.dynamic = 1,
.ops = &broxton_refcap_ops,
SND_SOC_DAILINK_REG(reference, dummy, platform),
},
[BXT_DPCM_AUDIO_DMIC_CP] =
{
.name = "Bxt Audio DMIC cap",
.stream_name = "dmiccap",
.cpu_dai_name = "DMIC Pin",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.platform_name = "0000:00:0e.0",
.init = NULL,
.dpcm_capture = 1,
.nonatomic = 1,
.dynamic = 1,
.ops = &broxton_dmic_ops,
SND_SOC_DAILINK_REG(dmic, dummy, platform),
},
[BXT_DPCM_AUDIO_HDMI1_PB] =
{
.name = "Bxt HDMI Port1",
.stream_name = "Hdmi1",
.cpu_dai_name = "HDMI1 Pin",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.platform_name = "0000:00:0e.0",
.dpcm_playback = 1,
.init = NULL,
.nonatomic = 1,
.dynamic = 1,
SND_SOC_DAILINK_REG(hdmi1, dummy, platform),
},
[BXT_DPCM_AUDIO_HDMI2_PB] =
{
.name = "Bxt HDMI Port2",
.stream_name = "Hdmi2",
.cpu_dai_name = "HDMI2 Pin",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.platform_name = "0000:00:0e.0",
.dpcm_playback = 1,
.init = NULL,
.nonatomic = 1,
.dynamic = 1,
SND_SOC_DAILINK_REG(hdmi2, dummy, platform),
},
[BXT_DPCM_AUDIO_HDMI3_PB] =
{
.name = "Bxt HDMI Port3",
.stream_name = "Hdmi3",
.cpu_dai_name = "HDMI3 Pin",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.platform_name = "0000:00:0e.0",
.dpcm_playback = 1,
.init = NULL,
.nonatomic = 1,
.dynamic = 1,
SND_SOC_DAILINK_REG(hdmi3, dummy, platform),
},
/* Back End DAI links */
{
/* SSP5 - Codec */
.name = "SSP5-Codec",
.id = 0,
.cpu_dai_name = "SSP5 Pin",
.platform_name = "0000:00:0e.0",
.no_pcm = 1,
.codec_name = "MX98357A:00",
.codec_dai_name = BXT_MAXIM_CODEC_DAI,
.dai_fmt = SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
.ignore_pmdown_time = 1,
.be_hw_params_fixup = broxton_ssp_fixup,
.dpcm_playback = 1,
SND_SOC_DAILINK_REG(ssp5_pin, ssp5_codec, platform),
},
{
/* SSP1 - Codec */
.name = "SSP1-Codec",
.id = 1,
.cpu_dai_name = "SSP1 Pin",
.platform_name = "0000:00:0e.0",
.no_pcm = 1,
.codec_name = "i2c-DLGS7219:00",
.codec_dai_name = BXT_DIALOG_CODEC_DAI,
.init = broxton_da7219_codec_init,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
@@ -512,57 +547,49 @@ static struct snd_soc_dai_link broxton_dais[] = {
.be_hw_params_fixup = broxton_ssp_fixup,
.dpcm_playback = 1,
.dpcm_capture = 1,
SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform),
},
{
.name = "dmic01",
.id = 2,
.cpu_dai_name = "DMIC01 Pin",
.codec_name = "dmic-codec",
.codec_dai_name = "dmic-hifi",
.platform_name = "0000:00:0e.0",
.ignore_suspend = 1,
.be_hw_params_fixup = broxton_dmic_fixup,
.dpcm_capture = 1,
.no_pcm = 1,
SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform),
},
{
.name = "iDisp1",
.id = 3,
.cpu_dai_name = "iDisp1 Pin",
.codec_name = "ehdaudio0D2",
.codec_dai_name = "intel-hdmi-hifi1",
.platform_name = "0000:00:0e.0",
.init = broxton_hdmi_init,
.dpcm_playback = 1,
.no_pcm = 1,
SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform),
},
{
.name = "iDisp2",
.id = 4,
.cpu_dai_name = "iDisp2 Pin",
.codec_name = "ehdaudio0D2",
.codec_dai_name = "intel-hdmi-hifi2",
.platform_name = "0000:00:0e.0",
.init = broxton_hdmi_init,
.dpcm_playback = 1,
.no_pcm = 1,
SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform),
},
{
.name = "iDisp3",
.id = 5,
.cpu_dai_name = "iDisp3 Pin",
.codec_name = "ehdaudio0D2",
.codec_dai_name = "intel-hdmi-hifi3",
.platform_name = "0000:00:0e.0",
.init = broxton_hdmi_init,
.dpcm_playback = 1,
.no_pcm = 1,
SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform),
},
{
.name = "dmic16k",
.id = 6,
.be_hw_params_fixup = broxton_dmic_fixup,
.dpcm_capture = 1,
.no_pcm = 1,
SND_SOC_DAILINK_REG(dmic16k_pin, dmic_codec, platform),
},
};
static const struct x86_cpu_id glk_ids[] = {
{ X86_VENDOR_INTEL, 6, 0x7A }, /* Geminilake CPU_ID */
{}
};
#define NAME_SIZE 32
@@ -574,7 +601,7 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
int err, i = 0;
char jack_name[NAME_SIZE];
if (x86_match_cpu(glk_ids))
if (soc_intel_is_glk())
snd_soc_dapm_add_routes(&card->dapm, gemini_map,
ARRAY_SIZE(gemini_map));
else
@@ -637,23 +664,23 @@ static int broxton_audio_probe(struct platform_device *pdev)
broxton_audio_card.dev = &pdev->dev;
snd_soc_card_set_drvdata(&broxton_audio_card, ctx);
if (x86_match_cpu(glk_ids)) {
if (soc_intel_is_glk()) {
unsigned int i;
broxton_audio_card.name = "glkda7219max";
/* Fixup the SSP entries for geminilake */
for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) {
/* MAXIM_CODEC is connected to SSP1. */
if (!strcmp(broxton_dais[i].codec_dai_name,
if (!strcmp(broxton_dais[i].codecs->dai_name,
BXT_MAXIM_CODEC_DAI)) {
broxton_dais[i].name = "SSP1-Codec";
broxton_dais[i].cpu_dai_name = "SSP1 Pin";
broxton_dais[i].cpus->dai_name = "SSP1 Pin";
}
/* DIALOG_CODE is connected to SSP2 */
else if (!strcmp(broxton_dais[i].codec_dai_name,
else if (!strcmp(broxton_dais[i].codecs->dai_name,
BXT_DIALOG_CODEC_DAI)) {
broxton_dais[i].name = "SSP2-Codec";
broxton_dais[i].cpu_dai_name = "SSP2 Pin";
broxton_dais[i].cpus->dai_name = "SSP2 Pin";
}
}
}

파일 보기

@@ -323,6 +323,64 @@ static const struct snd_soc_ops broxton_rt286_fe_ops = {
.startup = bxt_fe_startup,
};
SND_SOC_DAILINK_DEF(dummy,
DAILINK_COMP_ARRAY(COMP_DUMMY()));
SND_SOC_DAILINK_DEF(system,
DAILINK_COMP_ARRAY(COMP_CPU("System Pin")));
SND_SOC_DAILINK_DEF(reference,
DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin")));
SND_SOC_DAILINK_DEF(dmic,
DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin")));
SND_SOC_DAILINK_DEF(hdmi1,
DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin")));
SND_SOC_DAILINK_DEF(hdmi2,
DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin")));
SND_SOC_DAILINK_DEF(hdmi3,
DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin")));
SND_SOC_DAILINK_DEF(ssp5_pin,
DAILINK_COMP_ARRAY(COMP_CPU("SSP5 Pin")));
SND_SOC_DAILINK_DEF(ssp5_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-INT343A:00",
"rt298-aif1")));
SND_SOC_DAILINK_DEF(dmic_pin,
DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin")));
SND_SOC_DAILINK_DEF(dmic_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec",
"dmic-hifi")));
SND_SOC_DAILINK_DEF(dmic16k,
DAILINK_COMP_ARRAY(COMP_CPU("DMIC16k Pin")));
SND_SOC_DAILINK_DEF(idisp1_pin,
DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin")));
SND_SOC_DAILINK_DEF(idisp1_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2",
"intel-hdmi-hifi1")));
SND_SOC_DAILINK_DEF(idisp2_pin,
DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin")));
SND_SOC_DAILINK_DEF(idisp2_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2",
"intel-hdmi-hifi2")));
SND_SOC_DAILINK_DEF(idisp3_pin,
DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin")));
SND_SOC_DAILINK_DEF(idisp3_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2",
"intel-hdmi-hifi3")));
SND_SOC_DAILINK_DEF(platform,
DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:0e.0")));
/* broxton digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link broxton_rt298_dais[] = {
/* Front End DAI links */
@@ -330,107 +388,82 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
{
.name = "Bxt Audio Port",
.stream_name = "Audio",
.cpu_dai_name = "System Pin",
.platform_name = "0000:00:0e.0",
.nonatomic = 1,
.dynamic = 1,
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.init = broxton_rt298_fe_init,
.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
.dpcm_playback = 1,
.ops = &broxton_rt286_fe_ops,
SND_SOC_DAILINK_REG(system, dummy, platform),
},
[BXT_DPCM_AUDIO_CP] =
{
.name = "Bxt Audio Capture Port",
.stream_name = "Audio Record",
.cpu_dai_name = "System Pin",
.platform_name = "0000:00:0e.0",
.nonatomic = 1,
.dynamic = 1,
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
.dpcm_capture = 1,
.ops = &broxton_rt286_fe_ops,
SND_SOC_DAILINK_REG(system, dummy, platform),
},
[BXT_DPCM_AUDIO_REF_CP] =
{
.name = "Bxt Audio Reference cap",
.stream_name = "refcap",
.cpu_dai_name = "Reference Pin",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.platform_name = "0000:00:0e.0",
.init = NULL,
.dpcm_capture = 1,
.nonatomic = 1,
.dynamic = 1,
SND_SOC_DAILINK_REG(reference, dummy, platform),
},
[BXT_DPCM_AUDIO_DMIC_CP] =
{
.name = "Bxt Audio DMIC cap",
.stream_name = "dmiccap",
.cpu_dai_name = "DMIC Pin",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.platform_name = "0000:00:0e.0",
.init = NULL,
.dpcm_capture = 1,
.nonatomic = 1,
.dynamic = 1,
.ops = &broxton_dmic_ops,
SND_SOC_DAILINK_REG(dmic, dummy, platform),
},
[BXT_DPCM_AUDIO_HDMI1_PB] =
{
.name = "Bxt HDMI Port1",
.stream_name = "Hdmi1",
.cpu_dai_name = "HDMI1 Pin",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.platform_name = "0000:00:0e.0",
.dpcm_playback = 1,
.init = NULL,
.nonatomic = 1,
.dynamic = 1,
SND_SOC_DAILINK_REG(hdmi1, dummy, platform),
},
[BXT_DPCM_AUDIO_HDMI2_PB] =
{
.name = "Bxt HDMI Port2",
.stream_name = "Hdmi2",
.cpu_dai_name = "HDMI2 Pin",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.platform_name = "0000:00:0e.0",
.dpcm_playback = 1,
.init = NULL,
.nonatomic = 1,
.dynamic = 1,
SND_SOC_DAILINK_REG(hdmi2, dummy, platform),
},
[BXT_DPCM_AUDIO_HDMI3_PB] =
{
.name = "Bxt HDMI Port3",
.stream_name = "Hdmi3",
.cpu_dai_name = "HDMI3 Pin",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.platform_name = "0000:00:0e.0",
.dpcm_playback = 1,
.init = NULL,
.nonatomic = 1,
.dynamic = 1,
SND_SOC_DAILINK_REG(hdmi3, dummy, platform),
},
/* Back End DAI links */
{
/* SSP5 - Codec */
.name = "SSP5-Codec",
.id = 0,
.cpu_dai_name = "SSP5 Pin",
.platform_name = "0000:00:0e.0",
.no_pcm = 1,
.codec_name = "i2c-INT343A:00",
.codec_dai_name = "rt298-aif1",
.init = broxton_rt298_codec_init,
.dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
@@ -439,63 +472,49 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
.ops = &broxton_rt298_ops,
.dpcm_playback = 1,
.dpcm_capture = 1,
SND_SOC_DAILINK_REG(ssp5_pin, ssp5_codec, platform),
},
{
.name = "dmic01",
.id = 1,
.cpu_dai_name = "DMIC01 Pin",
.codec_name = "dmic-codec",
.codec_dai_name = "dmic-hifi",
.platform_name = "0000:00:0e.0",
.be_hw_params_fixup = broxton_dmic_fixup,
.ignore_suspend = 1,
.dpcm_capture = 1,
.no_pcm = 1,
SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform),
},
{
.name = "dmic16k",
.id = 2,
.cpu_dai_name = "DMIC16k Pin",
.codec_name = "dmic-codec",
.codec_dai_name = "dmic-hifi",
.platform_name = "0000:00:0e.0",
.be_hw_params_fixup = broxton_dmic_fixup,
.ignore_suspend = 1,
.dpcm_capture = 1,
.no_pcm = 1,
SND_SOC_DAILINK_REG(dmic16k, dmic_codec, platform),
},
{
.name = "iDisp1",
.id = 3,
.cpu_dai_name = "iDisp1 Pin",
.codec_name = "ehdaudio0D2",
.codec_dai_name = "intel-hdmi-hifi1",
.platform_name = "0000:00:0e.0",
.init = broxton_hdmi_init,
.dpcm_playback = 1,
.no_pcm = 1,
SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform),
},
{
.name = "iDisp2",
.id = 4,
.cpu_dai_name = "iDisp2 Pin",
.codec_name = "ehdaudio0D2",
.codec_dai_name = "intel-hdmi-hifi2",
.platform_name = "0000:00:0e.0",
.init = broxton_hdmi_init,
.dpcm_playback = 1,
.no_pcm = 1,
SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform),
},
{
.name = "iDisp3",
.id = 5,
.cpu_dai_name = "iDisp3 Pin",
.codec_name = "ehdaudio0D2",
.codec_dai_name = "intel-hdmi-hifi3",
.platform_name = "0000:00:0e.0",
.init = broxton_hdmi_init,
.dpcm_playback = 1,
.no_pcm = 1,
SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform),
},
};
@@ -575,16 +594,16 @@ static int broxton_audio_probe(struct platform_device *pdev)
int i;
for (i = 0; i < ARRAY_SIZE(broxton_rt298_dais); i++) {
if (!strncmp(card->dai_link[i].codec_name, "i2c-INT343A:00",
I2C_NAME_SIZE)) {
if (!strncmp(card->dai_link[i].codecs->name, "i2c-INT343A:00",
I2C_NAME_SIZE)) {
if (!strncmp(card->name, "broxton-rt298",
PLATFORM_NAME_SIZE)) {
PLATFORM_NAME_SIZE)) {
card->dai_link[i].name = "SSP5-Codec";
card->dai_link[i].cpu_dai_name = "SSP5 Pin";
card->dai_link[i].cpus->dai_name = "SSP5 Pin";
} else if (!strncmp(card->name, "geminilake-rt298",
PLATFORM_NAME_SIZE)) {
PLATFORM_NAME_SIZE)) {
card->dai_link[i].name = "SSP2-Codec";
card->dai_link[i].cpu_dai_name = "SSP2 Pin";
card->dai_link[i].cpus->dai_name = "SSP2 Pin";
}
}
}

파일 보기

@@ -109,17 +109,19 @@ static int byt_max98090_init(struct snd_soc_pcm_runtime *runtime)
hs_jack_gpios);
}
SND_SOC_DAILINK_DEFS(baytrail,
DAILINK_COMP_ARRAY(COMP_CPU("baytrail-pcm-audio")),
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-193C9890:00", "HiFi")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("baytrail-pcm-audio")));
static struct snd_soc_dai_link byt_max98090_dais[] = {
{
.name = "Baytrail Audio",
.stream_name = "Audio",
.cpu_dai_name = "baytrail-pcm-audio",
.codec_dai_name = "HiFi",
.codec_name = "i2c-193C9890:00",
.platform_name = "baytrail-pcm-audio",
.init = byt_max98090_init,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
SND_SOC_DAILINK_REG(baytrail),
},
};

파일 보기

@@ -172,18 +172,20 @@ static struct snd_soc_ops byt_rt5640_ops = {
.hw_params = byt_rt5640_hw_params,
};
SND_SOC_DAILINK_DEFS(audio,
DAILINK_COMP_ARRAY(COMP_CPU("baytrail-pcm-audio")),
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5640:00", "rt5640-aif1")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("baytrail-pcm-audio")));
static struct snd_soc_dai_link byt_rt5640_dais[] = {
{
.name = "Baytrail Audio",
.stream_name = "Audio",
.cpu_dai_name = "baytrail-pcm-audio",
.codec_dai_name = "rt5640-aif1",
.codec_name = "i2c-10EC5640:00",
.platform_name = "baytrail-pcm-audio",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
.init = byt_rt5640_init,
.ops = &byt_rt5640_ops,
SND_SOC_DAILINK_REG(audio),
},
};

파일 보기

@@ -0,0 +1,270 @@
// SPDX-License-Identifier: GPL-2.0
//
// ASoC DPCM Machine driver for Baytrail / Cherrytrail platforms with
// CX2072X codec
//
#include <linux/acpi.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/jack.h>
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include "../../codecs/cx2072x.h"
#include "../atom/sst-atom-controls.h"
static const struct snd_soc_dapm_widget byt_cht_cx2072x_widgets[] = {
SND_SOC_DAPM_HP("Headphone", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
SND_SOC_DAPM_MIC("Int Mic", NULL),
SND_SOC_DAPM_SPK("Ext Spk", NULL),
};
static const struct snd_soc_dapm_route byt_cht_cx2072x_audio_map[] = {
/* External Speakers: HFL, HFR */
{"Headphone", NULL, "PORTA"},
{"Ext Spk", NULL, "PORTG"},
{"PORTC", NULL, "Int Mic"},
{"PORTD", NULL, "Headset Mic"},
{"Playback", NULL, "ssp2 Tx"},
{"ssp2 Tx", NULL, "codec_out0"},
{"ssp2 Tx", NULL, "codec_out1"},
{"codec_in0", NULL, "ssp2 Rx"},
{"codec_in1", NULL, "ssp2 Rx"},
{"ssp2 Rx", NULL, "Capture"},
};
static const struct snd_kcontrol_new byt_cht_cx2072x_controls[] = {
SOC_DAPM_PIN_SWITCH("Headphone"),
SOC_DAPM_PIN_SWITCH("Headset Mic"),
SOC_DAPM_PIN_SWITCH("Int Mic"),
SOC_DAPM_PIN_SWITCH("Ext Spk"),
};
static struct snd_soc_jack byt_cht_cx2072x_headset;
/* Headset jack detection DAPM pins */
static struct snd_soc_jack_pin byt_cht_cx2072x_headset_pins[] = {
{
.pin = "Headset Mic",
.mask = SND_JACK_MICROPHONE,
},
{
.pin = "Headphone",
.mask = SND_JACK_HEADPHONE,
},
};
static const struct acpi_gpio_params byt_cht_cx2072x_headset_gpios;
static const struct acpi_gpio_mapping byt_cht_cx2072x_acpi_gpios[] = {
{ "headset-gpios", &byt_cht_cx2072x_headset_gpios, 1 },
{},
};
static int byt_cht_cx2072x_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
struct snd_soc_component *codec = rtd->codec_dai->component;
int ret;
if (devm_acpi_dev_add_driver_gpios(codec->dev,
byt_cht_cx2072x_acpi_gpios))
dev_warn(rtd->dev, "Unable to add GPIO mapping table\n");
card->dapm.idle_bias_off = true;
/* set the default PLL rate, the clock is handled by the codec driver */
ret = snd_soc_dai_set_sysclk(rtd->codec_dai, CX2072X_MCLK_EXTERNAL_PLL,
19200000, SND_SOC_CLOCK_IN);
if (ret) {
dev_err(rtd->dev, "Could not set sysclk\n");
return ret;
}
ret = snd_soc_card_jack_new(card, "Headset",
SND_JACK_HEADSET | SND_JACK_BTN_0,
&byt_cht_cx2072x_headset,
byt_cht_cx2072x_headset_pins,
ARRAY_SIZE(byt_cht_cx2072x_headset_pins));
if (ret)
return ret;
snd_soc_component_set_jack(codec, &byt_cht_cx2072x_headset, NULL);
snd_soc_dai_set_bclk_ratio(rtd->codec_dai, 50);
return ret;
}
static int byt_cht_cx2072x_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
struct snd_interval *rate =
hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
struct snd_interval *channels =
hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
int ret;
/* The DSP will covert the FE rate to 48k, stereo, 24bits */
rate->min = rate->max = 48000;
channels->min = channels->max = 2;
/* set SSP2 to 24-bit */
params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
/*
* Default mode for SSP configuration is TDM 4 slot, override config
* with explicit setting to I2S 2ch 24-bit. The word length is set with
* dai_set_tdm_slot() since there is no other API exposed
*/
ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS);
if (ret < 0) {
dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
return ret;
}
ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
if (ret < 0) {
dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
return ret;
}
return 0;
}
static int byt_cht_cx2072x_aif1_startup(struct snd_pcm_substream *substream)
{
return snd_pcm_hw_constraint_single(substream->runtime,
SNDRV_PCM_HW_PARAM_RATE, 48000);
}
static struct snd_soc_ops byt_cht_cx2072x_aif1_ops = {
.startup = byt_cht_cx2072x_aif1_startup,
};
SND_SOC_DAILINK_DEF(dummy,
DAILINK_COMP_ARRAY(COMP_DUMMY()));
SND_SOC_DAILINK_DEF(media,
DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai")));
SND_SOC_DAILINK_DEF(deepbuffer,
DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai")));
SND_SOC_DAILINK_DEF(ssp2,
DAILINK_COMP_ARRAY(COMP_CPU("ssp2-port")));
SND_SOC_DAILINK_DEF(cx2072x,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-14F10720:00", "cx2072x-hifi")));
SND_SOC_DAILINK_DEF(platform,
DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform")));
static struct snd_soc_dai_link byt_cht_cx2072x_dais[] = {
[MERR_DPCM_AUDIO] = {
.name = "Audio Port",
.stream_name = "Audio",
.nonatomic = true,
.dynamic = 1,
.dpcm_playback = 1,
.dpcm_capture = 1,
.ops = &byt_cht_cx2072x_aif1_ops,
SND_SOC_DAILINK_REG(media, dummy, platform),
},
[MERR_DPCM_DEEP_BUFFER] = {
.name = "Deep-Buffer Audio Port",
.stream_name = "Deep-Buffer Audio",
.nonatomic = true,
.dynamic = 1,
.dpcm_playback = 1,
.ops = &byt_cht_cx2072x_aif1_ops,
SND_SOC_DAILINK_REG(deepbuffer, dummy, platform),
},
/* back ends */
{
.name = "SSP2-Codec",
.id = 0,
.no_pcm = 1,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBS_CFS,
.init = byt_cht_cx2072x_init,
.be_hw_params_fixup = byt_cht_cx2072x_fixup,
.nonatomic = true,
.dpcm_playback = 1,
.dpcm_capture = 1,
SND_SOC_DAILINK_REG(ssp2, cx2072x, platform),
},
};
/* SoC card */
static struct snd_soc_card byt_cht_cx2072x_card = {
.name = "bytcht-cx2072x",
.owner = THIS_MODULE,
.dai_link = byt_cht_cx2072x_dais,
.num_links = ARRAY_SIZE(byt_cht_cx2072x_dais),
.dapm_widgets = byt_cht_cx2072x_widgets,
.num_dapm_widgets = ARRAY_SIZE(byt_cht_cx2072x_widgets),
.dapm_routes = byt_cht_cx2072x_audio_map,
.num_dapm_routes = ARRAY_SIZE(byt_cht_cx2072x_audio_map),
.controls = byt_cht_cx2072x_controls,
.num_controls = ARRAY_SIZE(byt_cht_cx2072x_controls),
};
static char codec_name[SND_ACPI_I2C_ID_LEN];
static int snd_byt_cht_cx2072x_probe(struct platform_device *pdev)
{
struct snd_soc_acpi_mach *mach;
struct acpi_device *adev;
int dai_index = 0;
int i, ret;
byt_cht_cx2072x_card.dev = &pdev->dev;
mach = dev_get_platdata(&pdev->dev);
/* fix index of codec dai */
for (i = 0; i < ARRAY_SIZE(byt_cht_cx2072x_dais); i++) {
if (!strcmp(byt_cht_cx2072x_dais[i].codecs->name,
"i2c-14F10720:00")) {
dai_index = i;
break;
}
}
/* fixup codec name based on HID */
adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1);
if (adev) {
snprintf(codec_name, sizeof(codec_name), "i2c-%s",
acpi_dev_name(adev));
put_device(&adev->dev);
byt_cht_cx2072x_dais[dai_index].codecs->name = codec_name;
}
/* override plaform name, if required */
ret = snd_soc_fixup_dai_links_platform_name(&byt_cht_cx2072x_card,
mach->mach_params.platform);
if (ret)
return ret;
return devm_snd_soc_register_card(&pdev->dev, &byt_cht_cx2072x_card);
}
static struct platform_driver snd_byt_cht_cx2072x_driver = {
.driver = {
.name = "bytcht_cx2072x",
},
.probe = snd_byt_cht_cx2072x_probe,
};
module_platform_driver(snd_byt_cht_cx2072x_driver);
MODULE_DESCRIPTION("ASoC Intel(R) Baytrail/Cherrytrail Machine driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:bytcht_cx2072x");

파일 보기

@@ -15,7 +15,6 @@
#include <linux/acpi.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <asm/platform_sst_audio.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
@@ -151,42 +150,50 @@ static const struct snd_soc_ops ssp2_ops = {
};
SND_SOC_DAILINK_DEF(dummy,
DAILINK_COMP_ARRAY(COMP_DUMMY()));
SND_SOC_DAILINK_DEF(media,
DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai")));
SND_SOC_DAILINK_DEF(deepbuffer,
DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai")));
SND_SOC_DAILINK_DEF(ssp2_port,
DAILINK_COMP_ARRAY(COMP_CPU("ssp2-port")));
SND_SOC_DAILINK_DEF(ssp2_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-DLGS7213:00",
"da7213-hifi")));
SND_SOC_DAILINK_DEF(platform,
DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform")));
static struct snd_soc_dai_link dailink[] = {
[MERR_DPCM_AUDIO] = {
.name = "Audio Port",
.stream_name = "Audio",
.cpu_dai_name = "media-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
.nonatomic = true,
.dynamic = 1,
.dpcm_playback = 1,
.dpcm_capture = 1,
.ops = &aif1_ops,
SND_SOC_DAILINK_REG(media, dummy, platform),
},
[MERR_DPCM_DEEP_BUFFER] = {
.name = "Deep-Buffer Audio Port",
.stream_name = "Deep-Buffer Audio",
.cpu_dai_name = "deepbuffer-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
.nonatomic = true,
.dynamic = 1,
.dpcm_playback = 1,
.ops = &aif1_ops,
SND_SOC_DAILINK_REG(deepbuffer, dummy, platform),
},
/* CODEC<->CODEC link */
/* back ends */
{
.name = "SSP2-Codec",
.id = 0,
.cpu_dai_name = "ssp2-port",
.platform_name = "sst-mfld-platform",
.no_pcm = 1,
.codec_dai_name = "da7213-hifi",
.codec_name = "i2c-DLGS7213:00",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBS_CFS,
.be_hw_params_fixup = codec_fixup,
@@ -194,6 +201,7 @@ static struct snd_soc_dai_link dailink[] = {
.dpcm_playback = 1,
.dpcm_capture = 1,
.ops = &ssp2_ops,
SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
},
};
@@ -229,7 +237,7 @@ static int bytcht_da7213_probe(struct platform_device *pdev)
/* fix index of codec dai */
for (i = 0; i < ARRAY_SIZE(dailink); i++) {
if (!strcmp(dailink[i].codec_name, "i2c-DLGS7213:00")) {
if (!strcmp(dailink[i].codecs->name, "i2c-DLGS7213:00")) {
dai_index = i;
break;
}
@@ -241,7 +249,7 @@ static int bytcht_da7213_probe(struct platform_device *pdev)
snprintf(codec_name, sizeof(codec_name),
"i2c-%s", acpi_dev_name(adev));
put_device(&adev->dev);
dailink[dai_index].codec_name = codec_name;
dailink[dai_index].codecs->name = codec_name;
}
/* override plaform name, if required */

파일 보기

@@ -22,9 +22,6 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <asm/cpu_device_id.h>
#include <asm/intel-family.h>
#include <asm/platform_sst_audio.h>
#include <sound/jack.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -32,6 +29,7 @@
#include <sound/soc-acpi.h>
#include "../atom/sst-atom-controls.h"
#include "../common/sst-dsp.h"
#include "../common/soc-intel-quirks.h"
/* jd-inv + terminating entry */
#define MAX_NO_PROPS 2
@@ -301,32 +299,43 @@ static const struct snd_soc_ops byt_cht_es8316_aif1_ops = {
.startup = byt_cht_es8316_aif1_startup,
};
SND_SOC_DAILINK_DEF(dummy,
DAILINK_COMP_ARRAY(COMP_DUMMY()));
SND_SOC_DAILINK_DEF(media,
DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai")));
SND_SOC_DAILINK_DEF(deepbuffer,
DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai")));
SND_SOC_DAILINK_DEF(ssp2_port,
DAILINK_COMP_ARRAY(COMP_CPU("ssp2-port")));
SND_SOC_DAILINK_DEF(ssp2_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-ESSX8316:00", "ES8316 HiFi")));
SND_SOC_DAILINK_DEF(platform,
DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform")));
static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
[MERR_DPCM_AUDIO] = {
.name = "Audio Port",
.stream_name = "Audio",
.cpu_dai_name = "media-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
.nonatomic = true,
.dynamic = 1,
.dpcm_playback = 1,
.dpcm_capture = 1,
.ops = &byt_cht_es8316_aif1_ops,
SND_SOC_DAILINK_REG(media, dummy, platform),
},
[MERR_DPCM_DEEP_BUFFER] = {
.name = "Deep-Buffer Audio Port",
.stream_name = "Deep-Buffer Audio",
.cpu_dai_name = "deepbuffer-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
.nonatomic = true,
.dynamic = 1,
.dpcm_playback = 1,
.ops = &byt_cht_es8316_aif1_ops,
SND_SOC_DAILINK_REG(deepbuffer, dummy, platform),
},
/* back ends */
@@ -336,11 +345,7 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
*/
.name = "SSP2-Codec",
.id = 0,
.cpu_dai_name = "ssp2-port",
.platform_name = "sst-mfld-platform",
.no_pcm = 1,
.codec_dai_name = "ES8316 HiFi",
.codec_name = "i2c-ESSX8316:00",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBS_CFS,
.be_hw_params_fixup = byt_cht_es8316_codec_fixup,
@@ -348,6 +353,7 @@ static struct snd_soc_dai_link byt_cht_es8316_dais[] = {
.dpcm_playback = 1,
.dpcm_capture = 1,
.init = byt_cht_es8316_init,
SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
},
};
@@ -422,11 +428,6 @@ static struct snd_soc_card byt_cht_es8316_card = {
.resume_post = byt_cht_es8316_resume,
};
static const struct x86_cpu_id baytrail_cpu_ids[] = {
{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT }, /* Valleyview */
{}
};
static const struct acpi_gpio_params first_gpio = { 0, 0, false };
static const struct acpi_gpio_mapping byt_cht_es8316_gpios[] = {
@@ -470,7 +471,7 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
mach = dev->platform_data;
/* fix index of codec dai */
for (i = 0; i < ARRAY_SIZE(byt_cht_es8316_dais); i++) {
if (!strcmp(byt_cht_es8316_dais[i].codec_name,
if (!strcmp(byt_cht_es8316_dais[i].codecs->name,
"i2c-ESSX8316:00")) {
dai_index = i;
break;
@@ -483,7 +484,7 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
snprintf(codec_name, sizeof(codec_name),
"i2c-%s", acpi_dev_name(adev));
put_device(&adev->dev);
byt_cht_es8316_dais[dai_index].codec_name = codec_name;
byt_cht_es8316_dais[dai_index].codecs->name = codec_name;
}
/* override plaform name, if required */
@@ -499,8 +500,8 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
dmi_id = dmi_first_match(byt_cht_es8316_quirk_table);
if (dmi_id) {
quirk = (unsigned long)dmi_id->driver_data;
} else if (x86_match_cpu(baytrail_cpu_ids) &&
mach->mach_params.acpi_ipc_irq_index == 0) {
} else if (soc_intel_is_byt() &&
mach->mach_params.acpi_ipc_irq_index == 0) {
/* On BYTCR default to SSP0, internal-mic-in2-map, mono-spk */
quirk = BYT_CHT_ES8316_SSP0 | BYT_CHT_ES8316_INTMIC_IN2_MAP |
BYT_CHT_ES8316_MONO_SPEAKER;
@@ -518,7 +519,7 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
log_quirks(dev);
if (quirk & BYT_CHT_ES8316_SSP0)
byt_cht_es8316_dais[dai_index].cpu_dai_name = "ssp0-port";
byt_cht_es8316_dais[dai_index].cpus->dai_name = "ssp0-port";
/* get the clock */
priv->mclk = devm_clk_get(dev, "pmc_plt_clk_3");

파일 보기

@@ -97,44 +97,49 @@ static struct snd_soc_ops aif1_ops = {
.startup = aif1_startup,
};
SND_SOC_DAILINK_DEF(dummy,
DAILINK_COMP_ARRAY(COMP_DUMMY()));
SND_SOC_DAILINK_DEF(media,
DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai")));
SND_SOC_DAILINK_DEF(deepbuffer,
DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai")));
SND_SOC_DAILINK_DEF(ssp2_port,
DAILINK_COMP_ARRAY(COMP_CPU("ssp2-port")));
SND_SOC_DAILINK_DEF(platform,
DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform")));
static struct snd_soc_dai_link dais[] = {
[MERR_DPCM_AUDIO] = {
.name = "Audio Port",
.stream_name = "Audio",
.cpu_dai_name = "media-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
.ignore_suspend = 1,
.nonatomic = true,
.dynamic = 1,
.dpcm_playback = 1,
.dpcm_capture = 1,
.ops = &aif1_ops,
SND_SOC_DAILINK_REG(media, dummy, platform),
},
[MERR_DPCM_DEEP_BUFFER] = {
.name = "Deep-Buffer Audio Port",
.stream_name = "Deep-Buffer Audio",
.cpu_dai_name = "deepbuffer-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
.ignore_suspend = 1,
.nonatomic = true,
.dynamic = 1,
.dpcm_playback = 1,
.ops = &aif1_ops,
SND_SOC_DAILINK_REG(deepbuffer, dummy, platform),
},
/* CODEC<->CODEC link */
/* back ends */
{
.name = "SSP2-LowSpeed Connector",
.id = 0,
.cpu_dai_name = "ssp2-port",
.platform_name = "sst-mfld-platform",
.no_pcm = 1,
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBS_CFS,
.be_hw_params_fixup = codec_fixup,
@@ -142,6 +147,7 @@ static struct snd_soc_dai_link dais[] = {
.nonatomic = true,
.dpcm_playback = 1,
.dpcm_capture = 1,
SND_SOC_DAILINK_REG(ssp2_port, dummy, platform),
},
};

파일 보기

@@ -20,7 +20,6 @@
#include <linux/dmi.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <asm/cpu_device_id.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
@@ -30,6 +29,7 @@
#include "../../codecs/rt5640.h"
#include "../atom/sst-atom-controls.h"
#include "../common/sst-dsp.h"
#include "../common/soc-intel-quirks.h"
enum {
BYT_RT5640_DMIC1_MAP,
@@ -1018,41 +1018,51 @@ static const struct snd_soc_ops byt_rt5640_be_ssp2_ops = {
.hw_params = byt_rt5640_aif1_hw_params,
};
SND_SOC_DAILINK_DEF(dummy,
DAILINK_COMP_ARRAY(COMP_DUMMY()));
SND_SOC_DAILINK_DEF(media,
DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai")));
SND_SOC_DAILINK_DEF(deepbuffer,
DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai")));
SND_SOC_DAILINK_DEF(ssp2_port,
/* overwritten for ssp0 routing */
DAILINK_COMP_ARRAY(COMP_CPU("ssp2-port")));
SND_SOC_DAILINK_DEF(ssp2_codec,
DAILINK_COMP_ARRAY(COMP_CODEC(
/* overwritten with HID */ "i2c-10EC5640:00",
/* changed w/ quirk */ "rt5640-aif1")));
SND_SOC_DAILINK_DEF(platform,
DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform")));
static struct snd_soc_dai_link byt_rt5640_dais[] = {
[MERR_DPCM_AUDIO] = {
.name = "Baytrail Audio Port",
.stream_name = "Baytrail Audio",
.cpu_dai_name = "media-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
.nonatomic = true,
.dynamic = 1,
.dpcm_playback = 1,
.dpcm_capture = 1,
.ops = &byt_rt5640_aif1_ops,
SND_SOC_DAILINK_REG(media, dummy, platform),
},
[MERR_DPCM_DEEP_BUFFER] = {
.name = "Deep-Buffer Audio Port",
.stream_name = "Deep-Buffer Audio",
.cpu_dai_name = "deepbuffer-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
.nonatomic = true,
.dynamic = 1,
.dpcm_playback = 1,
.ops = &byt_rt5640_aif1_ops,
SND_SOC_DAILINK_REG(deepbuffer, dummy, platform),
},
/* back ends */
{
.name = "SSP2-Codec",
.id = 0,
.cpu_dai_name = "ssp2-port", /* overwritten for ssp0 routing */
.platform_name = "sst-mfld-platform",
.no_pcm = 1,
.codec_dai_name = "rt5640-aif1", /* changed w/ quirk */
.codec_name = "i2c-10EC5640:00", /* overwritten with HID */
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBS_CFS,
.be_hw_params_fixup = byt_rt5640_codec_fixup,
@@ -1062,6 +1072,7 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = {
.dpcm_capture = 1,
.init = byt_rt5640_init,
.ops = &byt_rt5640_be_ssp2_ops,
SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
},
};
@@ -1122,18 +1133,6 @@ static struct snd_soc_card byt_rt5640_card = {
.resume_post = byt_rt5640_resume,
};
static bool is_valleyview(void)
{
static const struct x86_cpu_id cpu_ids[] = {
{ X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
{}
};
if (!x86_match_cpu(cpu_ids))
return false;
return true;
}
struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */
u64 aif_value; /* 1: AIF1, 2: AIF2 */
u64 mclock_value; /* usually 25MHz (0x17d7940), ignored */
@@ -1163,7 +1162,8 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
/* fix index of codec dai */
for (i = 0; i < ARRAY_SIZE(byt_rt5640_dais); i++) {
if (!strcmp(byt_rt5640_dais[i].codec_name, "i2c-10EC5640:00")) {
if (!strcmp(byt_rt5640_dais[i].codecs->name,
"i2c-10EC5640:00")) {
dai_index = i;
break;
}
@@ -1175,14 +1175,14 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name),
"i2c-%s", acpi_dev_name(adev));
put_device(&adev->dev);
byt_rt5640_dais[dai_index].codec_name = byt_rt5640_codec_name;
byt_rt5640_dais[dai_index].codecs->name = byt_rt5640_codec_name;
}
/*
* swap SSP0 if bytcr is detected
* (will be overridden if DMI quirk is detected)
*/
if (is_valleyview()) {
if (soc_intel_is_byt()) {
if (mach->mach_params.acpi_ipc_irq_index == 0)
is_bytcr = true;
}
@@ -1267,7 +1267,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
sizeof(byt_rt5640_codec_aif_name),
"%s", "rt5640-aif2");
byt_rt5640_dais[dai_index].codec_dai_name =
byt_rt5640_dais[dai_index].codecs->dai_name =
byt_rt5640_codec_aif_name;
}
@@ -1279,7 +1279,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
sizeof(byt_rt5640_cpu_dai_name),
"%s", "ssp0-port");
byt_rt5640_dais[dai_index].cpu_dai_name =
byt_rt5640_dais[dai_index].cpus->dai_name =
byt_rt5640_cpu_dai_name;
}

파일 보기

@@ -22,8 +22,6 @@
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h>
#include <linux/slab.h>
#include <asm/cpu_device_id.h>
#include <asm/intel-family.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
@@ -31,6 +29,7 @@
#include <sound/soc-acpi.h>
#include "../../codecs/rt5651.h"
#include "../atom/sst-atom-controls.h"
#include "../common/soc-intel-quirks.h"
enum {
BYT_RT5651_DMIC_MAP,
@@ -738,42 +737,49 @@ static const struct snd_soc_ops byt_rt5651_be_ssp2_ops = {
.hw_params = byt_rt5651_aif1_hw_params,
};
SND_SOC_DAILINK_DEF(dummy,
DAILINK_COMP_ARRAY(COMP_DUMMY()));
SND_SOC_DAILINK_DEF(media,
DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai")));
SND_SOC_DAILINK_DEF(deepbuffer,
DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai")));
SND_SOC_DAILINK_DEF(ssp2_port,
DAILINK_COMP_ARRAY(COMP_CPU("ssp2-port")));
SND_SOC_DAILINK_DEF(ssp2_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5651:00", "rt5651-aif1")));
SND_SOC_DAILINK_DEF(platform,
DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform")));
static struct snd_soc_dai_link byt_rt5651_dais[] = {
[MERR_DPCM_AUDIO] = {
.name = "Audio Port",
.stream_name = "Audio",
.cpu_dai_name = "media-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
.nonatomic = true,
.dynamic = 1,
.dpcm_playback = 1,
.dpcm_capture = 1,
.ops = &byt_rt5651_aif1_ops,
SND_SOC_DAILINK_REG(media, dummy, platform),
},
[MERR_DPCM_DEEP_BUFFER] = {
.name = "Deep-Buffer Audio Port",
.stream_name = "Deep-Buffer Audio",
.cpu_dai_name = "deepbuffer-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
.nonatomic = true,
.dynamic = 1,
.dpcm_playback = 1,
.ops = &byt_rt5651_aif1_ops,
SND_SOC_DAILINK_REG(deepbuffer, dummy, platform),
},
/* CODEC<->CODEC link */
/* back ends */
{
.name = "SSP2-Codec",
.id = 0,
.cpu_dai_name = "ssp2-port",
.platform_name = "sst-mfld-platform",
.no_pcm = 1,
.codec_dai_name = "rt5651-aif1",
.codec_name = "i2c-10EC5651:00",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBS_CFS,
.be_hw_params_fixup = byt_rt5651_codec_fixup,
@@ -783,6 +789,7 @@ static struct snd_soc_dai_link byt_rt5651_dais[] = {
.dpcm_capture = 1,
.init = byt_rt5651_init,
.ops = &byt_rt5651_be_ssp2_ops,
SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
},
};
@@ -844,16 +851,6 @@ static struct snd_soc_card byt_rt5651_card = {
.resume_post = byt_rt5651_resume,
};
static const struct x86_cpu_id baytrail_cpu_ids[] = {
{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT }, /* Valleyview */
{}
};
static const struct x86_cpu_id cherrytrail_cpu_ids[] = {
{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_AIRMONT }, /* Braswell */
{}
};
static const struct acpi_gpio_params ext_amp_enable_gpios = { 0, 0, false };
static const struct acpi_gpio_mapping cht_rt5651_gpios[] = {
@@ -897,7 +894,8 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
/* fix index of codec dai */
for (i = 0; i < ARRAY_SIZE(byt_rt5651_dais); i++) {
if (!strcmp(byt_rt5651_dais[i].codec_name, "i2c-10EC5651:00")) {
if (!strcmp(byt_rt5651_dais[i].codecs->name,
"i2c-10EC5651:00")) {
dai_index = i;
break;
}
@@ -909,7 +907,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name),
"i2c-%s", acpi_dev_name(adev));
put_device(&adev->dev);
byt_rt5651_dais[dai_index].codec_name = byt_rt5651_codec_name;
byt_rt5651_dais[dai_index].codecs->name = byt_rt5651_codec_name;
} else {
dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id);
return -ENODEV;
@@ -924,7 +922,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
* swap SSP0 if bytcr is detected
* (will be overridden if DMI quirk is detected)
*/
if (x86_match_cpu(baytrail_cpu_ids)) {
if (soc_intel_is_byt()) {
if (mach->mach_params.acpi_ipc_irq_index == 0)
is_bytcr = true;
}
@@ -993,7 +991,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
}
/* Cherry Trail devices use an external amplifier enable gpio */
if (x86_match_cpu(cherrytrail_cpu_ids) && !byt_rt5651_gpios)
if (soc_intel_is_cht() && !byt_rt5651_gpios)
byt_rt5651_gpios = cht_rt5651_gpios;
if (byt_rt5651_gpios) {
@@ -1049,7 +1047,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
sizeof(byt_rt5651_codec_aif_name),
"%s", "rt5651-aif2");
byt_rt5651_dais[dai_index].codec_dai_name =
byt_rt5651_dais[dai_index].codecs->dai_name =
byt_rt5651_codec_aif_name;
}
@@ -1060,7 +1058,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
sizeof(byt_rt5651_cpu_dai_name),
"%s", "ssp0-port");
byt_rt5651_dais[dai_index].cpu_dai_name =
byt_rt5651_dais[dai_index].cpus->dai_name =
byt_rt5651_cpu_dai_name;
}

파일 보기

@@ -329,41 +329,48 @@ static struct snd_soc_aux_dev cht_max98090_headset_dev = {
.codec_name = "i2c-104C227E:00",
};
SND_SOC_DAILINK_DEF(dummy,
DAILINK_COMP_ARRAY(COMP_DUMMY()));
SND_SOC_DAILINK_DEF(media,
DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai")));
SND_SOC_DAILINK_DEF(deepbuffer,
DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai")));
SND_SOC_DAILINK_DEF(ssp2_port,
DAILINK_COMP_ARRAY(COMP_CPU("ssp2-port")));
SND_SOC_DAILINK_DEF(ssp2_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-193C9890:00", "HiFi")));
SND_SOC_DAILINK_DEF(platform,
DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform")));
static struct snd_soc_dai_link cht_dailink[] = {
[MERR_DPCM_AUDIO] = {
.name = "Audio Port",
.stream_name = "Audio",
.cpu_dai_name = "media-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
.nonatomic = true,
.dynamic = 1,
.dpcm_playback = 1,
.dpcm_capture = 1,
.ops = &cht_aif1_ops,
SND_SOC_DAILINK_REG(media, dummy, platform),
},
[MERR_DPCM_DEEP_BUFFER] = {
.name = "Deep-Buffer Audio Port",
.stream_name = "Deep-Buffer Audio",
.cpu_dai_name = "deepbuffer-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
.nonatomic = true,
.dynamic = 1,
.dpcm_playback = 1,
.ops = &cht_aif1_ops,
SND_SOC_DAILINK_REG(deepbuffer, dummy, platform),
},
/* back ends */
{
.name = "SSP2-Codec",
.id = 0,
.cpu_dai_name = "ssp2-port",
.platform_name = "sst-mfld-platform",
.no_pcm = 1,
.codec_dai_name = "HiFi",
.codec_name = "i2c-193C9890:00",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBS_CFS,
.init = cht_codec_init,
@@ -371,6 +378,7 @@ static struct snd_soc_dai_link cht_dailink[] = {
.dpcm_playback = 1,
.dpcm_capture = 1,
.ops = &cht_be_ssp2_ops,
SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
},
};

파일 보기

@@ -167,51 +167,59 @@ static const struct snd_soc_ops cht_be_ssp2_ops = {
.hw_params = cht_aif1_hw_params,
};
SND_SOC_DAILINK_DEF(dummy,
DAILINK_COMP_ARRAY(COMP_DUMMY()));
SND_SOC_DAILINK_DEF(media,
DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai")));
SND_SOC_DAILINK_DEF(deepbuffer,
DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai")));
SND_SOC_DAILINK_DEF(compress,
DAILINK_COMP_ARRAY(COMP_CPU("compress-cpu-dai")));
SND_SOC_DAILINK_DEF(ssp2_port,
DAILINK_COMP_ARRAY(COMP_CPU("ssp2-port")));
SND_SOC_DAILINK_DEF(ssp2_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10508824:00",
NAU8824_CODEC_DAI)));
SND_SOC_DAILINK_DEF(platform,
DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform")));
static struct snd_soc_dai_link cht_dailink[] = {
/* Front End DAI links */
[MERR_DPCM_AUDIO] = {
.name = "Audio Port",
.stream_name = "Audio",
.cpu_dai_name = "media-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
.nonatomic = true,
.dynamic = 1,
.dpcm_playback = 1,
.dpcm_capture = 1,
.ops = &cht_aif1_ops,
SND_SOC_DAILINK_REG(media, dummy, platform),
},
[MERR_DPCM_DEEP_BUFFER] = {
.name = "Deep-Buffer Audio Port",
.stream_name = "Deep-Buffer Audio",
.cpu_dai_name = "deepbuffer-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
.nonatomic = true,
.dynamic = 1,
.dpcm_playback = 1,
.ops = &cht_aif1_ops,
SND_SOC_DAILINK_REG(deepbuffer, dummy, platform),
},
[MERR_DPCM_COMPR] = {
.name = "Compressed Port",
.stream_name = "Compress",
.cpu_dai_name = "compress-cpu-dai",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
.platform_name = "sst-mfld-platform",
SND_SOC_DAILINK_REG(compress, dummy, platform),
},
/* Back End DAI links */
{
/* SSP2 - Codec */
.name = "SSP2-Codec",
.id = 1,
.cpu_dai_name = "ssp2-port",
.platform_name = "sst-mfld-platform",
.no_pcm = 1,
.codec_dai_name = NAU8824_CODEC_DAI,
.codec_name = "i2c-10508824:00",
.dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF
| SND_SOC_DAIFMT_CBS_CFS,
.init = cht_codec_init,
@@ -219,6 +227,7 @@ static struct snd_soc_dai_link cht_dailink[] = {
.dpcm_playback = 1,
.dpcm_capture = 1,
.ops = &cht_be_ssp2_ops,
SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
},
};

Some files were not shown because too many files have changed in this diff Show More