aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitris Papastamos <dp@opensource.wolfsonmicro.com>2013-07-29 08:51:59 -0400
committerMark Brown <broonie@linaro.org>2013-07-29 10:39:11 -0400
commit81ad93ecfda64cb37129d29adb384affd0d0fa5b (patch)
tree7c560ec6c39ca529f99320e6fab838f8edc8e06c
parent4fefd69853a4e83040ddaa98d3b6e5e12cc4f97a (diff)
ASoC: wm_adsp: Simplify kcontrol handling
Get rid off the wm_coeff struct and the wm_coeff_add_kcontrol() function. We are now using the snd_soc_card_kcontrol() function to get the kcontrol pointers. No need to call into ALSA code to register the kcontrols. Signed-off-by: Dimitris Papastamos <dp@opensource.wolfsonmicro.com> Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--sound/soc/codecs/wm_adsp.c103
-rw-r--r--sound/soc/codecs/wm_adsp.h2
2 files changed, 32 insertions, 73 deletions
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 05252ac936a3..3168224bc104 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -225,15 +225,9 @@ struct wm_coeff_ctl_ops {
225 struct snd_ctl_elem_info *uinfo); 225 struct snd_ctl_elem_info *uinfo);
226}; 226};
227 227
228struct wm_coeff {
229 struct device *dev;
230 struct list_head ctl_list;
231 struct regmap *regmap;
232};
233
234struct wm_coeff_ctl { 228struct wm_coeff_ctl {
235 const char *name; 229 const char *name;
236 struct snd_card *card; 230 struct snd_soc_card *card;
237 struct wm_adsp_alg_region region; 231 struct wm_adsp_alg_region region;
238 struct wm_coeff_ctl_ops ops; 232 struct wm_coeff_ctl_ops ops;
239 struct wm_adsp *adsp; 233 struct wm_adsp *adsp;
@@ -378,7 +372,6 @@ static int wm_coeff_info(struct snd_kcontrol *kcontrol,
378static int wm_coeff_write_control(struct snd_kcontrol *kcontrol, 372static int wm_coeff_write_control(struct snd_kcontrol *kcontrol,
379 const void *buf, size_t len) 373 const void *buf, size_t len)
380{ 374{
381 struct wm_coeff *wm_coeff= snd_kcontrol_chip(kcontrol);
382 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; 375 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
383 struct wm_adsp_alg_region *region = &ctl->region; 376 struct wm_adsp_alg_region *region = &ctl->region;
384 const struct wm_adsp_region *mem; 377 const struct wm_adsp_region *mem;
@@ -401,7 +394,7 @@ static int wm_coeff_write_control(struct snd_kcontrol *kcontrol,
401 if (!scratch) 394 if (!scratch)
402 return -ENOMEM; 395 return -ENOMEM;
403 396
404 ret = regmap_raw_write(wm_coeff->regmap, reg, scratch, 397 ret = regmap_raw_write(adsp->regmap, reg, scratch,
405 ctl->len); 398 ctl->len);
406 if (ret) { 399 if (ret) {
407 adsp_err(adsp, "Failed to write %zu bytes to %x\n", 400 adsp_err(adsp, "Failed to write %zu bytes to %x\n",
@@ -434,7 +427,6 @@ static int wm_coeff_put(struct snd_kcontrol *kcontrol,
434static int wm_coeff_read_control(struct snd_kcontrol *kcontrol, 427static int wm_coeff_read_control(struct snd_kcontrol *kcontrol,
435 void *buf, size_t len) 428 void *buf, size_t len)
436{ 429{
437 struct wm_coeff *wm_coeff= snd_kcontrol_chip(kcontrol);
438 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; 430 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
439 struct wm_adsp_alg_region *region = &ctl->region; 431 struct wm_adsp_alg_region *region = &ctl->region;
440 const struct wm_adsp_region *mem; 432 const struct wm_adsp_region *mem;
@@ -457,7 +449,7 @@ static int wm_coeff_read_control(struct snd_kcontrol *kcontrol,
457 if (!scratch) 449 if (!scratch)
458 return -ENOMEM; 450 return -ENOMEM;
459 451
460 ret = regmap_raw_read(wm_coeff->regmap, reg, scratch, ctl->len); 452 ret = regmap_raw_read(adsp->regmap, reg, scratch, ctl->len);
461 if (ret) { 453 if (ret) {
462 adsp_err(adsp, "Failed to read %zu bytes from %x\n", 454 adsp_err(adsp, "Failed to read %zu bytes from %x\n",
463 ctl->len, reg); 455 ctl->len, reg);
@@ -481,37 +473,18 @@ static int wm_coeff_get(struct snd_kcontrol *kcontrol,
481 return 0; 473 return 0;
482} 474}
483 475
484static int wm_coeff_add_kcontrol(struct wm_coeff *wm_coeff,
485 struct wm_coeff_ctl *ctl,
486 const struct snd_kcontrol_new *kctl)
487{
488 int ret;
489 struct snd_kcontrol *kcontrol;
490
491 kcontrol = snd_ctl_new1(kctl, wm_coeff);
492 ret = snd_ctl_add(ctl->card, kcontrol);
493 if (ret < 0) {
494 dev_err(wm_coeff->dev, "Failed to add %s: %d\n",
495 kctl->name, ret);
496 return ret;
497 }
498 ctl->kcontrol = kcontrol;
499 return 0;
500}
501
502struct wmfw_ctl_work { 476struct wmfw_ctl_work {
503 struct wm_coeff *wm_coeff; 477 struct wm_adsp *adsp;
504 struct wm_coeff_ctl *ctl; 478 struct wm_coeff_ctl *ctl;
505 struct work_struct work; 479 struct work_struct work;
506}; 480};
507 481
508static int wmfw_add_ctl(struct wm_coeff *wm_coeff, 482static int wmfw_add_ctl(struct wm_adsp *adsp, struct wm_coeff_ctl *ctl)
509 struct wm_coeff_ctl *ctl)
510{ 483{
511 struct snd_kcontrol_new *kcontrol; 484 struct snd_kcontrol_new *kcontrol;
512 int ret; 485 int ret;
513 486
514 if (!wm_coeff || !ctl || !ctl->name || !ctl->card) 487 if (!ctl || !ctl->name || !ctl->card)
515 return -EINVAL; 488 return -EINVAL;
516 489
517 kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL); 490 kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL);
@@ -525,14 +498,17 @@ static int wmfw_add_ctl(struct wm_coeff *wm_coeff,
525 kcontrol->put = wm_coeff_put; 498 kcontrol->put = wm_coeff_put;
526 kcontrol->private_value = (unsigned long)ctl; 499 kcontrol->private_value = (unsigned long)ctl;
527 500
528 ret = wm_coeff_add_kcontrol(wm_coeff, 501 ret = snd_soc_add_card_controls(ctl->card,
529 ctl, kcontrol); 502 kcontrol, 1);
530 if (ret < 0) 503 if (ret < 0)
531 goto err_kcontrol; 504 goto err_kcontrol;
532 505
533 kfree(kcontrol); 506 kfree(kcontrol);
534 507
535 list_add(&ctl->list, &wm_coeff->ctl_list); 508 ctl->kcontrol = snd_soc_card_get_kcontrol(ctl->card,
509 ctl->name);
510
511 list_add(&ctl->list, &adsp->ctl_list);
536 return 0; 512 return 0;
537 513
538err_kcontrol: 514err_kcontrol:
@@ -753,13 +729,12 @@ out:
753 return ret; 729 return ret;
754} 730}
755 731
756static int wm_coeff_init_control_caches(struct wm_coeff *wm_coeff) 732static int wm_coeff_init_control_caches(struct wm_adsp *adsp)
757{ 733{
758 struct wm_coeff_ctl *ctl; 734 struct wm_coeff_ctl *ctl;
759 int ret; 735 int ret;
760 736
761 list_for_each_entry(ctl, &wm_coeff->ctl_list, 737 list_for_each_entry(ctl, &adsp->ctl_list, list) {
762 list) {
763 if (!ctl->enabled || ctl->set) 738 if (!ctl->enabled || ctl->set)
764 continue; 739 continue;
765 ret = wm_coeff_read_control(ctl->kcontrol, 740 ret = wm_coeff_read_control(ctl->kcontrol,
@@ -772,13 +747,12 @@ static int wm_coeff_init_control_caches(struct wm_coeff *wm_coeff)
772 return 0; 747 return 0;
773} 748}
774 749
775static int wm_coeff_sync_controls(struct wm_coeff *wm_coeff) 750static int wm_coeff_sync_controls(struct wm_adsp *adsp)
776{ 751{
777 struct wm_coeff_ctl *ctl; 752 struct wm_coeff_ctl *ctl;
778 int ret; 753 int ret;
779 754
780 list_for_each_entry(ctl, &wm_coeff->ctl_list, 755 list_for_each_entry(ctl, &adsp->ctl_list, list) {
781 list) {
782 if (!ctl->enabled) 756 if (!ctl->enabled)
783 continue; 757 continue;
784 if (ctl->set) { 758 if (ctl->set) {
@@ -799,7 +773,7 @@ static void wm_adsp_ctl_work(struct work_struct *work)
799 struct wmfw_ctl_work, 773 struct wmfw_ctl_work,
800 work); 774 work);
801 775
802 wmfw_add_ctl(ctl_work->wm_coeff, ctl_work->ctl); 776 wmfw_add_ctl(ctl_work->adsp, ctl_work->ctl);
803 kfree(ctl_work); 777 kfree(ctl_work);
804} 778}
805 779
@@ -842,7 +816,7 @@ static int wm_adsp_create_control(struct snd_soc_codec *codec,
842 snprintf(name, PAGE_SIZE, "DSP%d %s %x", 816 snprintf(name, PAGE_SIZE, "DSP%d %s %x",
843 dsp->num, region_name, region->alg); 817 dsp->num, region_name, region->alg);
844 818
845 list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list, 819 list_for_each_entry(ctl, &dsp->ctl_list,
846 list) { 820 list) {
847 if (!strcmp(ctl->name, name)) { 821 if (!strcmp(ctl->name, name)) {
848 if (!ctl->enabled) 822 if (!ctl->enabled)
@@ -866,7 +840,7 @@ static int wm_adsp_create_control(struct snd_soc_codec *codec,
866 ctl->set = 0; 840 ctl->set = 0;
867 ctl->ops.xget = wm_coeff_get; 841 ctl->ops.xget = wm_coeff_get;
868 ctl->ops.xput = wm_coeff_put; 842 ctl->ops.xput = wm_coeff_put;
869 ctl->card = codec->card->snd_card; 843 ctl->card = codec->card;
870 ctl->adsp = dsp; 844 ctl->adsp = dsp;
871 845
872 ctl->len = region->len; 846 ctl->len = region->len;
@@ -882,7 +856,7 @@ static int wm_adsp_create_control(struct snd_soc_codec *codec,
882 goto err_ctl_cache; 856 goto err_ctl_cache;
883 } 857 }
884 858
885 ctl_work->wm_coeff = dsp->wm_coeff; 859 ctl_work->adsp = dsp;
886 ctl_work->ctl = ctl; 860 ctl_work->ctl = ctl;
887 INIT_WORK(&ctl_work->work, wm_adsp_ctl_work); 861 INIT_WORK(&ctl_work->work, wm_adsp_ctl_work);
888 schedule_work(&ctl_work->work); 862 schedule_work(&ctl_work->work);
@@ -1434,12 +1408,12 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1434 goto err; 1408 goto err;
1435 1409
1436 /* Initialize caches for enabled and unset controls */ 1410 /* Initialize caches for enabled and unset controls */
1437 ret = wm_coeff_init_control_caches(dsp->wm_coeff); 1411 ret = wm_coeff_init_control_caches(dsp);
1438 if (ret != 0) 1412 if (ret != 0)
1439 goto err; 1413 goto err;
1440 1414
1441 /* Sync set controls */ 1415 /* Sync set controls */
1442 ret = wm_coeff_sync_controls(dsp->wm_coeff); 1416 ret = wm_coeff_sync_controls(dsp);
1443 if (ret != 0) 1417 if (ret != 0)
1444 goto err; 1418 goto err;
1445 1419
@@ -1460,10 +1434,8 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1460 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 1434 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
1461 ADSP1_SYS_ENA, 0); 1435 ADSP1_SYS_ENA, 0);
1462 1436
1463 list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list, 1437 list_for_each_entry(ctl, &dsp->ctl_list, list)
1464 list) {
1465 ctl->enabled = 0; 1438 ctl->enabled = 0;
1466 }
1467 break; 1439 break;
1468 1440
1469 default: 1441 default:
@@ -1591,12 +1563,12 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1591 goto err; 1563 goto err;
1592 1564
1593 /* Initialize caches for enabled and unset controls */ 1565 /* Initialize caches for enabled and unset controls */
1594 ret = wm_coeff_init_control_caches(dsp->wm_coeff); 1566 ret = wm_coeff_init_control_caches(dsp);
1595 if (ret != 0) 1567 if (ret != 0)
1596 goto err; 1568 goto err;
1597 1569
1598 /* Sync set controls */ 1570 /* Sync set controls */
1599 ret = wm_coeff_sync_controls(dsp->wm_coeff); 1571 ret = wm_coeff_sync_controls(dsp);
1600 if (ret != 0) 1572 if (ret != 0)
1601 goto err; 1573 goto err;
1602 1574
@@ -1637,10 +1609,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1637 ret); 1609 ret);
1638 } 1610 }
1639 1611
1640 list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list, 1612 list_for_each_entry(ctl, &dsp->ctl_list, list)
1641 list) {
1642 ctl->enabled = 0; 1613 ctl->enabled = 0;
1643 }
1644 1614
1645 while (!list_empty(&dsp->alg_regions)) { 1615 while (!list_empty(&dsp->alg_regions)) {
1646 alg_region = list_first_entry(&dsp->alg_regions, 1616 alg_region = list_first_entry(&dsp->alg_regions,
@@ -1679,49 +1649,38 @@ int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs)
1679 } 1649 }
1680 1650
1681 INIT_LIST_HEAD(&adsp->alg_regions); 1651 INIT_LIST_HEAD(&adsp->alg_regions);
1682 1652 INIT_LIST_HEAD(&adsp->ctl_list);
1683 adsp->wm_coeff = kzalloc(sizeof(*adsp->wm_coeff),
1684 GFP_KERNEL);
1685 if (!adsp->wm_coeff)
1686 return -ENOMEM;
1687 adsp->wm_coeff->regmap = adsp->regmap;
1688 adsp->wm_coeff->dev = adsp->dev;
1689 INIT_LIST_HEAD(&adsp->wm_coeff->ctl_list);
1690 1653
1691 if (dvfs) { 1654 if (dvfs) {
1692 adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD"); 1655 adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD");
1693 if (IS_ERR(adsp->dvfs)) { 1656 if (IS_ERR(adsp->dvfs)) {
1694 ret = PTR_ERR(adsp->dvfs); 1657 ret = PTR_ERR(adsp->dvfs);
1695 dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret); 1658 dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret);
1696 goto out_coeff; 1659 return ret;
1697 } 1660 }
1698 1661
1699 ret = regulator_enable(adsp->dvfs); 1662 ret = regulator_enable(adsp->dvfs);
1700 if (ret != 0) { 1663 if (ret != 0) {
1701 dev_err(adsp->dev, "Failed to enable DCVDD: %d\n", 1664 dev_err(adsp->dev, "Failed to enable DCVDD: %d\n",
1702 ret); 1665 ret);
1703 goto out_coeff; 1666 return ret;
1704 } 1667 }
1705 1668
1706 ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000); 1669 ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000);
1707 if (ret != 0) { 1670 if (ret != 0) {
1708 dev_err(adsp->dev, "Failed to initialise DVFS: %d\n", 1671 dev_err(adsp->dev, "Failed to initialise DVFS: %d\n",
1709 ret); 1672 ret);
1710 goto out_coeff; 1673 return ret;
1711 } 1674 }
1712 1675
1713 ret = regulator_disable(adsp->dvfs); 1676 ret = regulator_disable(adsp->dvfs);
1714 if (ret != 0) { 1677 if (ret != 0) {
1715 dev_err(adsp->dev, "Failed to disable DCVDD: %d\n", 1678 dev_err(adsp->dev, "Failed to disable DCVDD: %d\n",
1716 ret); 1679 ret);
1717 goto out_coeff; 1680 return ret;
1718 } 1681 }
1719 } 1682 }
1720 1683
1721 return 0; 1684 return 0;
1722
1723out_coeff:
1724 kfree(adsp->wm_coeff);
1725 return ret;
1726} 1685}
1727EXPORT_SYMBOL_GPL(wm_adsp2_init); 1686EXPORT_SYMBOL_GPL(wm_adsp2_init);
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index 9f922c82536c..64087fb1cdec 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -57,7 +57,7 @@ struct wm_adsp {
57 57
58 struct regulator *dvfs; 58 struct regulator *dvfs;
59 59
60 struct wm_coeff *wm_coeff; 60 struct list_head ctl_list;
61}; 61};
62 62
63#define WM_ADSP1(wname, num) \ 63#define WM_ADSP1(wname, num) \