diff options
| -rw-r--r-- | sound/soc/codecs/wm5102.c | 47 | ||||
| -rw-r--r-- | sound/soc/codecs/wm5110.c | 2 | ||||
| -rw-r--r-- | sound/soc/codecs/wm_adsp.c | 73 | ||||
| -rw-r--r-- | sound/soc/codecs/wm_adsp.h | 15 |
4 files changed, 54 insertions, 83 deletions
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index b73e3a3da2d2..11eba0e58fc0 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c | |||
| @@ -614,6 +614,49 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w, | |||
| 614 | return arizona_dvfs_sysclk_ev(w, kcontrol, event); | 614 | return arizona_dvfs_sysclk_ev(w, kcontrol, event); |
| 615 | } | 615 | } |
| 616 | 616 | ||
| 617 | static int wm5102_adsp_power_ev(struct snd_soc_dapm_widget *w, | ||
| 618 | struct snd_kcontrol *kcontrol, int event) | ||
| 619 | { | ||
| 620 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
| 621 | struct arizona *arizona = dev_get_drvdata(codec->dev->parent); | ||
| 622 | unsigned int v; | ||
| 623 | int ret; | ||
| 624 | |||
| 625 | switch (event) { | ||
| 626 | case SND_SOC_DAPM_PRE_PMU: | ||
| 627 | ret = regmap_read(arizona->regmap, ARIZONA_SYSTEM_CLOCK_1, &v); | ||
| 628 | if (ret != 0) { | ||
| 629 | dev_err(codec->dev, | ||
| 630 | "Failed to read SYSCLK state: %d\n", ret); | ||
| 631 | return -EIO; | ||
| 632 | } | ||
| 633 | |||
| 634 | v = (v & ARIZONA_SYSCLK_FREQ_MASK) >> ARIZONA_SYSCLK_FREQ_SHIFT; | ||
| 635 | |||
| 636 | if (v >= 3) { | ||
| 637 | ret = arizona_dvfs_up(codec, ARIZONA_DVFS_ADSP1_RQ); | ||
| 638 | if (ret) { | ||
| 639 | dev_err(codec->dev, | ||
| 640 | "Failed to raise DVFS: %d\n", ret); | ||
| 641 | return ret; | ||
| 642 | } | ||
| 643 | } | ||
| 644 | break; | ||
| 645 | |||
| 646 | case SND_SOC_DAPM_POST_PMD: | ||
| 647 | ret = arizona_dvfs_down(codec, ARIZONA_DVFS_ADSP1_RQ); | ||
| 648 | if (ret) | ||
| 649 | dev_warn(codec->dev, | ||
| 650 | "Failed to lower DVFS: %d\n", ret); | ||
| 651 | break; | ||
| 652 | |||
| 653 | default: | ||
| 654 | break; | ||
| 655 | } | ||
| 656 | |||
| 657 | return wm_adsp2_early_event(w, kcontrol, event); | ||
| 658 | } | ||
| 659 | |||
| 617 | static int wm5102_out_comp_coeff_get(struct snd_kcontrol *kcontrol, | 660 | static int wm5102_out_comp_coeff_get(struct snd_kcontrol *kcontrol, |
| 618 | struct snd_ctl_elem_value *ucontrol) | 661 | struct snd_ctl_elem_value *ucontrol) |
| 619 | { | 662 | { |
| @@ -1369,7 +1412,7 @@ ARIZONA_MUX_WIDGETS(ISRC2DEC2, "ISRC2DEC2"), | |||
| 1369 | ARIZONA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"), | 1412 | ARIZONA_MUX_WIDGETS(ISRC2INT1, "ISRC2INT1"), |
| 1370 | ARIZONA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"), | 1413 | ARIZONA_MUX_WIDGETS(ISRC2INT2, "ISRC2INT2"), |
| 1371 | 1414 | ||
| 1372 | WM_ADSP2("DSP1", 0), | 1415 | WM_ADSP2_E("DSP1", 0, wm5102_adsp_power_ev), |
| 1373 | 1416 | ||
| 1374 | SND_SOC_DAPM_OUTPUT("HPOUT1L"), | 1417 | SND_SOC_DAPM_OUTPUT("HPOUT1L"), |
| 1375 | SND_SOC_DAPM_OUTPUT("HPOUT1R"), | 1418 | SND_SOC_DAPM_OUTPUT("HPOUT1R"), |
| @@ -1922,7 +1965,7 @@ static int wm5102_probe(struct platform_device *pdev) | |||
| 1922 | wm5102->core.adsp[0].mem = wm5102_dsp1_regions; | 1965 | wm5102->core.adsp[0].mem = wm5102_dsp1_regions; |
| 1923 | wm5102->core.adsp[0].num_mems = ARRAY_SIZE(wm5102_dsp1_regions); | 1966 | wm5102->core.adsp[0].num_mems = ARRAY_SIZE(wm5102_dsp1_regions); |
| 1924 | 1967 | ||
| 1925 | ret = wm_adsp2_init(&wm5102->core.adsp[0], true); | 1968 | ret = wm_adsp2_init(&wm5102->core.adsp[0]); |
| 1926 | if (ret != 0) | 1969 | if (ret != 0) |
| 1927 | return ret; | 1970 | return ret; |
| 1928 | 1971 | ||
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index fbaeddb3e903..d65364e91532 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c | |||
| @@ -1697,7 +1697,7 @@ static int wm5110_probe(struct platform_device *pdev) | |||
| 1697 | wm5110->core.adsp[i].num_mems | 1697 | wm5110->core.adsp[i].num_mems |
| 1698 | = ARRAY_SIZE(wm5110_dsp1_regions); | 1698 | = ARRAY_SIZE(wm5110_dsp1_regions); |
| 1699 | 1699 | ||
| 1700 | ret = wm_adsp2_init(&wm5110->core.adsp[i], false); | 1700 | ret = wm_adsp2_init(&wm5110->core.adsp[i]); |
| 1701 | if (ret != 0) | 1701 | if (ret != 0) |
| 1702 | return ret; | 1702 | return ret; |
| 1703 | } | 1703 | } |
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 477390ad9c6d..b62ffd0c133e 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c | |||
| @@ -1811,35 +1811,6 @@ static void wm_adsp2_boot_work(struct work_struct *work) | |||
| 1811 | return; | 1811 | return; |
| 1812 | } | 1812 | } |
| 1813 | 1813 | ||
| 1814 | if (dsp->dvfs) { | ||
| 1815 | ret = regmap_read(dsp->regmap, | ||
| 1816 | dsp->base + ADSP2_CLOCKING, &val); | ||
| 1817 | if (ret != 0) { | ||
| 1818 | adsp_err(dsp, "Failed to read clocking: %d\n", ret); | ||
| 1819 | return; | ||
| 1820 | } | ||
| 1821 | |||
| 1822 | if ((val & ADSP2_CLK_SEL_MASK) >= 3) { | ||
| 1823 | ret = regulator_enable(dsp->dvfs); | ||
| 1824 | if (ret != 0) { | ||
| 1825 | adsp_err(dsp, | ||
| 1826 | "Failed to enable supply: %d\n", | ||
| 1827 | ret); | ||
| 1828 | return; | ||
| 1829 | } | ||
| 1830 | |||
| 1831 | ret = regulator_set_voltage(dsp->dvfs, | ||
| 1832 | 1800000, | ||
| 1833 | 1800000); | ||
| 1834 | if (ret != 0) { | ||
| 1835 | adsp_err(dsp, | ||
| 1836 | "Failed to raise supply: %d\n", | ||
| 1837 | ret); | ||
| 1838 | return; | ||
| 1839 | } | ||
| 1840 | } | ||
| 1841 | } | ||
| 1842 | |||
| 1843 | ret = wm_adsp2_ena(dsp); | 1814 | ret = wm_adsp2_ena(dsp); |
| 1844 | if (ret != 0) | 1815 | if (ret != 0) |
| 1845 | return; | 1816 | return; |
| @@ -1936,21 +1907,6 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, | |||
| 1936 | regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0); | 1907 | regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0); |
| 1937 | regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); | 1908 | regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); |
| 1938 | 1909 | ||
| 1939 | if (dsp->dvfs) { | ||
| 1940 | ret = regulator_set_voltage(dsp->dvfs, 1200000, | ||
| 1941 | 1800000); | ||
| 1942 | if (ret != 0) | ||
| 1943 | adsp_warn(dsp, | ||
| 1944 | "Failed to lower supply: %d\n", | ||
| 1945 | ret); | ||
| 1946 | |||
| 1947 | ret = regulator_disable(dsp->dvfs); | ||
| 1948 | if (ret != 0) | ||
| 1949 | adsp_err(dsp, | ||
| 1950 | "Failed to enable supply: %d\n", | ||
| 1951 | ret); | ||
| 1952 | } | ||
| 1953 | |||
| 1954 | list_for_each_entry(ctl, &dsp->ctl_list, list) | 1910 | list_for_each_entry(ctl, &dsp->ctl_list, list) |
| 1955 | ctl->enabled = 0; | 1911 | ctl->enabled = 0; |
| 1956 | 1912 | ||
| @@ -1977,7 +1933,7 @@ err: | |||
| 1977 | } | 1933 | } |
| 1978 | EXPORT_SYMBOL_GPL(wm_adsp2_event); | 1934 | EXPORT_SYMBOL_GPL(wm_adsp2_event); |
| 1979 | 1935 | ||
| 1980 | int wm_adsp2_init(struct wm_adsp *dsp, bool dvfs) | 1936 | int wm_adsp2_init(struct wm_adsp *dsp) |
| 1981 | { | 1937 | { |
| 1982 | int ret; | 1938 | int ret; |
| 1983 | 1939 | ||
| @@ -1996,33 +1952,6 @@ int wm_adsp2_init(struct wm_adsp *dsp, bool dvfs) | |||
| 1996 | INIT_LIST_HEAD(&dsp->ctl_list); | 1952 | INIT_LIST_HEAD(&dsp->ctl_list); |
| 1997 | INIT_WORK(&dsp->boot_work, wm_adsp2_boot_work); | 1953 | INIT_WORK(&dsp->boot_work, wm_adsp2_boot_work); |
| 1998 | 1954 | ||
| 1999 | if (dvfs) { | ||
| 2000 | dsp->dvfs = devm_regulator_get(dsp->dev, "DCVDD"); | ||
| 2001 | if (IS_ERR(dsp->dvfs)) { | ||
| 2002 | ret = PTR_ERR(dsp->dvfs); | ||
| 2003 | adsp_err(dsp, "Failed to get DCVDD: %d\n", ret); | ||
| 2004 | return ret; | ||
| 2005 | } | ||
| 2006 | |||
| 2007 | ret = regulator_enable(dsp->dvfs); | ||
| 2008 | if (ret != 0) { | ||
| 2009 | adsp_err(dsp, "Failed to enable DCVDD: %d\n", ret); | ||
| 2010 | return ret; | ||
| 2011 | } | ||
| 2012 | |||
| 2013 | ret = regulator_set_voltage(dsp->dvfs, 1200000, 1800000); | ||
| 2014 | if (ret != 0) { | ||
| 2015 | adsp_err(dsp, "Failed to initialise DVFS: %d\n", ret); | ||
| 2016 | return ret; | ||
| 2017 | } | ||
| 2018 | |||
| 2019 | ret = regulator_disable(dsp->dvfs); | ||
| 2020 | if (ret != 0) { | ||
| 2021 | adsp_err(dsp, "Failed to disable DCVDD: %d\n", ret); | ||
| 2022 | return ret; | ||
| 2023 | } | ||
| 2024 | } | ||
| 2025 | |||
| 2026 | return 0; | 1955 | return 0; |
| 2027 | } | 1956 | } |
| 2028 | EXPORT_SYMBOL_GPL(wm_adsp2_init); | 1957 | EXPORT_SYMBOL_GPL(wm_adsp2_init); |
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index 4fe066745377..0e5f07c35d50 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h | |||
| @@ -18,8 +18,6 @@ | |||
| 18 | 18 | ||
| 19 | #include "wmfw.h" | 19 | #include "wmfw.h" |
| 20 | 20 | ||
| 21 | struct regulator; | ||
| 22 | |||
| 23 | struct wm_adsp_region { | 21 | struct wm_adsp_region { |
| 24 | int type; | 22 | int type; |
| 25 | unsigned int base; | 23 | unsigned int base; |
| @@ -56,8 +54,6 @@ struct wm_adsp { | |||
| 56 | int fw_ver; | 54 | int fw_ver; |
| 57 | bool running; | 55 | bool running; |
| 58 | 56 | ||
| 59 | struct regulator *dvfs; | ||
| 60 | |||
| 61 | struct list_head ctl_list; | 57 | struct list_head ctl_list; |
| 62 | 58 | ||
| 63 | struct work_struct boot_work; | 59 | struct work_struct boot_work; |
| @@ -67,19 +63,22 @@ struct wm_adsp { | |||
| 67 | SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \ | 63 | SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \ |
| 68 | wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) | 64 | wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) |
| 69 | 65 | ||
| 70 | #define WM_ADSP2(wname, num) \ | 66 | #define WM_ADSP2_E(wname, num, event_fn) \ |
| 71 | { .id = snd_soc_dapm_dai_link, .name = wname " Preloader", \ | 67 | { .id = snd_soc_dapm_dai_link, .name = wname " Preloader", \ |
| 72 | .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_early_event, \ | 68 | .reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \ |
| 73 | .event_flags = SND_SOC_DAPM_PRE_PMU }, \ | 69 | .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }, \ |
| 74 | { .id = snd_soc_dapm_out_drv, .name = wname, \ | 70 | { .id = snd_soc_dapm_out_drv, .name = wname, \ |
| 75 | .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \ | 71 | .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \ |
| 76 | .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } | 72 | .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } |
| 77 | 73 | ||
| 74 | #define WM_ADSP2(wname, num) \ | ||
| 75 | WM_ADSP2_E(wname, num, wm_adsp2_early_event) | ||
| 76 | |||
| 78 | extern const struct snd_kcontrol_new wm_adsp1_fw_controls[]; | 77 | extern const struct snd_kcontrol_new wm_adsp1_fw_controls[]; |
| 79 | extern const struct snd_kcontrol_new wm_adsp2_fw_controls[]; | 78 | extern const struct snd_kcontrol_new wm_adsp2_fw_controls[]; |
| 80 | 79 | ||
| 81 | int wm_adsp1_init(struct wm_adsp *dsp); | 80 | int wm_adsp1_init(struct wm_adsp *dsp); |
| 82 | int wm_adsp2_init(struct wm_adsp *dsp, bool dvfs); | 81 | int wm_adsp2_init(struct wm_adsp *dsp); |
| 83 | int wm_adsp1_event(struct snd_soc_dapm_widget *w, | 82 | int wm_adsp1_event(struct snd_soc_dapm_widget *w, |
| 84 | struct snd_kcontrol *kcontrol, int event); | 83 | struct snd_kcontrol *kcontrol, int event); |
| 85 | int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, | 84 | int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, |
