aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm2000.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-08 18:07:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-08 18:07:14 -0400
commitf5a246eab9a268f51ba8189ea5b098a1bfff200e (patch)
treea6ff7169e0bcaca498d9aec8b0624de1b74eaecb /sound/soc/codecs/wm2000.c
parentd5bbd43d5f450c3fca058f5b85f3dfb4e8cc88c9 (diff)
parent7ff34ad80b7080fafaac8efa9ef0061708eddd51 (diff)
Merge tag 'sound-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "This contains pretty many small commits covering fairly large range of files in sound/ directory. Partly because of additional API support and partly because of constantly developed ASoC and ARM stuff. Some highlights: - Introduced the helper function and documentation for exposing the channel map via control API, as discussed in Plumbers; most of PCI drivers are covered, will follow more drivers later - Most of drivers have been replaced with the new PM callbacks (if the bus is supported) - HD-audio controller got the support of runtime PM and the support of D3 clock-stop. Also changing the power_save option in sysfs kicks off immediately to enable / disable the power-save mode. - Another significant code change in HD-audio is the rewrite of firmware loading code. Other than that, most of changes in HD-audio are continued cleanups and standardization for the generic auto parser and bug fixes (HBR, device-specific fixups), in addition to the support of channel-map API. - Addition of ASoC bindings for the compressed API, used by the mid-x86 drivers. - Lots of cleanups and API refreshes for ASoC codec drivers and DaVinci. - Conversion of OMAP to dmaengine. - New machine driver for Wolfson Microelectronics Bells. - New CODEC driver for Wolfson Microelectronics WM0010. - Enhancements to the ux500 and wm2000 drivers - A new driver for DA9055 and the support for regulator bypass mode." Fix up various arm soc header file reorg conflicts. * tag 'sound-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (339 commits) ALSA: hda - Add new codec ALC283 ALC290 support ALSA: hda - avoid unneccesary indices on "Headphone Jack" controls ALSA: hda - fix indices on boost volume on Conexant ALSA: aloop - add locking to timer access ALSA: hda - Fix hang caused by race during suspend. sound: Remove unnecessary semicolon ALSA: hda/realtek - Fix detection of ALC271X codec ALSA: hda - Add inverted internal mic quirk for Lenovo IdeaPad U310 ALSA: hda - make Realtek/Sigmatel/Conexant use the generic unsol event ALSA: hda - make a generic unsol event handler ASoC: codecs: Add DA9055 codec driver ASoC: eukrea-tlv320: Convert it to platform driver ALSA: ASoC: add DT bindings for CS4271 ASoC: wm_hubs: Ensure volume updates are handled during class W startup ASoC: wm5110: Adding missing volume update bits ASoC: wm5110: Add OUT3R support ASoC: wm5110: Add AEC loopback support ASoC: wm5110: Rename EPOUT to HPOUT3 ASoC: arizona: Add more clock rates ASoC: arizona: Add more DSP options for mixer input muxes ...
Diffstat (limited to 'sound/soc/codecs/wm2000.c')
-rw-r--r--sound/soc/codecs/wm2000.c72
1 files changed, 49 insertions, 23 deletions
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index a3acb7a85f6a..683dc43b1d87 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -31,6 +31,7 @@
31#include <linux/i2c.h> 31#include <linux/i2c.h>
32#include <linux/regmap.h> 32#include <linux/regmap.h>
33#include <linux/debugfs.h> 33#include <linux/debugfs.h>
34#include <linux/regulator/consumer.h>
34#include <linux/slab.h> 35#include <linux/slab.h>
35#include <sound/core.h> 36#include <sound/core.h>
36#include <sound/pcm.h> 37#include <sound/pcm.h>
@@ -43,6 +44,14 @@
43 44
44#include "wm2000.h" 45#include "wm2000.h"
45 46
47#define WM2000_NUM_SUPPLIES 3
48
49static const char *wm2000_supplies[WM2000_NUM_SUPPLIES] = {
50 "SPKVDD",
51 "DBVDD",
52 "DCVDD",
53};
54
46enum wm2000_anc_mode { 55enum wm2000_anc_mode {
47 ANC_ACTIVE = 0, 56 ANC_ACTIVE = 0,
48 ANC_BYPASS = 1, 57 ANC_BYPASS = 1,
@@ -54,6 +63,8 @@ struct wm2000_priv {
54 struct i2c_client *i2c; 63 struct i2c_client *i2c;
55 struct regmap *regmap; 64 struct regmap *regmap;
56 65
66 struct regulator_bulk_data supplies[WM2000_NUM_SUPPLIES];
67
57 enum wm2000_anc_mode anc_mode; 68 enum wm2000_anc_mode anc_mode;
58 69
59 unsigned int anc_active:1; 70 unsigned int anc_active:1;
@@ -126,6 +137,12 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue)
126 137
127 dev_dbg(&i2c->dev, "Beginning power up\n"); 138 dev_dbg(&i2c->dev, "Beginning power up\n");
128 139
140 ret = regulator_bulk_enable(WM2000_NUM_SUPPLIES, wm2000->supplies);
141 if (ret != 0) {
142 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
143 return ret;
144 }
145
129 if (!wm2000->mclk_div) { 146 if (!wm2000->mclk_div) {
130 dev_dbg(&i2c->dev, "Disabling MCLK divider\n"); 147 dev_dbg(&i2c->dev, "Disabling MCLK divider\n");
131 wm2000_write(i2c, WM2000_REG_SYS_CTL2, 148 wm2000_write(i2c, WM2000_REG_SYS_CTL2,
@@ -143,12 +160,14 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue)
143 if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, 160 if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
144 WM2000_ANC_ENG_IDLE)) { 161 WM2000_ANC_ENG_IDLE)) {
145 dev_err(&i2c->dev, "ANC engine failed to reset\n"); 162 dev_err(&i2c->dev, "ANC engine failed to reset\n");
163 regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
146 return -ETIMEDOUT; 164 return -ETIMEDOUT;
147 } 165 }
148 166
149 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, 167 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
150 WM2000_STATUS_BOOT_COMPLETE)) { 168 WM2000_STATUS_BOOT_COMPLETE)) {
151 dev_err(&i2c->dev, "ANC engine failed to initialise\n"); 169 dev_err(&i2c->dev, "ANC engine failed to initialise\n");
170 regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
152 return -ETIMEDOUT; 171 return -ETIMEDOUT;
153 } 172 }
154 173
@@ -163,11 +182,13 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue)
163 wm2000->anc_download_size); 182 wm2000->anc_download_size);
164 if (ret < 0) { 183 if (ret < 0) {
165 dev_err(&i2c->dev, "i2c_transfer() failed: %d\n", ret); 184 dev_err(&i2c->dev, "i2c_transfer() failed: %d\n", ret);
185 regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
166 return ret; 186 return ret;
167 } 187 }
168 if (ret != wm2000->anc_download_size) { 188 if (ret != wm2000->anc_download_size) {
169 dev_err(&i2c->dev, "i2c_transfer() failed, %d != %d\n", 189 dev_err(&i2c->dev, "i2c_transfer() failed, %d != %d\n",
170 ret, wm2000->anc_download_size); 190 ret, wm2000->anc_download_size);
191 regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
171 return -EIO; 192 return -EIO;
172 } 193 }
173 194
@@ -201,6 +222,7 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue)
201 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, 222 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
202 WM2000_STATUS_MOUSE_ACTIVE)) { 223 WM2000_STATUS_MOUSE_ACTIVE)) {
203 dev_err(&i2c->dev, "Timed out waiting for device\n"); 224 dev_err(&i2c->dev, "Timed out waiting for device\n");
225 regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
204 return -ETIMEDOUT; 226 return -ETIMEDOUT;
205 } 227 }
206 228
@@ -238,6 +260,8 @@ static int wm2000_power_down(struct i2c_client *i2c, int analogue)
238 return -ETIMEDOUT; 260 return -ETIMEDOUT;
239 } 261 }
240 262
263 regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
264
241 dev_dbg(&i2c->dev, "powered off\n"); 265 dev_dbg(&i2c->dev, "powered off\n");
242 wm2000->anc_mode = ANC_OFF; 266 wm2000->anc_mode = ANC_OFF;
243 267
@@ -747,7 +771,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
747 struct wm2000_platform_data *pdata; 771 struct wm2000_platform_data *pdata;
748 const char *filename; 772 const char *filename;
749 const struct firmware *fw = NULL; 773 const struct firmware *fw = NULL;
750 int ret; 774 int ret, i;
751 int reg; 775 int reg;
752 u16 id; 776 u16 id;
753 777
@@ -760,7 +784,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
760 784
761 dev_set_drvdata(&i2c->dev, wm2000); 785 dev_set_drvdata(&i2c->dev, wm2000);
762 786
763 wm2000->regmap = regmap_init_i2c(i2c, &wm2000_regmap); 787 wm2000->regmap = devm_regmap_init_i2c(i2c, &wm2000_regmap);
764 if (IS_ERR(wm2000->regmap)) { 788 if (IS_ERR(wm2000->regmap)) {
765 ret = PTR_ERR(wm2000->regmap); 789 ret = PTR_ERR(wm2000->regmap);
766 dev_err(&i2c->dev, "Failed to allocate register map: %d\n", 790 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
@@ -768,6 +792,22 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
768 goto out; 792 goto out;
769 } 793 }
770 794
795 for (i = 0; i < WM2000_NUM_SUPPLIES; i++)
796 wm2000->supplies[i].supply = wm2000_supplies[i];
797
798 ret = devm_regulator_bulk_get(&i2c->dev, WM2000_NUM_SUPPLIES,
799 wm2000->supplies);
800 if (ret != 0) {
801 dev_err(&i2c->dev, "Failed to get supplies: %d\n", ret);
802 return ret;
803 }
804
805 ret = regulator_bulk_enable(WM2000_NUM_SUPPLIES, wm2000->supplies);
806 if (ret != 0) {
807 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
808 return ret;
809 }
810
771 /* Verify that this is a WM2000 */ 811 /* Verify that this is a WM2000 */
772 reg = wm2000_read(i2c, WM2000_REG_ID1); 812 reg = wm2000_read(i2c, WM2000_REG_ID1);
773 id = reg << 8; 813 id = reg << 8;
@@ -777,7 +817,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
777 if (id != 0x2000) { 817 if (id != 0x2000) {
778 dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id); 818 dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id);
779 ret = -ENODEV; 819 ret = -ENODEV;
780 goto out_regmap_exit; 820 goto err_supplies;
781 } 821 }
782 822
783 reg = wm2000_read(i2c, WM2000_REG_REVISON); 823 reg = wm2000_read(i2c, WM2000_REG_REVISON);
@@ -796,7 +836,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
796 ret = request_firmware(&fw, filename, &i2c->dev); 836 ret = request_firmware(&fw, filename, &i2c->dev);
797 if (ret != 0) { 837 if (ret != 0) {
798 dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); 838 dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret);
799 goto out_regmap_exit; 839 goto err_supplies;
800 } 840 }
801 841
802 /* Pre-cook the concatenation of the register address onto the image */ 842 /* Pre-cook the concatenation of the register address onto the image */
@@ -807,7 +847,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
807 if (wm2000->anc_download == NULL) { 847 if (wm2000->anc_download == NULL) {
808 dev_err(&i2c->dev, "Out of memory\n"); 848 dev_err(&i2c->dev, "Out of memory\n");
809 ret = -ENOMEM; 849 ret = -ENOMEM;
810 goto out_regmap_exit; 850 goto err_supplies;
811 } 851 }
812 852
813 wm2000->anc_download[0] = 0x80; 853 wm2000->anc_download[0] = 0x80;
@@ -822,11 +862,10 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
822 wm2000_reset(wm2000); 862 wm2000_reset(wm2000);
823 863
824 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0); 864 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0);
825 if (!ret)
826 goto out;
827 865
828out_regmap_exit: 866err_supplies:
829 regmap_exit(wm2000->regmap); 867 regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
868
830out: 869out:
831 release_firmware(fw); 870 release_firmware(fw);
832 return ret; 871 return ret;
@@ -834,10 +873,7 @@ out:
834 873
835static __devexit int wm2000_i2c_remove(struct i2c_client *i2c) 874static __devexit int wm2000_i2c_remove(struct i2c_client *i2c)
836{ 875{
837 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
838
839 snd_soc_unregister_codec(&i2c->dev); 876 snd_soc_unregister_codec(&i2c->dev);
840 regmap_exit(wm2000->regmap);
841 877
842 return 0; 878 return 0;
843} 879}
@@ -858,17 +894,7 @@ static struct i2c_driver wm2000_i2c_driver = {
858 .id_table = wm2000_i2c_id, 894 .id_table = wm2000_i2c_id,
859}; 895};
860 896
861static int __init wm2000_init(void) 897module_i2c_driver(wm2000_i2c_driver);
862{
863 return i2c_add_driver(&wm2000_i2c_driver);
864}
865module_init(wm2000_init);
866
867static void __exit wm2000_exit(void)
868{
869 i2c_del_driver(&wm2000_i2c_driver);
870}
871module_exit(wm2000_exit);
872 898
873MODULE_DESCRIPTION("ASoC WM2000 driver"); 899MODULE_DESCRIPTION("ASoC WM2000 driver");
874MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>"); 900MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>");