static int wm2000_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *i2c_id) { struct wm2000_priv *wm2000; struct wm2000_platform_data *pdata; const char *filename; const struct firmware *fw = NULL; int ret, i; int reg; u16 id; wm2000 = devm_kzalloc(&i2c->dev, sizeof(struct wm2000_priv), GFP_KERNEL); if (wm2000 == NULL) { dev_err(&i2c->dev, "Unable to allocate private data\n"); return -ENOMEM; } mutex_init(&wm2000->lock); dev_set_drvdata(&i2c->dev, wm2000); wm2000->regmap = devm_regmap_init_i2c(i2c, &wm2000_regmap); if (IS_ERR(wm2000->regmap)) { ret = PTR_ERR(wm2000->regmap); dev_err(&i2c->dev, "Failed to allocate register map: %d\n", ret); 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 */ reg = wm2000_read(i2c, WM2000_REG_ID1); id = reg << 8; reg = wm2000_read(i2c, WM2000_REG_ID2); id |= reg & 0xff; if (id != 0x2000) { dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id); ret = -ENODEV; goto err_supplies; } reg = wm2000_read(i2c, WM2000_REG_REVISON); dev_info(&i2c->dev, "revision %c\n", reg + 'A'); wm2000->mclk = devm_clk_get(&i2c->dev, "MCLK"); if (IS_ERR(wm2000->mclk)) { ret = PTR_ERR(wm2000->mclk); dev_err(&i2c->dev, "Failed to get MCLK: %d\n", ret); goto err_supplies; } filename = "/*(DEBLOBBED)*/"; pdata = dev_get_platdata(&i2c->dev); if (pdata) { wm2000->speech_clarity = !pdata->speech_enh_disable; if (pdata->download_file) filename = pdata->download_file; } ret = reject_firmware(&fw, filename, &i2c->dev); if (ret != 0) { dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); goto err_supplies; } /* Pre-cook the concatenation of the register address onto the image */ wm2000->anc_download_size = fw->size + 2; wm2000->anc_download = devm_kzalloc(&i2c->dev, wm2000->anc_download_size, GFP_KERNEL); if (wm2000->anc_download == NULL) { dev_err(&i2c->dev, "Out of memory\n"); ret = -ENOMEM; goto err_supplies; } wm2000->anc_download[0] = 0x80; wm2000->anc_download[1] = 0x00; memcpy(wm2000->anc_download + 2, fw->data, fw->size); wm2000->anc_eng_ena = 1; wm2000->anc_active = 1; wm2000->spk_ena = 1; wm2000->i2c = i2c; wm2000_reset(wm2000); ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0); err_supplies: regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies); out: release_firmware(fw); return ret; }
static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *i2c_id) { struct wm2000_priv *wm2000; struct wm2000_platform_data *pdata; const char *filename; const struct firmware *fw = NULL; int ret; int reg; u16 id; wm2000 = devm_kzalloc(&i2c->dev, sizeof(struct wm2000_priv), GFP_KERNEL); if (wm2000 == NULL) { dev_err(&i2c->dev, "Unable to allocate private data\n"); return -ENOMEM; } dev_set_drvdata(&i2c->dev, wm2000); wm2000->regmap = regmap_init_i2c(i2c, &wm2000_regmap); if (IS_ERR(wm2000->regmap)) { ret = PTR_ERR(wm2000->regmap); dev_err(&i2c->dev, "Failed to allocate register map: %d\n", ret); goto out; } /* Verify that this is a WM2000 */ reg = wm2000_read(i2c, WM2000_REG_ID1); id = reg << 8; reg = wm2000_read(i2c, WM2000_REG_ID2); id |= reg & 0xff; if (id != 0x2000) { dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id); ret = -ENODEV; goto out_regmap_exit; } reg = wm2000_read(i2c, WM2000_REG_REVISON); dev_info(&i2c->dev, "revision %c\n", reg + 'A'); filename = "wm2000_anc.bin"; pdata = dev_get_platdata(&i2c->dev); if (pdata) { wm2000->mclk_div = pdata->mclkdiv2; wm2000->speech_clarity = !pdata->speech_enh_disable; if (pdata->download_file) filename = pdata->download_file; } ret = request_firmware(&fw, filename, &i2c->dev); if (ret != 0) { dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); goto out_regmap_exit; } /* Pre-cook the concatenation of the register address onto the image */ wm2000->anc_download_size = fw->size + 2; wm2000->anc_download = devm_kzalloc(&i2c->dev, wm2000->anc_download_size, GFP_KERNEL); if (wm2000->anc_download == NULL) { dev_err(&i2c->dev, "Out of memory\n"); ret = -ENOMEM; goto out_regmap_exit; } wm2000->anc_download[0] = 0x80; wm2000->anc_download[1] = 0x00; memcpy(wm2000->anc_download + 2, fw->data, fw->size); wm2000->anc_eng_ena = 1; wm2000->anc_active = 1; wm2000->spk_ena = 1; wm2000->i2c = i2c; wm2000_reset(wm2000); ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0); if (!ret) goto out; out_regmap_exit: regmap_exit(wm2000->regmap); out: release_firmware(fw); return ret; }
static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *i2c_id) { struct wm2000_priv *wm2000; struct wm2000_platform_data *pdata; const char *filename; const struct firmware *fw = NULL; int ret; int reg; u16 id; #ifdef WM2000_GPIO_ENABLE wm2000_gpio_request(); #endif wm2000 = devm_kzalloc(&i2c->dev, sizeof(struct wm2000_priv), GFP_KERNEL); if (wm2000 == NULL) { dev_err(&i2c->dev, "Unable to allocate private data\n"); return -ENOMEM; } dev_set_drvdata(&i2c->dev, wm2000); mutex_init(&wm2000->anc_lock); wm2000->regmap = regmap_init_i2c(i2c, &wm2000_regmap); if (IS_ERR(wm2000->regmap)) { ret = PTR_ERR(wm2000->regmap); dev_err(&i2c->dev, "Failed to allocate register map: %d\n", ret); goto err; } /* when the system reboot, the power supply of wm2000 is always supplied, * so there is the bug solution below, powerdown and powerup the module before * probed! */ ret=wm2000_write(i2c, WM2000_REG_SYS_CTL1, 0); ret=wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, 1); ret=wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL, WM2000_MODE_ANA_SEQ_INCLUDE | WM2000_MODE_THERMAL_ENABLE | WM2000_MODE_MOUSE_ENABLE); /* Verify that this is a WM2000 */ reg = wm2000_read(i2c, WM2000_REG_ID1); id = reg << 8; reg = wm2000_read(i2c, WM2000_REG_ID2); id |= reg & 0xff; if (id != 0x2000) { dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id); wm2000_id = 0; ret = -ENODEV; goto out_regmap_exit; } else wm2000_id = 2000; printk("wm2000_id = 0x%x\n", id); reg = wm2000_read(i2c, WM2000_REG_REVISON); dev_info(&i2c->dev, "revision %c\n", reg + 'A'); filename = "wm2000_anc.bin"; pdata = dev_get_platdata(&i2c->dev); wm2000->mclk_div = 1; wm2000->speech_clarity = 0; if (pdata) { wm2000->mclk_div = pdata->mclkdiv2; wm2000->speech_clarity = !pdata->speech_enh_disable; if (pdata->download_file) filename = pdata->download_file; } ret = request_firmware(&fw, filename, &i2c->dev); if (ret != 0) { dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); goto out; } /* Pre-cook the concatenation of the register address onto the image */ wm2000->anc_download_size = fw->size + 2; wm2000->anc_download = devm_kzalloc(&i2c->dev, wm2000->anc_download_size, GFP_KERNEL); if (wm2000->anc_download == NULL) { dev_err(&i2c->dev, "Out of memory\n"); ret = -ENOMEM; goto out; } wm2000->anc_download[0] = 0x80; wm2000->anc_download[1] = 0x00; memcpy(wm2000->anc_download + 2, fw->data, fw->size); wm2000->anc_eng_ena = 0; wm2000->anc_active = 0; wm2000->spk_ena = 1; wm2000->incall_mode =0; wm2000->i2c = i2c; wm2000_reset(wm2000); ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0); if (!ret) { release_firmware(fw); return ret; } out: release_firmware(fw); out_regmap_exit: regmap_exit(wm2000->regmap); err: devm_kfree(&i2c->dev, wm2000); return ret; }