summaryrefslogtreecommitdiff
path: root/drivers/mfd
diff options
context:
space:
mode:
authorPhani Kumar Uppalapati <phaniu@codeaurora.org>2016-02-01 13:09:08 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-25 16:02:34 -0700
commit4aaf0c05a5b197420168e1499363a0f178c163d2 (patch)
treebaee484b26ac2329a2502374412c4d2fa8569182 /drivers/mfd
parent92881d2eded54ab9f7f4b3a1a0a26d584d4042b2 (diff)
drivers: mfd: Return EPROBE_DEFER during codec failure
In case of any codec access failure, return -EPROBE_DEFER so that slimbus driver can probe the codec again to toggle codec reset and retry codec access. CRs-fixed: 969497 Change-Id: I570e7357a6d7810c495f56bbb626b8e823892837 Signed-off-by: Phani Kumar Uppalapati <phaniu@codeaurora.org>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/wcd9xxx-core.c41
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