Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: wm2000: Add regulator support

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

+47 -6
+47 -6
sound/soc/codecs/wm2000.c
··· 31 31 #include <linux/i2c.h> 32 32 #include <linux/regmap.h> 33 33 #include <linux/debugfs.h> 34 + #include <linux/regulator/consumer.h> 34 35 #include <linux/slab.h> 35 36 #include <sound/core.h> 36 37 #include <sound/pcm.h> ··· 44 43 45 44 #include "wm2000.h" 46 45 46 + #define WM2000_NUM_SUPPLIES 3 47 + 48 + static const char *wm2000_supplies[WM2000_NUM_SUPPLIES] = { 49 + "SPKVDD", 50 + "DBVDD", 51 + "DCVDD", 52 + }; 53 + 47 54 enum wm2000_anc_mode { 48 55 ANC_ACTIVE = 0, 49 56 ANC_BYPASS = 1, ··· 62 53 struct wm2000_priv { 63 54 struct i2c_client *i2c; 64 55 struct regmap *regmap; 56 + 57 + struct regulator_bulk_data supplies[WM2000_NUM_SUPPLIES]; 65 58 66 59 enum wm2000_anc_mode anc_mode; 67 60 ··· 137 126 138 127 dev_dbg(&i2c->dev, "Beginning power up\n"); 139 128 129 + ret = regulator_bulk_enable(WM2000_NUM_SUPPLIES, wm2000->supplies); 130 + if (ret != 0) { 131 + dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); 132 + return ret; 133 + } 134 + 140 135 if (!wm2000->mclk_div) { 141 136 dev_dbg(&i2c->dev, "Disabling MCLK divider\n"); 142 137 wm2000_write(i2c, WM2000_REG_SYS_CTL2, ··· 160 143 if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, 161 144 WM2000_ANC_ENG_IDLE)) { 162 145 dev_err(&i2c->dev, "ANC engine failed to reset\n"); 146 + regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); 163 147 return -ETIMEDOUT; 164 148 } 165 149 166 150 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, 167 151 WM2000_STATUS_BOOT_COMPLETE)) { 168 152 dev_err(&i2c->dev, "ANC engine failed to initialise\n"); 153 + regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); 169 154 return -ETIMEDOUT; 170 155 } 171 156 ··· 182 163 wm2000->anc_download_size); 183 164 if (ret < 0) { 184 165 dev_err(&i2c->dev, "i2c_transfer() failed: %d\n", ret); 166 + regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); 185 167 return ret; 186 168 } 187 169 if (ret != wm2000->anc_download_size) { 188 170 dev_err(&i2c->dev, "i2c_transfer() failed, %d != %d\n", 189 171 ret, wm2000->anc_download_size); 172 + regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); 190 173 return -EIO; 191 174 } 192 175 ··· 222 201 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, 223 202 WM2000_STATUS_MOUSE_ACTIVE)) { 224 203 dev_err(&i2c->dev, "Timed out waiting for device\n"); 204 + regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); 225 205 return -ETIMEDOUT; 226 206 } 227 207 ··· 259 237 dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n"); 260 238 return -ETIMEDOUT; 261 239 } 240 + 241 + regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); 262 242 263 243 dev_dbg(&i2c->dev, "powered off\n"); 264 244 wm2000->anc_mode = ANC_OFF; ··· 771 747 struct wm2000_platform_data *pdata; 772 748 const char *filename; 773 749 const struct firmware *fw = NULL; 774 - int ret; 750 + int ret, i; 775 751 int reg; 776 752 u16 id; 777 753 ··· 792 768 goto out; 793 769 } 794 770 771 + for (i = 0; i < WM2000_NUM_SUPPLIES; i++) 772 + wm2000->supplies[i].supply = wm2000_supplies[i]; 773 + 774 + ret = devm_regulator_bulk_get(&i2c->dev, WM2000_NUM_SUPPLIES, 775 + wm2000->supplies); 776 + if (ret != 0) { 777 + dev_err(&i2c->dev, "Failed to get supplies: %d\n", ret); 778 + return ret; 779 + } 780 + 781 + ret = regulator_bulk_enable(WM2000_NUM_SUPPLIES, wm2000->supplies); 782 + if (ret != 0) { 783 + dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); 784 + return ret; 785 + } 786 + 795 787 /* Verify that this is a WM2000 */ 796 788 reg = wm2000_read(i2c, WM2000_REG_ID1); 797 789 id = reg << 8; ··· 817 777 if (id != 0x2000) { 818 778 dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id); 819 779 ret = -ENODEV; 820 - goto out; 780 + goto err_supplies; 821 781 } 822 782 823 783 reg = wm2000_read(i2c, WM2000_REG_REVISON); ··· 836 796 ret = request_firmware(&fw, filename, &i2c->dev); 837 797 if (ret != 0) { 838 798 dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); 839 - goto out; 799 + goto err_supplies; 840 800 } 841 801 842 802 /* Pre-cook the concatenation of the register address onto the image */ ··· 847 807 if (wm2000->anc_download == NULL) { 848 808 dev_err(&i2c->dev, "Out of memory\n"); 849 809 ret = -ENOMEM; 850 - goto out; 810 + goto err_supplies; 851 811 } 852 812 853 813 wm2000->anc_download[0] = 0x80; ··· 862 822 wm2000_reset(wm2000); 863 823 864 824 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0); 865 - if (!ret) 866 - goto out; 825 + 826 + err_supplies: 827 + regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); 867 828 868 829 out: 869 830 release_firmware(fw);