aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2016-12-29 06:34:03 -0500
committerMark Brown <broonie@kernel.org>2016-12-31 13:35:07 -0500
commitbe2c92eb64023e294d6bb9232578963670bb121b (patch)
treeb5a1b6bb1024b69c855a5f93760ea7d71c7a534b
parent409c69be433b819c924a8d1c457a835bc6d51700 (diff)
ASoC: samsung: i2s: Remove virtual device for secondary DAI
For some unknown (maybe historical?) reasons support for secondary I2S DAI was implemented by adding additional virtual platform device, which was then probed again with the main I2S driver. This pattern is really hard to follow and provides no benefits, so lets remove this hack and register both DAIs during linear probe of Exynos I2S controller driver. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/samsung/i2s.c102
1 files changed, 26 insertions, 76 deletions
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index d55326289a4a..10b19a4afe86 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -34,11 +34,6 @@
34 34
35#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) 35#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
36 36
37enum samsung_dai_type {
38 TYPE_PRI,
39 TYPE_SEC,
40};
41
42struct samsung_i2s_variant_regs { 37struct samsung_i2s_variant_regs {
43 unsigned int bfs_off; 38 unsigned int bfs_off;
44 unsigned int rfs_off; 39 unsigned int rfs_off;
@@ -54,7 +49,6 @@ struct samsung_i2s_variant_regs {
54}; 49};
55 50
56struct samsung_i2s_dai_data { 51struct samsung_i2s_dai_data {
57 int dai_type;
58 u32 quirks; 52 u32 quirks;
59 const struct samsung_i2s_variant_regs *i2s_variant_regs; 53 const struct samsung_i2s_variant_regs *i2s_variant_regs;
60}; 54};
@@ -1066,7 +1060,6 @@ static const struct snd_soc_component_driver samsung_i2s_component = {
1066static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) 1060static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
1067{ 1061{
1068 struct i2s_dai *i2s; 1062 struct i2s_dai *i2s;
1069 int ret;
1070 1063
1071 i2s = devm_kzalloc(&pdev->dev, sizeof(struct i2s_dai), GFP_KERNEL); 1064 i2s = devm_kzalloc(&pdev->dev, sizeof(struct i2s_dai), GFP_KERNEL);
1072 if (i2s == NULL) 1065 if (i2s == NULL)
@@ -1091,28 +1084,10 @@ static struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
1091 i2s->i2s_dai_drv.capture.channels_max = 2; 1084 i2s->i2s_dai_drv.capture.channels_max = 2;
1092 i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES; 1085 i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES;
1093 i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS; 1086 i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS;
1094 dev_set_drvdata(&i2s->pdev->dev, i2s);
1095 } else { /* Create a new platform_device for Secondary */
1096 i2s->pdev = platform_device_alloc("samsung-i2s-sec", -1);
1097 if (!i2s->pdev)
1098 return NULL;
1099
1100 i2s->pdev->dev.parent = &pdev->dev;
1101
1102 platform_set_drvdata(i2s->pdev, i2s);
1103 ret = platform_device_add(i2s->pdev);
1104 if (ret < 0)
1105 return NULL;
1106 } 1087 }
1107
1108 return i2s; 1088 return i2s;
1109} 1089}
1110 1090
1111static void i2s_free_sec_dai(struct i2s_dai *i2s)
1112{
1113 platform_device_del(i2s->pdev);
1114}
1115
1116#ifdef CONFIG_PM 1091#ifdef CONFIG_PM
1117static int i2s_runtime_suspend(struct device *dev) 1092static int i2s_runtime_suspend(struct device *dev)
1118{ 1093{
@@ -1230,22 +1205,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1230 i2s_dai_data = (struct samsung_i2s_dai_data *) 1205 i2s_dai_data = (struct samsung_i2s_dai_data *)
1231 platform_get_device_id(pdev)->driver_data; 1206 platform_get_device_id(pdev)->driver_data;
1232 1207
1233 /* Call during the secondary interface registration */
1234 if (i2s_dai_data->dai_type == TYPE_SEC) {
1235 sec_dai = dev_get_drvdata(&pdev->dev);
1236 if (!sec_dai) {
1237 dev_err(&pdev->dev, "Unable to get drvdata\n");
1238 return -EFAULT;
1239 }
1240 ret = samsung_asoc_dma_platform_register(&pdev->dev,
1241 sec_dai->filter, "tx-sec", NULL);
1242 if (ret != 0)
1243 return ret;
1244
1245 return devm_snd_soc_register_component(&sec_dai->pdev->dev,
1246 &samsung_i2s_component,
1247 &sec_dai->i2s_dai_drv, 1);
1248 }
1249 1208
1250 pri_dai = i2s_alloc_dai(pdev, false); 1209 pri_dai = i2s_alloc_dai(pdev, false);
1251 if (!pri_dai) { 1210 if (!pri_dai) {
@@ -1312,6 +1271,12 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1312 if (ret < 0) 1271 if (ret < 0)
1313 goto err_disable_clk; 1272 goto err_disable_clk;
1314 1273
1274 ret = devm_snd_soc_register_component(&pdev->dev,
1275 &samsung_i2s_component,
1276 &pri_dai->i2s_dai_drv, 1);
1277 if (ret < 0)
1278 goto err_disable_clk;
1279
1315 if (quirks & QUIRK_SEC_DAI) { 1280 if (quirks & QUIRK_SEC_DAI) {
1316 sec_dai = i2s_alloc_dai(pdev, true); 1281 sec_dai = i2s_alloc_dai(pdev, true);
1317 if (!sec_dai) { 1282 if (!sec_dai) {
@@ -1336,6 +1301,17 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1336 sec_dai->idma_playback.addr = idma_addr; 1301 sec_dai->idma_playback.addr = idma_addr;
1337 sec_dai->pri_dai = pri_dai; 1302 sec_dai->pri_dai = pri_dai;
1338 pri_dai->sec_dai = sec_dai; 1303 pri_dai->sec_dai = sec_dai;
1304
1305 ret = samsung_asoc_dma_platform_register(&pdev->dev,
1306 sec_dai->filter, "tx-sec", NULL);
1307 if (ret < 0)
1308 goto err_disable_clk;
1309
1310 ret = devm_snd_soc_register_component(&pdev->dev,
1311 &samsung_i2s_component,
1312 &sec_dai->i2s_dai_drv, 1);
1313 if (ret < 0)
1314 goto err_disable_clk;
1339 } 1315 }
1340 1316
1341 if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { 1317 if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
@@ -1344,11 +1320,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1344 goto err_disable_clk; 1320 goto err_disable_clk;
1345 } 1321 }
1346 1322
1347 ret = devm_snd_soc_register_component(&pri_dai->pdev->dev, 1323 dev_set_drvdata(&pdev->dev, pri_dai);
1348 &samsung_i2s_component,
1349 &pri_dai->i2s_dai_drv, 1);
1350 if (ret < 0)
1351 goto err_free_dai;
1352 1324
1353 1325
1354 pm_runtime_enable(&pdev->dev); 1326 pm_runtime_enable(&pdev->dev);
@@ -1358,9 +1330,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
1358 return 0; 1330 return 0;
1359 1331
1360 pm_runtime_disable(&pdev->dev); 1332 pm_runtime_disable(&pdev->dev);
1361err_free_dai:
1362 if (sec_dai)
1363 i2s_free_sec_dai(sec_dai);
1364err_disable_clk: 1333err_disable_clk:
1365 clk_disable_unprepare(pri_dai->clk); 1334 clk_disable_unprepare(pri_dai->clk);
1366 return ret; 1335 return ret;
@@ -1368,25 +1337,18 @@ err_disable_clk:
1368 1337
1369static int samsung_i2s_remove(struct platform_device *pdev) 1338static int samsung_i2s_remove(struct platform_device *pdev)
1370{ 1339{
1371 struct i2s_dai *i2s, *other; 1340 struct i2s_dai *pri_dai, *sec_dai;
1372 1341
1373 i2s = dev_get_drvdata(&pdev->dev); 1342 pri_dai = dev_get_drvdata(&pdev->dev);
1374 other = get_other_dai(i2s); 1343 sec_dai = pri_dai->sec_dai;
1375 1344
1376 if (other) { 1345 pri_dai->sec_dai = NULL;
1377 other->pri_dai = NULL; 1346 sec_dai->pri_dai = NULL;
1378 other->sec_dai = NULL;
1379 } else {
1380 pm_runtime_disable(&pdev->dev);
1381 }
1382 1347
1383 if (!is_secondary(i2s)) { 1348 pm_runtime_disable(&pdev->dev);
1384 i2s_unregister_clock_provider(pdev);
1385 clk_disable_unprepare(i2s->clk);
1386 }
1387 1349
1388 i2s->pri_dai = NULL; 1350 i2s_unregister_clock_provider(pdev);
1389 i2s->sec_dai = NULL; 1351 clk_disable_unprepare(pri_dai->clk);
1390 1352
1391 return 0; 1353 return 0;
1392} 1354}
@@ -1448,49 +1410,37 @@ static const struct samsung_i2s_variant_regs i2sv5_i2s1_regs = {
1448}; 1410};
1449 1411
1450static const struct samsung_i2s_dai_data i2sv3_dai_type = { 1412static const struct samsung_i2s_dai_data i2sv3_dai_type = {
1451 .dai_type = TYPE_PRI,
1452 .quirks = QUIRK_NO_MUXPSR, 1413 .quirks = QUIRK_NO_MUXPSR,
1453 .i2s_variant_regs = &i2sv3_regs, 1414 .i2s_variant_regs = &i2sv3_regs,
1454}; 1415};
1455 1416
1456static const struct samsung_i2s_dai_data i2sv5_dai_type = { 1417static const struct samsung_i2s_dai_data i2sv5_dai_type = {
1457 .dai_type = TYPE_PRI,
1458 .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | 1418 .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR |
1459 QUIRK_SUPPORTS_IDMA, 1419 QUIRK_SUPPORTS_IDMA,
1460 .i2s_variant_regs = &i2sv3_regs, 1420 .i2s_variant_regs = &i2sv3_regs,
1461}; 1421};
1462 1422
1463static const struct samsung_i2s_dai_data i2sv6_dai_type = { 1423static const struct samsung_i2s_dai_data i2sv6_dai_type = {
1464 .dai_type = TYPE_PRI,
1465 .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | 1424 .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR |
1466 QUIRK_SUPPORTS_TDM | QUIRK_SUPPORTS_IDMA, 1425 QUIRK_SUPPORTS_TDM | QUIRK_SUPPORTS_IDMA,
1467 .i2s_variant_regs = &i2sv6_regs, 1426 .i2s_variant_regs = &i2sv6_regs,
1468}; 1427};
1469 1428
1470static const struct samsung_i2s_dai_data i2sv7_dai_type = { 1429static const struct samsung_i2s_dai_data i2sv7_dai_type = {
1471 .dai_type = TYPE_PRI,
1472 .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR | 1430 .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR |
1473 QUIRK_SUPPORTS_TDM, 1431 QUIRK_SUPPORTS_TDM,
1474 .i2s_variant_regs = &i2sv7_regs, 1432 .i2s_variant_regs = &i2sv7_regs,
1475}; 1433};
1476 1434
1477static const struct samsung_i2s_dai_data i2sv5_dai_type_i2s1 = { 1435static const struct samsung_i2s_dai_data i2sv5_dai_type_i2s1 = {
1478 .dai_type = TYPE_PRI,
1479 .quirks = QUIRK_PRI_6CHAN | QUIRK_NEED_RSTCLR, 1436 .quirks = QUIRK_PRI_6CHAN | QUIRK_NEED_RSTCLR,
1480 .i2s_variant_regs = &i2sv5_i2s1_regs, 1437 .i2s_variant_regs = &i2sv5_i2s1_regs,
1481}; 1438};
1482 1439
1483static const struct samsung_i2s_dai_data samsung_dai_type_sec = {
1484 .dai_type = TYPE_SEC,
1485};
1486
1487static const struct platform_device_id samsung_i2s_driver_ids[] = { 1440static const struct platform_device_id samsung_i2s_driver_ids[] = {
1488 { 1441 {
1489 .name = "samsung-i2s", 1442 .name = "samsung-i2s",
1490 .driver_data = (kernel_ulong_t)&i2sv3_dai_type, 1443 .driver_data = (kernel_ulong_t)&i2sv3_dai_type,
1491 }, {
1492 .name = "samsung-i2s-sec",
1493 .driver_data = (kernel_ulong_t)&samsung_dai_type_sec,
1494 }, 1444 },
1495 {}, 1445 {},
1496}; 1446};