Commit 7196c64c authored by Sylwester Nawrocki's avatar Sylwester Nawrocki Committed by Mark Brown

ASoC: samsung: i2s: Restore support for the secondary PCM

This patch introduces again registration of additional platform device as
we still need it for registering the secondary dmaengine PCM component.

This patch in most part is a revert of changes done in commit
be2c92eb ("ASoC: samsung: i2s: Remove virtual device for secondary DAI")
Signed-off-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Acked-by: default avatarKrzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent b3d8f7ca
...@@ -109,6 +109,7 @@ static DEFINE_SPINLOCK(lock); ...@@ -109,6 +109,7 @@ static DEFINE_SPINLOCK(lock);
struct samsung_i2s_priv { struct samsung_i2s_priv {
struct platform_device *pdev; struct platform_device *pdev;
struct platform_device *pdev_sec;
/* Spinlock protecting access to the device's registers */ /* Spinlock protecting access to the device's registers */
spinlock_t spinlock; spinlock_t spinlock;
...@@ -1306,6 +1307,34 @@ static int i2s_register_clock_provider(struct platform_device *pdev) ...@@ -1306,6 +1307,34 @@ static int i2s_register_clock_provider(struct platform_device *pdev)
return ret; return ret;
} }
/* Create platform device for the secondary PCM */
static int i2s_create_secondary_device(struct samsung_i2s_priv *priv)
{
struct platform_device *pdev;
int ret;
pdev = platform_device_register_simple("samsung-i2s-sec", -1, NULL, 0);
if (!pdev)
return -ENOMEM;
ret = device_attach(&pdev->dev);
if (ret < 0) {
dev_info(&pdev->dev, "device_attach() failed\n");
return ret;
}
priv->pdev_sec = pdev;
return 0;
}
static void i2s_delete_secondary_device(struct samsung_i2s_priv *priv)
{
if (priv->pdev_sec) {
platform_device_del(priv->pdev_sec);
priv->pdev_sec = NULL;
}
}
static int samsung_i2s_probe(struct platform_device *pdev) static int samsung_i2s_probe(struct platform_device *pdev)
{ {
struct i2s_dai *pri_dai, *sec_dai = NULL; struct i2s_dai *pri_dai, *sec_dai = NULL;
...@@ -1323,13 +1352,15 @@ static int samsung_i2s_probe(struct platform_device *pdev) ...@@ -1323,13 +1352,15 @@ static int samsung_i2s_probe(struct platform_device *pdev)
i2s_dai_data = (struct samsung_i2s_dai_data *) i2s_dai_data = (struct samsung_i2s_dai_data *)
platform_get_device_id(pdev)->driver_data; platform_get_device_id(pdev)->driver_data;
/* Nothing to do if it is the secondary device probe */
if (!i2s_dai_data)
return 0;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
quirks = np ? i2s_dai_data->quirks : i2s_pdata->type.quirks; quirks = np ? i2s_dai_data->quirks : i2s_pdata->type.quirks;
quirks &= ~(QUIRK_SEC_DAI | QUIRK_SUPPORTS_IDMA);
num_dais = (quirks & QUIRK_SEC_DAI) ? 2 : 1; num_dais = (quirks & QUIRK_SEC_DAI) ? 2 : 1;
priv->pdev = pdev; priv->pdev = pdev;
...@@ -1419,8 +1450,13 @@ static int samsung_i2s_probe(struct platform_device *pdev) ...@@ -1419,8 +1450,13 @@ static int samsung_i2s_probe(struct platform_device *pdev)
sec_dai->pri_dai = pri_dai; sec_dai->pri_dai = pri_dai;
pri_dai->sec_dai = sec_dai; pri_dai->sec_dai = sec_dai;
ret = samsung_asoc_dma_platform_register(&pdev->dev, ret = i2s_create_secondary_device(priv);
sec_dai->filter, "tx-sec", NULL, NULL); if (ret < 0)
goto err_disable_clk;
ret = samsung_asoc_dma_platform_register(&priv->pdev_sec->dev,
sec_dai->filter, "tx-sec", NULL,
&pdev->dev);
if (ret < 0) if (ret < 0)
goto err_disable_clk; goto err_disable_clk;
...@@ -1455,6 +1491,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) ...@@ -1455,6 +1491,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
err_disable_clk: err_disable_clk:
clk_disable_unprepare(pri_dai->clk); clk_disable_unprepare(pri_dai->clk);
i2s_delete_secondary_device(priv);
return ret; return ret;
} }
...@@ -1463,12 +1500,17 @@ static int samsung_i2s_remove(struct platform_device *pdev) ...@@ -1463,12 +1500,17 @@ static int samsung_i2s_remove(struct platform_device *pdev)
struct samsung_i2s_priv *priv = dev_get_drvdata(&pdev->dev); struct samsung_i2s_priv *priv = dev_get_drvdata(&pdev->dev);
struct i2s_dai *pri_dai = samsung_i2s_get_pri_dai(&pdev->dev); struct i2s_dai *pri_dai = samsung_i2s_get_pri_dai(&pdev->dev);
/* The secondary device has no driver data assigned */
if (!priv)
return 0;
pm_runtime_get_sync(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
i2s_unregister_clock_provider(pdev); i2s_unregister_clock_provider(pdev);
clk_disable_unprepare(pri_dai->clk); clk_disable_unprepare(pri_dai->clk);
pm_runtime_put_noidle(&pdev->dev); pm_runtime_put_noidle(&pdev->dev);
i2s_delete_secondary_device(priv);
return 0; return 0;
} }
...@@ -1566,6 +1608,8 @@ static const struct platform_device_id samsung_i2s_driver_ids[] = { ...@@ -1566,6 +1608,8 @@ static const struct platform_device_id samsung_i2s_driver_ids[] = {
{ {
.name = "samsung-i2s", .name = "samsung-i2s",
.driver_data = (kernel_ulong_t)&i2sv3_dai_type, .driver_data = (kernel_ulong_t)&i2sv3_dai_type,
}, {
.name = "samsung-i2s-sec",
}, },
{}, {},
}; };
......
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