diff options
author | Dimitris Papastamos <dp@opensource.wolfsonmicro.com> | 2013-07-29 08:51:59 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-07-29 10:39:11 -0400 |
commit | 81ad93ecfda64cb37129d29adb384affd0d0fa5b (patch) | |
tree | 7c560ec6c39ca529f99320e6fab838f8edc8e06c | |
parent | 4fefd69853a4e83040ddaa98d3b6e5e12cc4f97a (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.c | 103 | ||||
-rw-r--r-- | sound/soc/codecs/wm_adsp.h | 2 |
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 | ||
228 | struct wm_coeff { | ||
229 | struct device *dev; | ||
230 | struct list_head ctl_list; | ||
231 | struct regmap *regmap; | ||
232 | }; | ||
233 | |||
234 | struct wm_coeff_ctl { | 228 | struct 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, | |||
378 | static int wm_coeff_write_control(struct snd_kcontrol *kcontrol, | 372 | static 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, | |||
434 | static int wm_coeff_read_control(struct snd_kcontrol *kcontrol, | 427 | static 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 | ||
484 | static 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 | |||
502 | struct wmfw_ctl_work { | 476 | struct 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 | ||
508 | static int wmfw_add_ctl(struct wm_coeff *wm_coeff, | 482 | static 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 | ||
538 | err_kcontrol: | 514 | err_kcontrol: |
@@ -753,13 +729,12 @@ out: | |||
753 | return ret; | 729 | return ret; |
754 | } | 730 | } |
755 | 731 | ||
756 | static int wm_coeff_init_control_caches(struct wm_coeff *wm_coeff) | 732 | static 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 | ||
775 | static int wm_coeff_sync_controls(struct wm_coeff *wm_coeff) | 750 | static 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 | |||
1723 | out_coeff: | ||
1724 | kfree(adsp->wm_coeff); | ||
1725 | return ret; | ||
1726 | } | 1685 | } |
1727 | EXPORT_SYMBOL_GPL(wm_adsp2_init); | 1686 | EXPORT_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) \ |