1
0
Fork 0

Merge remote-tracking branches 'asoc/topic/samsung', 'asoc/topic/si476x', 'asoc/topic/simple', 'asoc/topic/spdif' and 'asoc/topic/stm32' into asoc-next

hifive-unleashed-5.1
Mark Brown 2018-01-05 12:44:03 +00:00
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
7 changed files with 65 additions and 125 deletions

View File

@ -140,6 +140,7 @@ sound {
simple-audio-card,name = "Cubox Audio"; simple-audio-card,name = "Cubox Audio";
simple-audio-card,dai-link@0 { /* I2S - HDMI */ simple-audio-card,dai-link@0 { /* I2S - HDMI */
reg = <0>;
format = "i2s"; format = "i2s";
cpu { cpu {
sound-dai = <&audio1 0>; sound-dai = <&audio1 0>;
@ -150,6 +151,7 @@ sound {
}; };
simple-audio-card,dai-link@1 { /* S/PDIF - HDMI */ simple-audio-card,dai-link@1 { /* S/PDIF - HDMI */
reg = <1>;
cpu { cpu {
sound-dai = <&audio1 1>; sound-dai = <&audio1 1>;
}; };
@ -159,6 +161,7 @@ sound {
}; };
simple-audio-card,dai-link@2 { /* S/PDIF - S/PDIF */ simple-audio-card,dai-link@2 { /* S/PDIF - S/PDIF */
reg = <2>;
cpu { cpu {
sound-dai = <&audio1 1>; sound-dai = <&audio1 1>;
}; };

View File

@ -20,11 +20,6 @@ Required properties:
Optional properties: Optional properties:
- resets: Reference to a reset controller asserting the SAI - resets: Reference to a reset controller asserting the SAI
- st,sync: specify synchronization mode.
By default SAI sub-block is in asynchronous mode.
This property sets SAI sub-block as slave of another SAI sub-block.
Must contain the phandle and index of the sai sub-block providing
the synchronization.
SAI subnodes: SAI subnodes:
Two subnodes corresponding to SAI sub-block instances A et B can be defined. Two subnodes corresponding to SAI sub-block instances A et B can be defined.
@ -44,6 +39,13 @@ SAI subnodes required properties:
- pinctrl-names: should contain only value "default" - pinctrl-names: should contain only value "default"
- pinctrl-0: see Documentation/devicetree/bindings/pinctrl/pinctrl-stm32.txt - pinctrl-0: see Documentation/devicetree/bindings/pinctrl/pinctrl-stm32.txt
SAI subnodes Optional properties:
- st,sync: specify synchronization mode.
By default SAI sub-block is in asynchronous mode.
This property sets SAI sub-block as slave of another SAI sub-block.
Must contain the phandle and index of the sai sub-block providing
the synchronization.
The device node should contain one 'port' child node with one child 'endpoint' The device node should contain one 'port' child node with one child 'endpoint'
node, according to the bindings defined in Documentation/devicetree/bindings/ node, according to the bindings defined in Documentation/devicetree/bindings/
graph.txt. graph.txt.

View File

@ -231,14 +231,17 @@ static struct snd_soc_dai_driver si476x_dai = {
.ops = &si476x_dai_ops, .ops = &si476x_dai_ops,
}; };
static struct regmap *si476x_get_regmap(struct device *dev) static int si476x_probe(struct snd_soc_component *component)
{ {
return dev_get_regmap(dev->parent, NULL); snd_soc_component_init_regmap(component,
dev_get_regmap(component->dev->parent, NULL));
return 0;
} }
static const struct snd_soc_codec_driver soc_codec_dev_si476x = { static const struct snd_soc_codec_driver soc_codec_dev_si476x = {
.get_regmap = si476x_get_regmap,
.component_driver = { .component_driver = {
.probe = si476x_probe,
.dapm_widgets = si476x_dapm_widgets, .dapm_widgets = si476x_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(si476x_dapm_widgets), .num_dapm_widgets = ARRAY_SIZE(si476x_dapm_widgets),
.dapm_routes = si476x_dapm_routes, .dapm_routes = si476x_dapm_routes,

View File

@ -34,10 +34,11 @@ static const struct snd_soc_dapm_route dir_routes[] = {
#define STUB_RATES SNDRV_PCM_RATE_8000_192000 #define STUB_RATES SNDRV_PCM_RATE_8000_192000
#define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ #define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S32_LE | \
SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)
static const struct snd_soc_codec_driver soc_codec_spdif_dir = { static struct snd_soc_codec_driver soc_codec_spdif_dir = {
.component_driver = { .component_driver = {
.dapm_widgets = dir_widgets, .dapm_widgets = dir_widgets,
.num_dapm_widgets = ARRAY_SIZE(dir_widgets), .num_dapm_widgets = ARRAY_SIZE(dir_widgets),

View File

@ -27,7 +27,8 @@
#define STUB_RATES SNDRV_PCM_RATE_8000_192000 #define STUB_RATES SNDRV_PCM_RATE_8000_192000
#define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ #define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S24_LE) SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S32_LE)
static const struct snd_soc_dapm_widget dit_widgets[] = { static const struct snd_soc_dapm_widget dit_widgets[] = {
SND_SOC_DAPM_OUTPUT("spdif-out"), SND_SOC_DAPM_OUTPUT("spdif-out"),
@ -37,7 +38,7 @@ static const struct snd_soc_dapm_route dit_routes[] = {
{ "spdif-out", NULL, "Playback" }, { "spdif-out", NULL, "Playback" },
}; };
static const struct snd_soc_codec_driver soc_codec_spdif_dit = { static struct snd_soc_codec_driver soc_codec_spdif_dit = {
.component_driver = { .component_driver = {
.dapm_widgets = dit_widgets, .dapm_widgets = dit_widgets,
.num_dapm_widgets = ARRAY_SIZE(dit_widgets), .num_dapm_widgets = ARRAY_SIZE(dit_widgets),

View File

@ -60,13 +60,13 @@ static int bells_set_bias_level(struct snd_soc_card *card,
{ {
struct snd_soc_pcm_runtime *rtd; struct snd_soc_pcm_runtime *rtd;
struct snd_soc_dai *codec_dai; struct snd_soc_dai *codec_dai;
struct snd_soc_codec *codec; struct snd_soc_component *component;
struct bells_drvdata *bells = card->drvdata; struct bells_drvdata *bells = card->drvdata;
int ret; int ret;
rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name); rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name);
codec_dai = rtd->codec_dai; codec_dai = rtd->codec_dai;
codec = codec_dai->codec; component = codec_dai->component;
if (dapm->dev != codec_dai->dev) if (dapm->dev != codec_dai->dev)
return 0; return 0;
@ -76,7 +76,7 @@ static int bells_set_bias_level(struct snd_soc_card *card,
if (dapm->bias_level != SND_SOC_BIAS_STANDBY) if (dapm->bias_level != SND_SOC_BIAS_STANDBY)
break; break;
ret = snd_soc_codec_set_pll(codec, WM5102_FLL1, ret = snd_soc_component_set_pll(component, WM5102_FLL1,
ARIZONA_FLL_SRC_MCLK1, ARIZONA_FLL_SRC_MCLK1,
MCLK_RATE, MCLK_RATE,
bells->sysclk_rate); bells->sysclk_rate);
@ -84,7 +84,7 @@ static int bells_set_bias_level(struct snd_soc_card *card,
pr_err("Failed to start FLL: %d\n", ret); pr_err("Failed to start FLL: %d\n", ret);
if (bells->asyncclk_rate) { if (bells->asyncclk_rate) {
ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, ret = snd_soc_component_set_pll(component, WM5102_FLL2,
ARIZONA_FLL_SRC_AIF2BCLK, ARIZONA_FLL_SRC_AIF2BCLK,
BCLK2_RATE, BCLK2_RATE,
bells->asyncclk_rate); bells->asyncclk_rate);
@ -106,27 +106,27 @@ static int bells_set_bias_level_post(struct snd_soc_card *card,
{ {
struct snd_soc_pcm_runtime *rtd; struct snd_soc_pcm_runtime *rtd;
struct snd_soc_dai *codec_dai; struct snd_soc_dai *codec_dai;
struct snd_soc_codec *codec; struct snd_soc_component *component;
struct bells_drvdata *bells = card->drvdata; struct bells_drvdata *bells = card->drvdata;
int ret; int ret;
rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name); rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name);
codec_dai = rtd->codec_dai; codec_dai = rtd->codec_dai;
codec = codec_dai->codec; component = codec_dai->component;
if (dapm->dev != codec_dai->dev) if (dapm->dev != codec_dai->dev)
return 0; return 0;
switch (level) { switch (level) {
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_STANDBY:
ret = snd_soc_codec_set_pll(codec, WM5102_FLL1, 0, 0, 0); ret = snd_soc_component_set_pll(component, WM5102_FLL1, 0, 0, 0);
if (ret < 0) { if (ret < 0) {
pr_err("Failed to stop FLL: %d\n", ret); pr_err("Failed to stop FLL: %d\n", ret);
return ret; return ret;
} }
if (bells->asyncclk_rate) { if (bells->asyncclk_rate) {
ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, ret = snd_soc_component_set_pll(component, WM5102_FLL2,
0, 0, 0); 0, 0, 0);
if (ret < 0) { if (ret < 0) {
pr_err("Failed to stop FLL: %d\n", ret); pr_err("Failed to stop FLL: %d\n", ret);
@ -148,8 +148,8 @@ static int bells_late_probe(struct snd_soc_card *card)
{ {
struct bells_drvdata *bells = card->drvdata; struct bells_drvdata *bells = card->drvdata;
struct snd_soc_pcm_runtime *rtd; struct snd_soc_pcm_runtime *rtd;
struct snd_soc_codec *wm0010; struct snd_soc_component *wm0010;
struct snd_soc_codec *codec; struct snd_soc_component *component;
struct snd_soc_dai *aif1_dai; struct snd_soc_dai *aif1_dai;
struct snd_soc_dai *aif2_dai; struct snd_soc_dai *aif2_dai;
struct snd_soc_dai *aif3_dai; struct snd_soc_dai *aif3_dai;
@ -157,22 +157,22 @@ static int bells_late_probe(struct snd_soc_card *card)
int ret; int ret;
rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_AP_DSP].name); rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_AP_DSP].name);
wm0010 = rtd->codec; wm0010 = rtd->codec_dai->component;
rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name); rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name);
codec = rtd->codec; component = rtd->codec_dai->component;
aif1_dai = rtd->codec_dai; aif1_dai = rtd->codec_dai;
ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK, ret = snd_soc_component_set_sysclk(component, ARIZONA_CLK_SYSCLK,
ARIZONA_CLK_SRC_FLL1, ARIZONA_CLK_SRC_FLL1,
bells->sysclk_rate, bells->sysclk_rate,
SND_SOC_CLOCK_IN); SND_SOC_CLOCK_IN);
if (ret != 0) { if (ret != 0) {
dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret); dev_err(component->dev, "Failed to set SYSCLK: %d\n", ret);
return ret; return ret;
} }
ret = snd_soc_codec_set_sysclk(wm0010, 0, 0, SYS_MCLK_RATE, 0); ret = snd_soc_component_set_sysclk(wm0010, 0, 0, SYS_MCLK_RATE, 0);
if (ret != 0) { if (ret != 0) {
dev_err(wm0010->dev, "Failed to set WM0010 clock: %d\n", ret); dev_err(wm0010->dev, "Failed to set WM0010 clock: %d\n", ret);
return ret; return ret;
@ -182,20 +182,20 @@ static int bells_late_probe(struct snd_soc_card *card)
if (ret != 0) if (ret != 0)
dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret); dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret);
ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_OPCLK, 0, ret = snd_soc_component_set_sysclk(component, ARIZONA_CLK_OPCLK, 0,
SYS_MCLK_RATE, SND_SOC_CLOCK_OUT); SYS_MCLK_RATE, SND_SOC_CLOCK_OUT);
if (ret != 0) if (ret != 0)
dev_err(codec->dev, "Failed to set OPCLK: %d\n", ret); dev_err(component->dev, "Failed to set OPCLK: %d\n", ret);
if (card->num_rtd == DAI_CODEC_CP) if (card->num_rtd == DAI_CODEC_CP)
return 0; return 0;
ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_ASYNCCLK, ret = snd_soc_component_set_sysclk(component, ARIZONA_CLK_ASYNCCLK,
ARIZONA_CLK_SRC_FLL2, ARIZONA_CLK_SRC_FLL2,
bells->asyncclk_rate, bells->asyncclk_rate,
SND_SOC_CLOCK_IN); SND_SOC_CLOCK_IN);
if (ret != 0) { if (ret != 0) {
dev_err(codec->dev, "Failed to set ASYNCCLK: %d\n", ret); dev_err(component->dev, "Failed to set ASYNCCLK: %d\n", ret);
return ret; return ret;
} }
@ -221,7 +221,7 @@ static int bells_late_probe(struct snd_soc_card *card)
return ret; return ret;
} }
ret = snd_soc_codec_set_sysclk(wm9081_dai->codec, WM9081_SYSCLK_MCLK, ret = snd_soc_component_set_sysclk(wm9081_dai->component, WM9081_SYSCLK_MCLK,
0, SYS_MCLK_RATE, 0); 0, SYS_MCLK_RATE, 0);
if (ret != 0) { if (ret != 0) {
dev_err(wm9081_dai->dev, "Failed to set MCLK: %d\n", ret); dev_err(wm9081_dai->dev, "Failed to set MCLK: %d\n", ret);

View File

@ -28,16 +28,6 @@
#include "stm32_sai.h" #include "stm32_sai.h"
static LIST_HEAD(sync_providers);
static DEFINE_MUTEX(sync_mutex);
struct sync_provider {
struct list_head link;
struct device_node *node;
int (*sync_conf)(void *data, int synco);
void *data;
};
static const struct stm32_sai_conf stm32_sai_conf_f4 = { static const struct stm32_sai_conf stm32_sai_conf_f4 = {
.version = SAI_STM32F4, .version = SAI_STM32F4,
}; };
@ -70,9 +60,8 @@ static int stm32_sai_sync_conf_client(struct stm32_sai_data *sai, int synci)
return 0; return 0;
} }
static int stm32_sai_sync_conf_provider(void *data, int synco) static int stm32_sai_sync_conf_provider(struct stm32_sai_data *sai, int synco)
{ {
struct stm32_sai_data *sai = (struct stm32_sai_data *)data;
u32 prev_synco; u32 prev_synco;
int ret; int ret;
@ -103,83 +92,42 @@ static int stm32_sai_sync_conf_provider(void *data, int synco)
return 0; return 0;
} }
static int stm32_sai_set_sync_provider(struct device_node *np, int synco) static int stm32_sai_set_sync(struct stm32_sai_data *sai_client,
{
struct sync_provider *provider;
int ret;
mutex_lock(&sync_mutex);
list_for_each_entry(provider, &sync_providers, link) {
if (provider->node == np) {
ret = provider->sync_conf(provider->data, synco);
mutex_unlock(&sync_mutex);
return ret;
}
}
mutex_unlock(&sync_mutex);
/* SAI sync provider not found */
return -ENODEV;
}
static int stm32_sai_set_sync(struct stm32_sai_data *sai,
struct device_node *np_provider, struct device_node *np_provider,
int synco, int synci) int synco, int synci)
{ {
struct platform_device *pdev = of_find_device_by_node(np_provider);
struct stm32_sai_data *sai_provider;
int ret; int ret;
if (!pdev) {
dev_err(&sai_client->pdev->dev,
"Device not found for node %s\n", np_provider->name);
return -ENODEV;
}
sai_provider = platform_get_drvdata(pdev);
if (!sai_provider) {
dev_err(&sai_client->pdev->dev,
"SAI sync provider data not found\n");
return -EINVAL;
}
/* Configure sync client */ /* Configure sync client */
stm32_sai_sync_conf_client(sai, synci); ret = stm32_sai_sync_conf_client(sai_client, synci);
if (ret < 0)
return ret;
/* Configure sync provider */ /* Configure sync provider */
ret = stm32_sai_set_sync_provider(np_provider, synco); return stm32_sai_sync_conf_provider(sai_provider, synco);
return ret;
}
static int stm32_sai_sync_add_provider(struct platform_device *pdev,
void *data)
{
struct sync_provider *sp;
sp = devm_kzalloc(&pdev->dev, sizeof(*sp), GFP_KERNEL);
if (!sp)
return -ENOMEM;
sp->node = of_node_get(pdev->dev.of_node);
sp->data = data;
sp->sync_conf = &stm32_sai_sync_conf_provider;
mutex_lock(&sync_mutex);
list_add(&sp->link, &sync_providers);
mutex_unlock(&sync_mutex);
return 0;
}
static void stm32_sai_sync_del_provider(struct device_node *np)
{
struct sync_provider *sp;
mutex_lock(&sync_mutex);
list_for_each_entry(sp, &sync_providers, link) {
if (sp->node == np) {
list_del(&sp->link);
of_node_put(sp->node);
break;
}
}
mutex_unlock(&sync_mutex);
} }
static int stm32_sai_probe(struct platform_device *pdev) static int stm32_sai_probe(struct platform_device *pdev)
{ {
struct device_node *np = pdev->dev.of_node;
struct stm32_sai_data *sai; struct stm32_sai_data *sai;
struct reset_control *rst; struct reset_control *rst;
struct resource *res; struct resource *res;
const struct of_device_id *of_id; const struct of_device_id *of_id;
int ret;
sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
if (!sai) if (!sai)
@ -231,28 +179,11 @@ static int stm32_sai_probe(struct platform_device *pdev)
reset_control_deassert(rst); reset_control_deassert(rst);
} }
ret = stm32_sai_sync_add_provider(pdev, sai);
if (ret < 0)
return ret;
sai->set_sync = &stm32_sai_set_sync;
sai->pdev = pdev; sai->pdev = pdev;
sai->set_sync = &stm32_sai_set_sync;
platform_set_drvdata(pdev, sai); platform_set_drvdata(pdev, sai);
ret = of_platform_populate(np, NULL, NULL, &pdev->dev); return devm_of_platform_populate(&pdev->dev);
if (ret < 0)
stm32_sai_sync_del_provider(np);
return ret;
}
static int stm32_sai_remove(struct platform_device *pdev)
{
of_platform_depopulate(&pdev->dev);
stm32_sai_sync_del_provider(pdev->dev.of_node);
return 0;
} }
MODULE_DEVICE_TABLE(of, stm32_sai_ids); MODULE_DEVICE_TABLE(of, stm32_sai_ids);
@ -263,7 +194,6 @@ static struct platform_driver stm32_sai_driver = {
.of_match_table = stm32_sai_ids, .of_match_table = stm32_sai_ids,
}, },
.probe = stm32_sai_probe, .probe = stm32_sai_probe,
.remove = stm32_sai_remove,
}; };
module_platform_driver(stm32_sai_driver); module_platform_driver(stm32_sai_driver);