Commit ef71b330 authored by Mark Brown's avatar Mark Brown

ASoC: fsl: Support register and unregister rpmsg

Merge series from Chancel Liu <chancel.liu@nxp.com>:

	echo /lib/firmware/fw.elf > /sys/class/remoteproc/remoteproc0/firmware
(A)	echo start > /sys/class/remoteproc/remoteproc0/state
(B)	echo stop > /sys/class/remoteproc/remoteproc0/state

The rpmsg sound card is registered in (A) and unregistered in (B).
After "start", imx-audio-rpmsg registers devices for ASoC platform driver
and machine driver. Then sound card is registered. After "stop",
imx-audio-rpmsg unregisters devices for ASoC platform driver and machine
driver. Then sound card is unregistered.
parents 22247e40 c14445bd
......@@ -135,7 +135,6 @@ static struct snd_soc_dai_driver fsl_rpmsg_dai = {
static const struct snd_soc_component_driver fsl_component = {
.name = "fsl-rpmsg",
.legacy_dai_naming = 1,
};
static const struct fsl_rpmsg_soc_data imx7ulp_data = {
......@@ -190,19 +189,40 @@ MODULE_DEVICE_TABLE(of, fsl_rpmsg_ids);
static int fsl_rpmsg_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct snd_soc_dai_driver *dai_drv;
const char *dai_name;
struct fsl_rpmsg *rpmsg;
int ret;
dai_drv = devm_kzalloc(&pdev->dev, sizeof(struct snd_soc_dai_driver), GFP_KERNEL);
if (!dai_drv)
return -ENOMEM;
memcpy(dai_drv, &fsl_rpmsg_dai, sizeof(fsl_rpmsg_dai));
rpmsg = devm_kzalloc(&pdev->dev, sizeof(struct fsl_rpmsg), GFP_KERNEL);
if (!rpmsg)
return -ENOMEM;
rpmsg->soc_data = of_device_get_match_data(&pdev->dev);
fsl_rpmsg_dai.playback.rates = rpmsg->soc_data->rates;
fsl_rpmsg_dai.capture.rates = rpmsg->soc_data->rates;
fsl_rpmsg_dai.playback.formats = rpmsg->soc_data->formats;
fsl_rpmsg_dai.capture.formats = rpmsg->soc_data->formats;
if (rpmsg->soc_data) {
dai_drv->playback.rates = rpmsg->soc_data->rates;
dai_drv->capture.rates = rpmsg->soc_data->rates;
dai_drv->playback.formats = rpmsg->soc_data->formats;
dai_drv->capture.formats = rpmsg->soc_data->formats;
}
/* Use rpmsg channel name as cpu dai name */
ret = of_property_read_string(np, "fsl,rpmsg-channel-name", &dai_name);
if (ret) {
if (ret == -EINVAL) {
dai_name = "rpmsg-audio-channel";
} else {
dev_err(&pdev->dev, "Failed to get rpmsg channel name: %d!\n", ret);
return ret;
}
}
dai_drv->name = dai_name;
if (of_property_read_bool(np, "fsl,enable-lpa")) {
rpmsg->enable_lpa = 1;
......@@ -236,21 +256,10 @@ static int fsl_rpmsg_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
&fsl_rpmsg_dai, 1);
dai_drv, 1);
if (ret)
goto err_pm_disable;
rpmsg->card_pdev = platform_device_register_data(&pdev->dev,
"imx-audio-rpmsg",
PLATFORM_DEVID_AUTO,
NULL,
0);
if (IS_ERR(rpmsg->card_pdev)) {
dev_err(&pdev->dev, "failed to register rpmsg card\n");
ret = PTR_ERR(rpmsg->card_pdev);
goto err_pm_disable;
}
return 0;
err_pm_disable:
......
......@@ -12,6 +12,7 @@
*/
struct imx_audio_rpmsg {
struct platform_device *rpmsg_pdev;
struct platform_device *card_pdev;
};
static int imx_audio_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len,
......@@ -87,14 +88,24 @@ static int imx_audio_rpmsg_probe(struct rpmsg_device *rpdev)
/* Register platform driver for rpmsg routine */
data->rpmsg_pdev = platform_device_register_data(&rpdev->dev,
IMX_PCM_DRV_NAME,
PLATFORM_DEVID_AUTO,
rpdev->id.name,
PLATFORM_DEVID_NONE,
NULL, 0);
if (IS_ERR(data->rpmsg_pdev)) {
dev_err(&rpdev->dev, "failed to register rpmsg platform.\n");
ret = PTR_ERR(data->rpmsg_pdev);
}
data->card_pdev = platform_device_register_data(&rpdev->dev,
"imx-audio-rpmsg",
PLATFORM_DEVID_AUTO,
rpdev->id.name,
strlen(rpdev->id.name) + 1);
if (IS_ERR(data->card_pdev)) {
dev_err(&rpdev->dev, "failed to register rpmsg card.\n");
ret = PTR_ERR(data->card_pdev);
}
return ret;
}
......@@ -105,6 +116,9 @@ static void imx_audio_rpmsg_remove(struct rpmsg_device *rpdev)
if (data->rpmsg_pdev)
platform_device_unregister(data->rpmsg_pdev);
if (data->card_pdev)
platform_device_unregister(data->card_pdev);
dev_info(&rpdev->dev, "audio rpmsg driver is removed\n");
}
......@@ -113,6 +127,7 @@ static struct rpmsg_device_id imx_audio_rpmsg_id_table[] = {
{ .name = "rpmsg-micfil-channel" },
{ },
};
MODULE_DEVICE_TABLE(rpmsg, imx_audio_rpmsg_id_table);
static struct rpmsg_driver imx_audio_rpmsg_driver = {
.drv.name = "imx_audio_rpmsg",
......@@ -126,5 +141,5 @@ module_rpmsg_driver(imx_audio_rpmsg_driver);
MODULE_DESCRIPTION("Freescale SoC Audio RPMSG interface");
MODULE_AUTHOR("Shengjiu Wang <shengjiu.wang@nxp.com>");
MODULE_ALIAS("platform:imx_audio_rpmsg");
MODULE_ALIAS("rpmsg:imx_audio_rpmsg");
MODULE_LICENSE("GPL v2");
......@@ -732,9 +732,6 @@ static int imx_rpmsg_pcm_probe(struct platform_device *pdev)
goto fail;
}
/* platform component name is used by machine driver to link with */
component->name = info->rpdev->id.name;
#ifdef CONFIG_DEBUG_FS
component->debugfs_prefix = "rpmsg";
#endif
......@@ -822,9 +819,17 @@ static const struct dev_pm_ops imx_rpmsg_pcm_pm_ops = {
imx_rpmsg_pcm_resume)
};
static const struct platform_device_id imx_rpmsg_pcm_id_table[] = {
{ .name = "rpmsg-audio-channel" },
{ .name = "rpmsg-micfil-channel" },
{ },
};
MODULE_DEVICE_TABLE(platform, imx_rpmsg_pcm_id_table);
static struct platform_driver imx_pcm_rpmsg_driver = {
.probe = imx_rpmsg_pcm_probe,
.remove_new = imx_rpmsg_pcm_remove,
.id_table = imx_rpmsg_pcm_id_table,
.driver = {
.name = IMX_PCM_DRV_NAME,
.pm = &imx_rpmsg_pcm_pm_ops,
......
......@@ -108,10 +108,8 @@ static int imx_rpmsg_late_probe(struct snd_soc_card *card)
static int imx_rpmsg_probe(struct platform_device *pdev)
{
struct snd_soc_dai_link_component *dlc;
struct device *dev = pdev->dev.parent;
/* rpmsg_pdev is the platform device for the rpmsg node that probed us */
struct platform_device *rpmsg_pdev = to_platform_device(dev);
struct device_node *np = rpmsg_pdev->dev.of_node;
struct snd_soc_dai *cpu_dai;
struct device_node *np = NULL;
struct of_phandle_args args;
const char *platform_name;
struct imx_rpmsg *data;
......@@ -127,10 +125,6 @@ static int imx_rpmsg_probe(struct platform_device *pdev)
goto fail;
}
ret = of_reserved_mem_device_init_by_idx(&pdev->dev, np, 0);
if (ret)
dev_warn(&pdev->dev, "no reserved DMA memory\n");
data->dai.cpus = &dlc[0];
data->dai.num_cpus = 1;
data->dai.platforms = &dlc[1];
......@@ -152,6 +146,23 @@ static int imx_rpmsg_probe(struct platform_device *pdev)
*/
data->dai.ignore_pmdown_time = 1;
data->dai.cpus->dai_name = pdev->dev.platform_data;
cpu_dai = snd_soc_find_dai(data->dai.cpus);
if (!cpu_dai) {
ret = -EPROBE_DEFER;
goto fail;
}
np = cpu_dai->dev->of_node;
if (!np) {
dev_err(&pdev->dev, "failed to parse CPU DAI device node\n");
ret = -ENODEV;
goto fail;
}
ret = of_reserved_mem_device_init_by_idx(&pdev->dev, np, 0);
if (ret)
dev_warn(&pdev->dev, "no reserved DMA memory\n");
/* Optional codec node */
ret = of_parse_phandle_with_fixed_args(np, "audio-codec", 0, 0, &args);
if (ret) {
......@@ -170,7 +181,6 @@ static int imx_rpmsg_probe(struct platform_device *pdev)
data->sysclk = clk_get_rate(clk);
}
data->dai.cpus->dai_name = dev_name(&rpmsg_pdev->dev);
if (!of_property_read_string(np, "fsl,rpmsg-channel-name", &platform_name))
data->dai.platforms->name = platform_name;
else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment