Loading sound/soc/codecs/wm2000.c +47 −6 Original line number Original line Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include <linux/i2c.h> #include <linux/i2c.h> #include <linux/regmap.h> #include <linux/regmap.h> #include <linux/debugfs.h> #include <linux/debugfs.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm.h> Loading @@ -43,6 +44,14 @@ #include "wm2000.h" #include "wm2000.h" #define WM2000_NUM_SUPPLIES 3 static const char *wm2000_supplies[WM2000_NUM_SUPPLIES] = { "SPKVDD", "DBVDD", "DCVDD", }; enum wm2000_anc_mode { enum wm2000_anc_mode { ANC_ACTIVE = 0, ANC_ACTIVE = 0, ANC_BYPASS = 1, ANC_BYPASS = 1, Loading @@ -54,6 +63,8 @@ struct wm2000_priv { struct i2c_client *i2c; struct i2c_client *i2c; struct regmap *regmap; struct regmap *regmap; struct regulator_bulk_data supplies[WM2000_NUM_SUPPLIES]; enum wm2000_anc_mode anc_mode; enum wm2000_anc_mode anc_mode; unsigned int anc_active:1; unsigned int anc_active:1; Loading Loading @@ -126,6 +137,12 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) dev_dbg(&i2c->dev, "Beginning power up\n"); dev_dbg(&i2c->dev, "Beginning power up\n"); ret = regulator_bulk_enable(WM2000_NUM_SUPPLIES, wm2000->supplies); if (ret != 0) { dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); return ret; } if (!wm2000->mclk_div) { if (!wm2000->mclk_div) { dev_dbg(&i2c->dev, "Disabling MCLK divider\n"); dev_dbg(&i2c->dev, "Disabling MCLK divider\n"); wm2000_write(i2c, WM2000_REG_SYS_CTL2, wm2000_write(i2c, WM2000_REG_SYS_CTL2, Loading @@ -143,12 +160,14 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, WM2000_ANC_ENG_IDLE)) { WM2000_ANC_ENG_IDLE)) { dev_err(&i2c->dev, "ANC engine failed to reset\n"); dev_err(&i2c->dev, "ANC engine failed to reset\n"); regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); return -ETIMEDOUT; return -ETIMEDOUT; } } if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, WM2000_STATUS_BOOT_COMPLETE)) { WM2000_STATUS_BOOT_COMPLETE)) { dev_err(&i2c->dev, "ANC engine failed to initialise\n"); dev_err(&i2c->dev, "ANC engine failed to initialise\n"); regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); return -ETIMEDOUT; return -ETIMEDOUT; } } Loading @@ -163,11 +182,13 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) wm2000->anc_download_size); wm2000->anc_download_size); if (ret < 0) { if (ret < 0) { dev_err(&i2c->dev, "i2c_transfer() failed: %d\n", ret); dev_err(&i2c->dev, "i2c_transfer() failed: %d\n", ret); regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); return ret; return ret; } } if (ret != wm2000->anc_download_size) { if (ret != wm2000->anc_download_size) { dev_err(&i2c->dev, "i2c_transfer() failed, %d != %d\n", dev_err(&i2c->dev, "i2c_transfer() failed, %d != %d\n", ret, wm2000->anc_download_size); ret, wm2000->anc_download_size); regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); return -EIO; return -EIO; } } Loading Loading @@ -201,6 +222,7 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, WM2000_STATUS_MOUSE_ACTIVE)) { WM2000_STATUS_MOUSE_ACTIVE)) { dev_err(&i2c->dev, "Timed out waiting for device\n"); dev_err(&i2c->dev, "Timed out waiting for device\n"); regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); return -ETIMEDOUT; return -ETIMEDOUT; } } Loading Loading @@ -238,6 +260,8 @@ static int wm2000_power_down(struct i2c_client *i2c, int analogue) return -ETIMEDOUT; return -ETIMEDOUT; } } regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); dev_dbg(&i2c->dev, "powered off\n"); dev_dbg(&i2c->dev, "powered off\n"); wm2000->anc_mode = ANC_OFF; wm2000->anc_mode = ANC_OFF; Loading Loading @@ -747,7 +771,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, struct wm2000_platform_data *pdata; struct wm2000_platform_data *pdata; const char *filename; const char *filename; const struct firmware *fw = NULL; const struct firmware *fw = NULL; int ret; int ret, i; int reg; int reg; u16 id; u16 id; Loading @@ -768,6 +792,22 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, goto out; goto out; } } for (i = 0; i < WM2000_NUM_SUPPLIES; i++) wm2000->supplies[i].supply = wm2000_supplies[i]; ret = devm_regulator_bulk_get(&i2c->dev, WM2000_NUM_SUPPLIES, wm2000->supplies); if (ret != 0) { dev_err(&i2c->dev, "Failed to get supplies: %d\n", ret); return ret; } ret = regulator_bulk_enable(WM2000_NUM_SUPPLIES, wm2000->supplies); if (ret != 0) { dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); return ret; } /* Verify that this is a WM2000 */ /* Verify that this is a WM2000 */ reg = wm2000_read(i2c, WM2000_REG_ID1); reg = wm2000_read(i2c, WM2000_REG_ID1); id = reg << 8; id = reg << 8; Loading @@ -777,7 +817,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, if (id != 0x2000) { if (id != 0x2000) { dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id); dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id); ret = -ENODEV; ret = -ENODEV; goto out; goto err_supplies; } } reg = wm2000_read(i2c, WM2000_REG_REVISON); reg = wm2000_read(i2c, WM2000_REG_REVISON); Loading @@ -796,7 +836,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, ret = request_firmware(&fw, filename, &i2c->dev); ret = request_firmware(&fw, filename, &i2c->dev); if (ret != 0) { if (ret != 0) { dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); goto out; goto err_supplies; } } /* Pre-cook the concatenation of the register address onto the image */ /* Pre-cook the concatenation of the register address onto the image */ Loading @@ -807,7 +847,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, if (wm2000->anc_download == NULL) { if (wm2000->anc_download == NULL) { dev_err(&i2c->dev, "Out of memory\n"); dev_err(&i2c->dev, "Out of memory\n"); ret = -ENOMEM; ret = -ENOMEM; goto out; goto err_supplies; } } wm2000->anc_download[0] = 0x80; wm2000->anc_download[0] = 0x80; Loading @@ -822,8 +862,9 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, wm2000_reset(wm2000); wm2000_reset(wm2000); ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0); ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0); if (!ret) goto out; err_supplies: regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); out: out: release_firmware(fw); release_firmware(fw); Loading Loading
sound/soc/codecs/wm2000.c +47 −6 Original line number Original line Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include <linux/i2c.h> #include <linux/i2c.h> #include <linux/regmap.h> #include <linux/regmap.h> #include <linux/debugfs.h> #include <linux/debugfs.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm.h> Loading @@ -43,6 +44,14 @@ #include "wm2000.h" #include "wm2000.h" #define WM2000_NUM_SUPPLIES 3 static const char *wm2000_supplies[WM2000_NUM_SUPPLIES] = { "SPKVDD", "DBVDD", "DCVDD", }; enum wm2000_anc_mode { enum wm2000_anc_mode { ANC_ACTIVE = 0, ANC_ACTIVE = 0, ANC_BYPASS = 1, ANC_BYPASS = 1, Loading @@ -54,6 +63,8 @@ struct wm2000_priv { struct i2c_client *i2c; struct i2c_client *i2c; struct regmap *regmap; struct regmap *regmap; struct regulator_bulk_data supplies[WM2000_NUM_SUPPLIES]; enum wm2000_anc_mode anc_mode; enum wm2000_anc_mode anc_mode; unsigned int anc_active:1; unsigned int anc_active:1; Loading Loading @@ -126,6 +137,12 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) dev_dbg(&i2c->dev, "Beginning power up\n"); dev_dbg(&i2c->dev, "Beginning power up\n"); ret = regulator_bulk_enable(WM2000_NUM_SUPPLIES, wm2000->supplies); if (ret != 0) { dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); return ret; } if (!wm2000->mclk_div) { if (!wm2000->mclk_div) { dev_dbg(&i2c->dev, "Disabling MCLK divider\n"); dev_dbg(&i2c->dev, "Disabling MCLK divider\n"); wm2000_write(i2c, WM2000_REG_SYS_CTL2, wm2000_write(i2c, WM2000_REG_SYS_CTL2, Loading @@ -143,12 +160,14 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, WM2000_ANC_ENG_IDLE)) { WM2000_ANC_ENG_IDLE)) { dev_err(&i2c->dev, "ANC engine failed to reset\n"); dev_err(&i2c->dev, "ANC engine failed to reset\n"); regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); return -ETIMEDOUT; return -ETIMEDOUT; } } if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, WM2000_STATUS_BOOT_COMPLETE)) { WM2000_STATUS_BOOT_COMPLETE)) { dev_err(&i2c->dev, "ANC engine failed to initialise\n"); dev_err(&i2c->dev, "ANC engine failed to initialise\n"); regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); return -ETIMEDOUT; return -ETIMEDOUT; } } Loading @@ -163,11 +182,13 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) wm2000->anc_download_size); wm2000->anc_download_size); if (ret < 0) { if (ret < 0) { dev_err(&i2c->dev, "i2c_transfer() failed: %d\n", ret); dev_err(&i2c->dev, "i2c_transfer() failed: %d\n", ret); regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); return ret; return ret; } } if (ret != wm2000->anc_download_size) { if (ret != wm2000->anc_download_size) { dev_err(&i2c->dev, "i2c_transfer() failed, %d != %d\n", dev_err(&i2c->dev, "i2c_transfer() failed, %d != %d\n", ret, wm2000->anc_download_size); ret, wm2000->anc_download_size); regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); return -EIO; return -EIO; } } Loading Loading @@ -201,6 +222,7 @@ static int wm2000_power_up(struct i2c_client *i2c, int analogue) if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS, WM2000_STATUS_MOUSE_ACTIVE)) { WM2000_STATUS_MOUSE_ACTIVE)) { dev_err(&i2c->dev, "Timed out waiting for device\n"); dev_err(&i2c->dev, "Timed out waiting for device\n"); regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); return -ETIMEDOUT; return -ETIMEDOUT; } } Loading Loading @@ -238,6 +260,8 @@ static int wm2000_power_down(struct i2c_client *i2c, int analogue) return -ETIMEDOUT; return -ETIMEDOUT; } } regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); dev_dbg(&i2c->dev, "powered off\n"); dev_dbg(&i2c->dev, "powered off\n"); wm2000->anc_mode = ANC_OFF; wm2000->anc_mode = ANC_OFF; Loading Loading @@ -747,7 +771,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, struct wm2000_platform_data *pdata; struct wm2000_platform_data *pdata; const char *filename; const char *filename; const struct firmware *fw = NULL; const struct firmware *fw = NULL; int ret; int ret, i; int reg; int reg; u16 id; u16 id; Loading @@ -768,6 +792,22 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, goto out; goto out; } } for (i = 0; i < WM2000_NUM_SUPPLIES; i++) wm2000->supplies[i].supply = wm2000_supplies[i]; ret = devm_regulator_bulk_get(&i2c->dev, WM2000_NUM_SUPPLIES, wm2000->supplies); if (ret != 0) { dev_err(&i2c->dev, "Failed to get supplies: %d\n", ret); return ret; } ret = regulator_bulk_enable(WM2000_NUM_SUPPLIES, wm2000->supplies); if (ret != 0) { dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); return ret; } /* Verify that this is a WM2000 */ /* Verify that this is a WM2000 */ reg = wm2000_read(i2c, WM2000_REG_ID1); reg = wm2000_read(i2c, WM2000_REG_ID1); id = reg << 8; id = reg << 8; Loading @@ -777,7 +817,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, if (id != 0x2000) { if (id != 0x2000) { dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id); dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id); ret = -ENODEV; ret = -ENODEV; goto out; goto err_supplies; } } reg = wm2000_read(i2c, WM2000_REG_REVISON); reg = wm2000_read(i2c, WM2000_REG_REVISON); Loading @@ -796,7 +836,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, ret = request_firmware(&fw, filename, &i2c->dev); ret = request_firmware(&fw, filename, &i2c->dev); if (ret != 0) { if (ret != 0) { dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); goto out; goto err_supplies; } } /* Pre-cook the concatenation of the register address onto the image */ /* Pre-cook the concatenation of the register address onto the image */ Loading @@ -807,7 +847,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, if (wm2000->anc_download == NULL) { if (wm2000->anc_download == NULL) { dev_err(&i2c->dev, "Out of memory\n"); dev_err(&i2c->dev, "Out of memory\n"); ret = -ENOMEM; ret = -ENOMEM; goto out; goto err_supplies; } } wm2000->anc_download[0] = 0x80; wm2000->anc_download[0] = 0x80; Loading @@ -822,8 +862,9 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, wm2000_reset(wm2000); wm2000_reset(wm2000); ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0); ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0); if (!ret) goto out; err_supplies: regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); out: out: release_firmware(fw); release_firmware(fw); Loading