diff options
Diffstat (limited to 'sound/soc/codecs/wm_adsp.c')
-rw-r--r-- | sound/soc/codecs/wm_adsp.c | 124 |
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 | ||
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; | ||
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, | |||
378 | static int wm_coeff_write_control(struct snd_kcontrol *kcontrol, | 371 | static 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, | |||
434 | static int wm_coeff_read_control(struct snd_kcontrol *kcontrol, | 426 | static 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 | ||
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 { | 475 | struct 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 | ||
508 | static int wmfw_add_ctl(struct wm_coeff *wm_coeff, | 481 | static 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 | ||
538 | err_kcontrol: | 513 | err_kcontrol: |
@@ -753,13 +728,12 @@ out: | |||
753 | return ret; | 728 | return ret; |
754 | } | 729 | } |
755 | 730 | ||
756 | static int wm_coeff_init_control_caches(struct wm_coeff *wm_coeff) | 731 | static 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 | ||
775 | static int wm_coeff_sync_controls(struct wm_coeff *wm_coeff) | 749 | static 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 | ||
806 | static int wm_adsp_create_control(struct snd_soc_codec *codec, | 779 | static 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 | ||
906 | static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec) | 877 | static 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 | |||
1723 | out_coeff: | ||
1724 | kfree(adsp->wm_coeff); | ||
1725 | return ret; | ||
1726 | } | 1686 | } |
1727 | EXPORT_SYMBOL_GPL(wm_adsp2_init); | 1687 | EXPORT_SYMBOL_GPL(wm_adsp2_init); |