diff options
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/wcd9xxx-core.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c index c521eff89abb..ddd92aa57dd5 100644 --- a/drivers/mfd/wcd9xxx-core.c +++ b/drivers/mfd/wcd9xxx-core.c @@ -1074,15 +1074,22 @@ static const struct wcd9xxx_codec_type wcd9xxx_codecs[] = { }, }; -static void wcd9335_bring_up(struct wcd9xxx *wcd9xxx) +static int wcd9335_bring_up(struct wcd9xxx *wcd9xxx) { int val, byte0; + int ret = 0; val = __wcd9xxx_reg_read(wcd9xxx, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0); byte0 = __wcd9xxx_reg_read(wcd9xxx, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0); + if ((val < 0) || (byte0 < 0)) { + dev_err(wcd9xxx->dev, "%s: tasha codec version detection fail!\n", + __func__); + return -EINVAL; + } + if ((val & 0x80) && (byte0 == 0x0)) { dev_info(wcd9xxx->dev, "%s: wcd9335 codec version is v1.1\n", __func__); @@ -1110,7 +1117,7 @@ static void wcd9335_bring_up(struct wcd9xxx *wcd9xxx) __wcd9xxx_reg_write(wcd9xxx, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3); __wcd9xxx_reg_write(wcd9xxx, WCD9335_CODEC_RPM_RST_CTL, 0x3); - } else { + } else if ((byte0 == 0) && (!(val & 0x80))) { dev_info(wcd9xxx->dev, "%s: wcd9335 codec version is v1.0\n", __func__); __wcd9xxx_reg_write(wcd9xxx, WCD9335_CODEC_RPM_RST_CTL, 0x01); @@ -1119,7 +1126,13 @@ static void wcd9335_bring_up(struct wcd9xxx *wcd9xxx) __wcd9xxx_reg_write(wcd9xxx, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3); __wcd9xxx_reg_write(wcd9xxx, WCD9335_CODEC_RPM_RST_CTL, 0x3); + } else { + dev_err(wcd9xxx->dev, "%s: tasha codec version unknown\n", + __func__); + ret = -EINVAL; } + + return ret; } static void wcd9335_bring_down(struct wcd9xxx *wcd9xxx) @@ -1128,12 +1141,14 @@ static void wcd9335_bring_down(struct wcd9xxx *wcd9xxx) WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x4); } -static void wcd9xxx_bring_up(struct wcd9xxx *wcd9xxx) +static int wcd9xxx_bring_up(struct wcd9xxx *wcd9xxx) { + int ret = 0; + pr_debug("%s: Codec Type: %d\n", __func__, wcd9xxx->type); if (wcd9xxx->type == WCD9335) { - wcd9335_bring_up(wcd9xxx); + ret = wcd9335_bring_up(wcd9xxx); } else if (wcd9xxx->type == WCD9330) { __wcd9xxx_reg_write(wcd9xxx, WCD9330_A_LEAKAGE_CTL, 0x4); __wcd9xxx_reg_write(wcd9xxx, WCD9330_A_CDC_CTL, 0); @@ -1149,6 +1164,8 @@ static void wcd9xxx_bring_up(struct wcd9xxx *wcd9xxx) __wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_CDC_CTL, 3); __wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 3); } + + return ret; } static void wcd9xxx_bring_down(struct wcd9xxx *wcd9xxx) @@ -1575,7 +1592,11 @@ static int wcd9xxx_device_init(struct wcd9xxx *wcd9xxx) mutex_init(&wcd9xxx->xfer_lock); dev_set_drvdata(wcd9xxx->dev, wcd9xxx); - wcd9xxx_bring_up(wcd9xxx); + ret = wcd9xxx_bring_up(wcd9xxx); + if (ret) { + ret = -EPROBE_DEFER; + goto err_bring_up; + } found = wcd9xxx_check_codec_type(wcd9xxx, &version); if (!found) { @@ -1652,6 +1673,7 @@ err_irq: err: wcd9xxx_bring_down(wcd9xxx); wcd9xxx_core_res_deinit(&wcd9xxx->core_res); +err_bring_up: mutex_destroy(&wcd9xxx->io_lock); mutex_destroy(&wcd9xxx->xfer_lock); return ret; @@ -2325,8 +2347,8 @@ static int wcd9xxx_i2c_probe(struct i2c_client *client, ret = wcd9xxx_device_init(wcd9xxx); if (ret) { - pr_err("%s: error, initializing device failed\n", - __func__); + pr_err("%s: error, initializing device failed (%d)\n", + __func__, ret); goto err_device_init; } @@ -3016,6 +3038,7 @@ static int wcd9xxx_slim_probe(struct slim_device *slim) if (ret) { pr_err("%s: failed to get slimbus %s logical address: %d\n", __func__, wcd9xxx->slim->name, ret); + ret = -EPROBE_DEFER; goto err_reset; } wcd9xxx->read_dev = wcd9xxx_slim_read_device; @@ -3039,6 +3062,7 @@ static int wcd9xxx_slim_probe(struct slim_device *slim) if (ret) { pr_err("%s: failed to get slimbus %s logical address: %d\n", __func__, wcd9xxx->slim->name, ret); + ret = -EPROBE_DEFER; goto err_slim_add; } wcd9xxx_inf_la = wcd9xxx->slim_slave->laddr; @@ -3046,7 +3070,8 @@ static int wcd9xxx_slim_probe(struct slim_device *slim) ret = wcd9xxx_device_init(wcd9xxx); if (ret) { - pr_err("%s: error, initializing device failed\n", __func__); + pr_err("%s: error, initializing device failed (%d)\n", + __func__, ret); goto err_slim_add; } #ifdef CONFIG_DEBUG_FS |