aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm_adsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm_adsp.c')
-rw-r--r--sound/soc/codecs/wm_adsp.c124
1 files changed, 42 insertions, 82 deletions
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 05252ac936a3..b38f3506418f 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -225,15 +225,8 @@ 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;
237 struct wm_adsp_alg_region region; 230 struct wm_adsp_alg_region region;
238 struct wm_coeff_ctl_ops ops; 231 struct wm_coeff_ctl_ops ops;
239 struct wm_adsp *adsp; 232 struct wm_adsp *adsp;
@@ -378,7 +371,6 @@ static int wm_coeff_info(struct snd_kcontrol *kcontrol,
378static int wm_coeff_write_control(struct snd_kcontrol *kcontrol, 371static int wm_coeff_write_control(struct snd_kcontrol *kcontrol,
379 const void *buf, size_t len) 372 const void *buf, size_t len)
380{ 373{
381 struct wm_coeff *wm_coeff= snd_kcontrol_chip(kcontrol);
382 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; 374 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
383 struct wm_adsp_alg_region *region = &ctl->region; 375 struct wm_adsp_alg_region *region = &ctl->region;
384 const struct wm_adsp_region *mem; 376 const struct wm_adsp_region *mem;
@@ -401,7 +393,7 @@ static int wm_coeff_write_control(struct snd_kcontrol *kcontrol,
401 if (!scratch) 393 if (!scratch)
402 return -ENOMEM; 394 return -ENOMEM;
403 395
404 ret = regmap_raw_write(wm_coeff->regmap, reg, scratch, 396 ret = regmap_raw_write(adsp->regmap, reg, scratch,
405 ctl->len); 397 ctl->len);
406 if (ret) { 398 if (ret) {
407 adsp_err(adsp, "Failed to write %zu bytes to %x\n", 399 adsp_err(adsp, "Failed to write %zu bytes to %x\n",
@@ -434,7 +426,6 @@ static int wm_coeff_put(struct snd_kcontrol *kcontrol,
434static int wm_coeff_read_control(struct snd_kcontrol *kcontrol, 426static int wm_coeff_read_control(struct snd_kcontrol *kcontrol,
435 void *buf, size_t len) 427 void *buf, size_t len)
436{ 428{
437 struct wm_coeff *wm_coeff= snd_kcontrol_chip(kcontrol);
438 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; 429 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value;
439 struct wm_adsp_alg_region *region = &ctl->region; 430 struct wm_adsp_alg_region *region = &ctl->region;
440 const struct wm_adsp_region *mem; 431 const struct wm_adsp_region *mem;
@@ -457,7 +448,7 @@ static int wm_coeff_read_control(struct snd_kcontrol *kcontrol,
457 if (!scratch) 448 if (!scratch)
458 return -ENOMEM; 449 return -ENOMEM;
459 450
460 ret = regmap_raw_read(wm_coeff->regmap, reg, scratch, ctl->len); 451 ret = regmap_raw_read(adsp->regmap, reg, scratch, ctl->len);
461 if (ret) { 452 if (ret) {
462 adsp_err(adsp, "Failed to read %zu bytes from %x\n", 453 adsp_err(adsp, "Failed to read %zu bytes from %x\n",
463 ctl->len, reg); 454 ctl->len, reg);
@@ -481,37 +472,18 @@ static int wm_coeff_get(struct snd_kcontrol *kcontrol,
481 return 0; 472 return 0;
482} 473}
483 474
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 { 475struct wmfw_ctl_work {
503 struct wm_coeff *wm_coeff; 476 struct wm_adsp *adsp;
504 struct wm_coeff_ctl *ctl; 477 struct wm_coeff_ctl *ctl;
505 struct work_struct work; 478 struct work_struct work;
506}; 479};
507 480
508static int wmfw_add_ctl(struct wm_coeff *wm_coeff, 481static int wmfw_add_ctl(struct wm_adsp *adsp, struct wm_coeff_ctl *ctl)
509 struct wm_coeff_ctl *ctl)
510{ 482{
511 struct snd_kcontrol_new *kcontrol; 483 struct snd_kcontrol_new *kcontrol;
512 int ret; 484 int ret;
513 485
514 if (!wm_coeff || !ctl || !ctl->name || !ctl->card) 486 if (!ctl || !ctl->name)
515 return -EINVAL; 487 return -EINVAL;
516 488
517 kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL); 489 kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL);
@@ -525,14 +497,17 @@ static int wmfw_add_ctl(struct wm_coeff *wm_coeff,
525 kcontrol->put = wm_coeff_put; 497 kcontrol->put = wm_coeff_put;
526 kcontrol->private_value = (unsigned long)ctl; 498 kcontrol->private_value = (unsigned long)ctl;
527 499
528 ret = wm_coeff_add_kcontrol(wm_coeff, 500 ret = snd_soc_add_card_controls(adsp->card,
529 ctl, kcontrol); 501 kcontrol, 1);
530 if (ret < 0) 502 if (ret < 0)
531 goto err_kcontrol; 503 goto err_kcontrol;
532 504
533 kfree(kcontrol); 505 kfree(kcontrol);
534 506
535 list_add(&ctl->list, &wm_coeff->ctl_list); 507 ctl->kcontrol = snd_soc_card_get_kcontrol(adsp->card,
508 ctl->name);
509
510 list_add(&ctl->list, &adsp->ctl_list);
536 return 0; 511 return 0;
537 512
538err_kcontrol: 513err_kcontrol:
@@ -753,13 +728,12 @@ out:
753 return ret; 728 return ret;
754} 729}
755 730
756static int wm_coeff_init_control_caches(struct wm_coeff *wm_coeff) 731static int wm_coeff_init_control_caches(struct wm_adsp *adsp)
757{ 732{
758 struct wm_coeff_ctl *ctl; 733 struct wm_coeff_ctl *ctl;
759 int ret; 734 int ret;
760 735
761 list_for_each_entry(ctl, &wm_coeff->ctl_list, 736 list_for_each_entry(ctl, &adsp->ctl_list, list) {
762 list) {
763 if (!ctl->enabled || ctl->set) 737 if (!ctl->enabled || ctl->set)
764 continue; 738 continue;
765 ret = wm_coeff_read_control(ctl->kcontrol, 739 ret = wm_coeff_read_control(ctl->kcontrol,
@@ -772,13 +746,12 @@ static int wm_coeff_init_control_caches(struct wm_coeff *wm_coeff)
772 return 0; 746 return 0;
773} 747}
774 748
775static int wm_coeff_sync_controls(struct wm_coeff *wm_coeff) 749static int wm_coeff_sync_controls(struct wm_adsp *adsp)
776{ 750{
777 struct wm_coeff_ctl *ctl; 751 struct wm_coeff_ctl *ctl;
778 int ret; 752 int ret;
779 753
780 list_for_each_entry(ctl, &wm_coeff->ctl_list, 754 list_for_each_entry(ctl, &adsp->ctl_list, list) {
781 list) {
782 if (!ctl->enabled) 755 if (!ctl->enabled)
783 continue; 756 continue;
784 if (ctl->set) { 757 if (ctl->set) {
@@ -799,15 +772,14 @@ static void wm_adsp_ctl_work(struct work_struct *work)
799 struct wmfw_ctl_work, 772 struct wmfw_ctl_work,
800 work); 773 work);
801 774
802 wmfw_add_ctl(ctl_work->wm_coeff, ctl_work->ctl); 775 wmfw_add_ctl(ctl_work->adsp, ctl_work->ctl);
803 kfree(ctl_work); 776 kfree(ctl_work);
804} 777}
805 778
806static int wm_adsp_create_control(struct snd_soc_codec *codec, 779static int wm_adsp_create_control(struct wm_adsp *dsp,
807 const struct wm_adsp_alg_region *region) 780 const struct wm_adsp_alg_region *region)
808 781
809{ 782{
810 struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec);
811 struct wm_coeff_ctl *ctl; 783 struct wm_coeff_ctl *ctl;
812 struct wmfw_ctl_work *ctl_work; 784 struct wmfw_ctl_work *ctl_work;
813 char *name; 785 char *name;
@@ -842,7 +814,7 @@ static int wm_adsp_create_control(struct snd_soc_codec *codec,
842 snprintf(name, PAGE_SIZE, "DSP%d %s %x", 814 snprintf(name, PAGE_SIZE, "DSP%d %s %x",
843 dsp->num, region_name, region->alg); 815 dsp->num, region_name, region->alg);
844 816
845 list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list, 817 list_for_each_entry(ctl, &dsp->ctl_list,
846 list) { 818 list) {
847 if (!strcmp(ctl->name, name)) { 819 if (!strcmp(ctl->name, name)) {
848 if (!ctl->enabled) 820 if (!ctl->enabled)
@@ -866,7 +838,6 @@ static int wm_adsp_create_control(struct snd_soc_codec *codec,
866 ctl->set = 0; 838 ctl->set = 0;
867 ctl->ops.xget = wm_coeff_get; 839 ctl->ops.xget = wm_coeff_get;
868 ctl->ops.xput = wm_coeff_put; 840 ctl->ops.xput = wm_coeff_put;
869 ctl->card = codec->card->snd_card;
870 ctl->adsp = dsp; 841 ctl->adsp = dsp;
871 842
872 ctl->len = region->len; 843 ctl->len = region->len;
@@ -882,7 +853,7 @@ static int wm_adsp_create_control(struct snd_soc_codec *codec,
882 goto err_ctl_cache; 853 goto err_ctl_cache;
883 } 854 }
884 855
885 ctl_work->wm_coeff = dsp->wm_coeff; 856 ctl_work->adsp = dsp;
886 ctl_work->ctl = ctl; 857 ctl_work->ctl = ctl;
887 INIT_WORK(&ctl_work->work, wm_adsp_ctl_work); 858 INIT_WORK(&ctl_work->work, wm_adsp_ctl_work);
888 schedule_work(&ctl_work->work); 859 schedule_work(&ctl_work->work);
@@ -903,7 +874,7 @@ err_name:
903 return ret; 874 return ret;
904} 875}
905 876
906static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec) 877static int wm_adsp_setup_algs(struct wm_adsp *dsp)
907{ 878{
908 struct regmap *regmap = dsp->regmap; 879 struct regmap *regmap = dsp->regmap;
909 struct wmfw_adsp1_id_hdr adsp1_id; 880 struct wmfw_adsp1_id_hdr adsp1_id;
@@ -1091,7 +1062,7 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec)
1091 if (i + 1 < algs) { 1062 if (i + 1 < algs) {
1092 region->len = be32_to_cpu(adsp1_alg[i + 1].dm); 1063 region->len = be32_to_cpu(adsp1_alg[i + 1].dm);
1093 region->len -= be32_to_cpu(adsp1_alg[i].dm); 1064 region->len -= be32_to_cpu(adsp1_alg[i].dm);
1094 wm_adsp_create_control(codec, region); 1065 wm_adsp_create_control(dsp, region);
1095 } else { 1066 } else {
1096 adsp_warn(dsp, "Missing length info for region DM with ID %x\n", 1067 adsp_warn(dsp, "Missing length info for region DM with ID %x\n",
1097 be32_to_cpu(adsp1_alg[i].alg.id)); 1068 be32_to_cpu(adsp1_alg[i].alg.id));
@@ -1108,7 +1079,7 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec)
1108 if (i + 1 < algs) { 1079 if (i + 1 < algs) {
1109 region->len = be32_to_cpu(adsp1_alg[i + 1].zm); 1080 region->len = be32_to_cpu(adsp1_alg[i + 1].zm);
1110 region->len -= be32_to_cpu(adsp1_alg[i].zm); 1081 region->len -= be32_to_cpu(adsp1_alg[i].zm);
1111 wm_adsp_create_control(codec, region); 1082 wm_adsp_create_control(dsp, region);
1112 } else { 1083 } else {
1113 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", 1084 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n",
1114 be32_to_cpu(adsp1_alg[i].alg.id)); 1085 be32_to_cpu(adsp1_alg[i].alg.id));
@@ -1137,7 +1108,7 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec)
1137 if (i + 1 < algs) { 1108 if (i + 1 < algs) {
1138 region->len = be32_to_cpu(adsp2_alg[i + 1].xm); 1109 region->len = be32_to_cpu(adsp2_alg[i + 1].xm);
1139 region->len -= be32_to_cpu(adsp2_alg[i].xm); 1110 region->len -= be32_to_cpu(adsp2_alg[i].xm);
1140 wm_adsp_create_control(codec, region); 1111 wm_adsp_create_control(dsp, region);
1141 } else { 1112 } else {
1142 adsp_warn(dsp, "Missing length info for region XM with ID %x\n", 1113 adsp_warn(dsp, "Missing length info for region XM with ID %x\n",
1143 be32_to_cpu(adsp2_alg[i].alg.id)); 1114 be32_to_cpu(adsp2_alg[i].alg.id));
@@ -1154,7 +1125,7 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec)
1154 if (i + 1 < algs) { 1125 if (i + 1 < algs) {
1155 region->len = be32_to_cpu(adsp2_alg[i + 1].ym); 1126 region->len = be32_to_cpu(adsp2_alg[i + 1].ym);
1156 region->len -= be32_to_cpu(adsp2_alg[i].ym); 1127 region->len -= be32_to_cpu(adsp2_alg[i].ym);
1157 wm_adsp_create_control(codec, region); 1128 wm_adsp_create_control(dsp, region);
1158 } else { 1129 } else {
1159 adsp_warn(dsp, "Missing length info for region YM with ID %x\n", 1130 adsp_warn(dsp, "Missing length info for region YM with ID %x\n",
1160 be32_to_cpu(adsp2_alg[i].alg.id)); 1131 be32_to_cpu(adsp2_alg[i].alg.id));
@@ -1171,7 +1142,7 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec)
1171 if (i + 1 < algs) { 1142 if (i + 1 < algs) {
1172 region->len = be32_to_cpu(adsp2_alg[i + 1].zm); 1143 region->len = be32_to_cpu(adsp2_alg[i + 1].zm);
1173 region->len -= be32_to_cpu(adsp2_alg[i].zm); 1144 region->len -= be32_to_cpu(adsp2_alg[i].zm);
1174 wm_adsp_create_control(codec, region); 1145 wm_adsp_create_control(dsp, region);
1175 } else { 1146 } else {
1176 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", 1147 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n",
1177 be32_to_cpu(adsp2_alg[i].alg.id)); 1148 be32_to_cpu(adsp2_alg[i].alg.id));
@@ -1391,6 +1362,8 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1391 int ret; 1362 int ret;
1392 int val; 1363 int val;
1393 1364
1365 dsp->card = codec->card;
1366
1394 switch (event) { 1367 switch (event) {
1395 case SND_SOC_DAPM_POST_PMU: 1368 case SND_SOC_DAPM_POST_PMU:
1396 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 1369 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
@@ -1425,7 +1398,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1425 if (ret != 0) 1398 if (ret != 0)
1426 goto err; 1399 goto err;
1427 1400
1428 ret = wm_adsp_setup_algs(dsp, codec); 1401 ret = wm_adsp_setup_algs(dsp);
1429 if (ret != 0) 1402 if (ret != 0)
1430 goto err; 1403 goto err;
1431 1404
@@ -1434,12 +1407,12 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1434 goto err; 1407 goto err;
1435 1408
1436 /* Initialize caches for enabled and unset controls */ 1409 /* Initialize caches for enabled and unset controls */
1437 ret = wm_coeff_init_control_caches(dsp->wm_coeff); 1410 ret = wm_coeff_init_control_caches(dsp);
1438 if (ret != 0) 1411 if (ret != 0)
1439 goto err; 1412 goto err;
1440 1413
1441 /* Sync set controls */ 1414 /* Sync set controls */
1442 ret = wm_coeff_sync_controls(dsp->wm_coeff); 1415 ret = wm_coeff_sync_controls(dsp);
1443 if (ret != 0) 1416 if (ret != 0)
1444 goto err; 1417 goto err;
1445 1418
@@ -1460,10 +1433,8 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
1460 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 1433 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
1461 ADSP1_SYS_ENA, 0); 1434 ADSP1_SYS_ENA, 0);
1462 1435
1463 list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list, 1436 list_for_each_entry(ctl, &dsp->ctl_list, list)
1464 list) {
1465 ctl->enabled = 0; 1437 ctl->enabled = 0;
1466 }
1467 break; 1438 break;
1468 1439
1469 default: 1440 default:
@@ -1520,6 +1491,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1520 unsigned int val; 1491 unsigned int val;
1521 int ret; 1492 int ret;
1522 1493
1494 dsp->card = codec->card;
1495
1523 switch (event) { 1496 switch (event) {
1524 case SND_SOC_DAPM_POST_PMU: 1497 case SND_SOC_DAPM_POST_PMU:
1525 /* 1498 /*
@@ -1582,7 +1555,7 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1582 if (ret != 0) 1555 if (ret != 0)
1583 goto err; 1556 goto err;
1584 1557
1585 ret = wm_adsp_setup_algs(dsp, codec); 1558 ret = wm_adsp_setup_algs(dsp);
1586 if (ret != 0) 1559 if (ret != 0)
1587 goto err; 1560 goto err;
1588 1561
@@ -1591,12 +1564,12 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1591 goto err; 1564 goto err;
1592 1565
1593 /* Initialize caches for enabled and unset controls */ 1566 /* Initialize caches for enabled and unset controls */
1594 ret = wm_coeff_init_control_caches(dsp->wm_coeff); 1567 ret = wm_coeff_init_control_caches(dsp);
1595 if (ret != 0) 1568 if (ret != 0)
1596 goto err; 1569 goto err;
1597 1570
1598 /* Sync set controls */ 1571 /* Sync set controls */
1599 ret = wm_coeff_sync_controls(dsp->wm_coeff); 1572 ret = wm_coeff_sync_controls(dsp);
1600 if (ret != 0) 1573 if (ret != 0)
1601 goto err; 1574 goto err;
1602 1575
@@ -1637,10 +1610,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w,
1637 ret); 1610 ret);
1638 } 1611 }
1639 1612
1640 list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list, 1613 list_for_each_entry(ctl, &dsp->ctl_list, list)
1641 list) {
1642 ctl->enabled = 0; 1614 ctl->enabled = 0;
1643 }
1644 1615
1645 while (!list_empty(&dsp->alg_regions)) { 1616 while (!list_empty(&dsp->alg_regions)) {
1646 alg_region = list_first_entry(&dsp->alg_regions, 1617 alg_region = list_first_entry(&dsp->alg_regions,
@@ -1679,49 +1650,38 @@ int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs)
1679 } 1650 }
1680 1651
1681 INIT_LIST_HEAD(&adsp->alg_regions); 1652 INIT_LIST_HEAD(&adsp->alg_regions);
1682 1653 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 1654
1691 if (dvfs) { 1655 if (dvfs) {
1692 adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD"); 1656 adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD");
1693 if (IS_ERR(adsp->dvfs)) { 1657 if (IS_ERR(adsp->dvfs)) {
1694 ret = PTR_ERR(adsp->dvfs); 1658 ret = PTR_ERR(adsp->dvfs);
1695 dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret); 1659 dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret);
1696 goto out_coeff; 1660 return ret;
1697 } 1661 }
1698 1662
1699 ret = regulator_enable(adsp->dvfs); 1663 ret = regulator_enable(adsp->dvfs);
1700 if (ret != 0) { 1664 if (ret != 0) {
1701 dev_err(adsp->dev, "Failed to enable DCVDD: %d\n", 1665 dev_err(adsp->dev, "Failed to enable DCVDD: %d\n",
1702 ret); 1666 ret);
1703 goto out_coeff; 1667 return ret;
1704 } 1668 }
1705 1669
1706 ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000); 1670 ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000);
1707 if (ret != 0) { 1671 if (ret != 0) {
1708 dev_err(adsp->dev, "Failed to initialise DVFS: %d\n", 1672 dev_err(adsp->dev, "Failed to initialise DVFS: %d\n",
1709 ret); 1673 ret);
1710 goto out_coeff; 1674 return ret;
1711 } 1675 }
1712 1676
1713 ret = regulator_disable(adsp->dvfs); 1677 ret = regulator_disable(adsp->dvfs);
1714 if (ret != 0) { 1678 if (ret != 0) {
1715 dev_err(adsp->dev, "Failed to disable DCVDD: %d\n", 1679 dev_err(adsp->dev, "Failed to disable DCVDD: %d\n",
1716 ret); 1680 ret);
1717 goto out_coeff; 1681 return ret;
1718 } 1682 }
1719 } 1683 }
1720 1684
1721 return 0; 1685 return 0;
1722
1723out_coeff:
1724 kfree(adsp->wm_coeff);
1725 return ret;
1726} 1686}
1727EXPORT_SYMBOL_GPL(wm_adsp2_init); 1687EXPORT_SYMBOL_GPL(wm_adsp2_init);