diff mbox series

[03/14] Add the i2c-retry count and callback function in regmap function.

Message ID 20230106091543.2440-4-kiseok.jo@irondevice.com (mailing list archive)
State New, archived
Headers show
Series ASoC: Add a driver the Iron Device SMA1303 AMP | expand

Commit Message

Ki-Seok Jo Jan. 6, 2023, 9:15 a.m. UTC
Signed-off-by: Kiseok Jo <kiseok.jo@irondevice.com>
Reported-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/codecs/sma1303.c | 261 ++++++++++++++++++++-----------------
 sound/soc/codecs/sma1303.h |   9 ++
 2 files changed, 147 insertions(+), 123 deletions(-)
diff mbox series

Patch

diff --git a/sound/soc/codecs/sma1303.c b/sound/soc/codecs/sma1303.c
index 50b471920fc8..8bd59a481f2d 100644
--- a/sound/soc/codecs/sma1303.c
+++ b/sound/soc/codecs/sma1303.c
@@ -47,6 +47,8 @@  enum sma1303_type {
 	SMA1303,
 };
 
+struct callback_ops gCallback;
+
 struct sma1303_pll_match {
 	char *input_clk_name;
 	char *output_clk_name;
@@ -69,6 +71,7 @@  struct sma1303_priv {
 	bool amp_power_status;
 	bool usage_status;
 	int num_of_pll_matches;
+	int retry_cnt;
 	unsigned int sys_clk_id;
 	unsigned int init_vol;
 	unsigned int cur_vol;
@@ -233,28 +236,66 @@  static bool sma1303_volatile_register(struct device *dev, unsigned int reg)
 
 static const DECLARE_TLV_DB_SCALE(sma1303_spk_tlv, -6000, 50, 0);
 
-static int sma1303_regmap_write(struct regmap *map, struct device *dev,
+void sma1303_set_callback_func(struct callback_ops ops)
+{
+	if (ops.set_i2c_err)
+		gCallback.set_i2c_err = ops.set_i2c_err;
+}
+EXPORT_SYMBOL(sma1303_set_callback_func);
+
+static int sma1303_regmap_write(struct sma1303_priv *sma1303,
 				unsigned int reg, unsigned int val)
 {
 	int ret = 0;
+	int cnt = sma1303->retry_cnt;
 
-	ret = regmap_write(map, reg, val);
-	if (ret < 0) {
-		dev_err(dev, "Failed to write, register: 0x%02X, ret: %d\n",
-			       reg, ret);
+	while (cnt--) {
+		ret = regmap_write(sma1303->regmap, reg, val);
+		if (ret < 0) {
+			dev_err(sma1303->dev,
+					"Failed to write [0x%02X]\n", reg);
+			if (gCallback.set_i2c_err)
+				gCallback.set_i2c_err(sma1303->dev, ret);
+		} else
+			break;
 	}
 	return ret;
 }
 
-static int sma1303_regmap_update_bits(struct regmap *map, struct device *dev,
+static int sma1303_regmap_update_bits(struct sma1303_priv *sma1303,
 		unsigned int reg, unsigned int mask, unsigned int val)
 {
 	int ret = 0;
+	int cnt = sma1303->retry_cnt;
 
-	ret = regmap_update_bits(map, reg, mask, val);
-	if (ret < 0) {
-		dev_err(dev, "Failed to write, register: 0x%02X, ret: %d\n",
-			       reg, ret);
+	while (cnt--) {
+		ret = regmap_update_bits(sma1303->regmap, reg, mask, val);
+		if (ret < 0) {
+			dev_err(sma1303->dev,
+					"Failed to update [0x%02X]\n", reg);
+			if (gCallback.set_i2c_err)
+				gCallback.set_i2c_err(sma1303->dev, ret);
+		} else
+			break;
+	}
+	return ret;
+}
+
+static int sma1303_regmap_read(struct sma1303_priv *sma1303,
+			unsigned int reg, unsigned int *val)
+{
+	int ret;
+	int cnt = sma1303->retry_cnt;
+
+	while (cnt--) {
+		ret = regmap_read(sma1303->regmap, reg, val);
+		if (ret < 0) {
+			dev_err(sma1303->dev,
+					"Failed to read [0x%02X]\n", reg);
+			if (gCallback.set_i2c_err)
+				gCallback.set_i2c_err(sma1303->dev, ret);
+		} else
+			break;
 	}
 	return ret;
 }
@@ -280,7 +321,7 @@  static int bytes_ext_get(struct snd_kcontrol *kcontrol,
 	}
 	val = (u8 *)ucontrol->value.bytes.data;
 	for (i = 0; i < params->max; i++) {
-		ret = regmap_read(sma1303->regmap, reg + i, &reg_val);
+		ret = sma1303_regmap_read(sma1303, reg + i, &reg_val);
 		if (ret < 0) {
 			dev_err(component->dev,
 				"Failed to read, register: %x ret: %d\n",
@@ -323,9 +364,7 @@  static int bytes_ext_put(struct snd_kcontrol *kcontrol,
 
 	val = (u8 *)data;
 	for (i = 0; i < params->max; i++) {
-		ret = sma1303_regmap_write(
-				sma1303->regmap, component->dev,
-				reg + i, *(val + i));
+		ret = sma1303_regmap_write(sma1303, reg + i, *(val + i));
 		if (ret < 0) {
 			kfree(data);
 			return ret;
@@ -463,32 +502,26 @@  static int sma1303_amp_mode_put(struct snd_kcontrol *kcontrol,
 	switch (sma1303->amp_mode) {
 	case ONE_CHIP_SOLUTION:
 	case MONO_TWO_CHIP_SOLUTION:
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_11_SYSTEM_CTRL2,
 				MONOMIX_MASK, MONOMIX_ON);
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_11_SYSTEM_CTRL2,
 				LR_DATA_SW_MASK, LR_DATA_SW_NORMAL);
 		break;
 	case LEFT_TWO_CHIP_SOLUTION:
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_11_SYSTEM_CTRL2,
 				MONOMIX_MASK, MONOMIX_OFF);
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_11_SYSTEM_CTRL2,
 				LR_DATA_SW_MASK, LR_DATA_SW_NORMAL);
 		break;
 	case RIGHT_TWO_CHIP_SOLUTION:
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_11_SYSTEM_CTRL2,
 				MONOMIX_MASK, MONOMIX_OFF);
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_11_SYSTEM_CTRL2,
 				LR_DATA_SW_MASK, LR_DATA_SW_SWAP);
 		break;
@@ -524,7 +557,7 @@  static int sma1303_outport_config_get(struct snd_kcontrol *kcontrol,
 		return ret;
 	}
 
-	ret = regmap_read(sma1303->regmap, SMA1303_09_OUTPUT_CTRL, &data);
+	ret = sma1303_regmap_read(sma1303, SMA1303_09_OUTPUT_CTRL, &data);
 	if (ret < 0) {
 		dev_err(component->dev,
 			"Failed to read, register: %x ret: %d\n",
@@ -582,7 +615,7 @@  static int sma1303_outport_config_put(struct snd_kcontrol *kcontrol,
 		return ret;
 	}
 
-	return sma1303_regmap_update_bits(sma1303->regmap, component->dev,
+	return sma1303_regmap_update_bits(sma1303,
 			SMA1303_09_OUTPUT_CTRL, PORT_CONFIG_MASK, val);
 }
 
@@ -618,7 +651,7 @@  static int sma1303_spkmode_get(struct snd_kcontrol *kcontrol,
 		return ret;
 	}
 
-	ret = regmap_read(sma1303->regmap, SMA1303_10_SYSTEM_CTRL1, &data);
+	ret = sma1303_regmap_read(sma1303, SMA1303_10_SYSTEM_CTRL1, &data);
 	if (ret < 0) {
 		dev_err(component->dev,
 			"Failed to read, register: %x ret: %d\n",
@@ -695,7 +728,7 @@  static int sma1303_spkmode_put(struct snd_kcontrol *kcontrol,
 		return ret;
 	}
 
-	return sma1303_regmap_update_bits(sma1303->regmap, component->dev,
+	return sma1303_regmap_update_bits(sma1303,
 			SMA1303_10_SYSTEM_CTRL1, SPK_MODE_MASK, val);
 }
 
@@ -735,7 +768,7 @@  static int sma1303_postscaler_config_get(struct snd_kcontrol *kcontrol,
 		return ret;
 	}
 
-	ret = regmap_read(sma1303->regmap, SMA1303_90_POSTSCALER, &data);
+	ret = sma1303_regmap_read(sma1303, SMA1303_90_POSTSCALER, &data);
 	if (ret < 0) {
 		dev_err(component->dev,
 			"Failed to read, register: %x ret: %d\n",
@@ -793,7 +826,7 @@  static int sma1303_postscaler_config_put(struct snd_kcontrol *kcontrol,
 		return ret;
 	}
 
-	return sma1303_regmap_update_bits(sma1303->regmap, component->dev,
+	return sma1303_regmap_update_bits(sma1303,
 			SMA1303_90_POSTSCALER, BYP_POST_MASK, val);
 }
 
@@ -820,7 +853,7 @@  static int sma1303_o_format_get(struct snd_kcontrol *kcontrol,
 		return ret;
 	}
 
-	ret = regmap_read(sma1303->regmap, SMA1303_A4_TOP_MAN3, &data);
+	ret = sma1303_regmap_read(sma1303, SMA1303_A4_TOP_MAN3, &data);
 	val = data & O_FORMAT_MASK;
 	switch (val) {
 	case O_FMT_LJ:
@@ -876,7 +909,7 @@  static int sma1303_o_format_put(struct snd_kcontrol *kcontrol,
 		return ret;
 	}
 
-	return sma1303_regmap_update_bits(sma1303->regmap, component->dev,
+	return sma1303_regmap_update_bits(sma1303,
 			SMA1303_A4_TOP_MAN3, O_FORMAT_MASK, val);
 }
 
@@ -927,17 +960,17 @@  static int sma1303_startup(struct snd_soc_component *component)
 		return ret;
 	}
 
-	ret += sma1303_regmap_update_bits(sma1303->regmap, component->dev,
+	ret += sma1303_regmap_update_bits(sma1303,
 			SMA1303_8E_PLL_CTRL, PLL_PD2_MASK, PLL_OPERATION2);
 
-	ret += sma1303_regmap_update_bits(sma1303->regmap, component->dev,
+	ret += sma1303_regmap_update_bits(sma1303,
 			SMA1303_00_SYSTEM_CTRL, POWER_MASK, POWER_ON);
 
 	if (sma1303->amp_mode == ONE_CHIP_SOLUTION)
-		ret += sma1303_regmap_update_bits(sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 			SMA1303_10_SYSTEM_CTRL1, SPK_MODE_MASK, SPK_MONO);
 	else
-		ret += sma1303_regmap_update_bits(sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 			SMA1303_10_SYSTEM_CTRL1, SPK_MODE_MASK, SPK_STEREO);
 
 	if (sma1303->check_fault_status) {
@@ -951,7 +984,7 @@  static int sma1303_startup(struct snd_soc_component *component)
 					CHECK_PERIOD_TIME * HZ);
 	}
 
-	ret += sma1303_regmap_update_bits(sma1303->regmap, component->dev,
+	ret += sma1303_regmap_update_bits(sma1303,
 			SMA1303_0E_MUTE_VOL_CTRL, SPK_MUTE_MASK, SPK_UNMUTE);
 
 	sma1303->amp_power_status = true;
@@ -970,20 +1003,20 @@  static int sma1303_shutdown(struct snd_soc_component *component)
 		return ret;
 	}
 
-	ret += sma1303_regmap_update_bits(sma1303->regmap, component->dev,
+	ret += sma1303_regmap_update_bits(sma1303,
 			SMA1303_0E_MUTE_VOL_CTRL, SPK_MUTE_MASK, SPK_MUTE);
 
 	cancel_delayed_work_sync(&sma1303->check_fault_work);
 
 	msleep(55);
 
-	ret += sma1303_regmap_update_bits(sma1303->regmap, component->dev,
+	ret += sma1303_regmap_update_bits(sma1303,
 			SMA1303_10_SYSTEM_CTRL1, SPK_MODE_MASK, SPK_OFF);
 
-	ret += sma1303_regmap_update_bits(sma1303->regmap, component->dev,
+	ret += sma1303_regmap_update_bits(sma1303,
 			SMA1303_00_SYSTEM_CTRL, POWER_MASK, POWER_OFF);
 
-	ret += sma1303_regmap_update_bits(sma1303->regmap, component->dev,
+	ret += sma1303_regmap_update_bits(sma1303,
 			SMA1303_8E_PLL_CTRL, PLL_PD2_MASK, PLL_PD2);
 
 	sma1303->amp_power_status = false;
@@ -1059,14 +1092,12 @@  static int sma1303_dac_feedback_event(struct snd_soc_dapm_widget *w,
 	case SND_SOC_DAPM_PRE_PMU:
 		dev_info(component->dev,
 				"%s : DAC feedback ON\n", __func__);
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_09_OUTPUT_CTRL,
 				PORT_CONFIG_MASK|PORT_OUT_SEL_MASK,
 				OUTPUT_PORT_ENABLE|SPEAKER_PATH);
 
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_A3_TOP_MAN2,
 				SDO_OUTPUT_MASK, NORMAL_OUT);
 		break;
@@ -1074,13 +1105,11 @@  static int sma1303_dac_feedback_event(struct snd_soc_dapm_widget *w,
 	case SND_SOC_DAPM_PRE_PMD:
 		dev_info(component->dev,
 				"%s : DAC feedback OFF\n", __func__);
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_09_OUTPUT_CTRL,
 				PORT_OUT_SEL_MASK, OUT_SEL_DISABLE);
 
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_A3_TOP_MAN2, SDO_OUTPUT_MASK,
 				HIGH_Z_OUT);
 		break;
@@ -1138,26 +1167,25 @@  static int sma1303_setup_pll(struct snd_soc_component *component,
 			return -EINVAL;
 		}
 
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_A2_TOP_MAN1,
 				PLL_PD_MASK|PLL_REF_CLK_MASK,
 				PLL_OPERATION|PLL_SCK);
 	}
 
-	ret += sma1303_regmap_write(sma1303->regmap, component->dev,
+	ret += sma1303_regmap_write(sma1303,
 			SMA1303_8B_PLL_POST_N,
 			sma1303->pll_matches[i].post_n);
 
-	ret += sma1303_regmap_write(sma1303->regmap, component->dev,
+	ret += sma1303_regmap_write(sma1303,
 			SMA1303_8C_PLL_N,
 			sma1303->pll_matches[i].n);
 
-	ret += sma1303_regmap_write(sma1303->regmap, component->dev,
+	ret += sma1303_regmap_write(sma1303,
 			SMA1303_8D_PLL_A_SETTING,
 			sma1303->pll_matches[i].vco);
 
-	ret += sma1303_regmap_write(sma1303->regmap, component->dev,
+	ret += sma1303_regmap_write(sma1303,
 			SMA1303_8F_PLL_P_CP,
 			sma1303->pll_matches[i].p_cp);
 
@@ -1211,25 +1239,21 @@  static int sma1303_dai_hw_params_amp(struct snd_pcm_substream *substream,
 		case 44100:
 		case 48000:
 		case 96000:
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_A2_TOP_MAN1,
 				DAC_DN_CONV_MASK, DAC_DN_CONV_DISABLE);
 
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_01_INPUT1_CTRL1,
 				LEFTPOL_MASK, LOW_FIRST_CH);
 		break;
 
 		case 192000:
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_A2_TOP_MAN1,
 				DAC_DN_CONV_MASK, DAC_DN_CONV_ENABLE);
 
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_01_INPUT1_CTRL1,
 				LEFTPOL_MASK, HIGH_FIRST_CH);
 		break;
@@ -1249,8 +1273,7 @@  static int sma1303_dai_hw_params_amp(struct snd_pcm_substream *substream,
 			dev_info(component->dev,
 				"%s set format SNDRV_PCM_FORMAT_S16_LE\n",
 				__func__);
-			ret += sma1303_regmap_update_bits(
-					sma1303->regmap, component->dev,
+			ret += sma1303_regmap_update_bits(sma1303,
 					SMA1303_A4_TOP_MAN3,
 					SCK_RATE_MASK, SCK_32FS);
 			break;
@@ -1259,8 +1282,7 @@  static int sma1303_dai_hw_params_amp(struct snd_pcm_substream *substream,
 			dev_info(component->dev,
 				"%s set format SNDRV_PCM_FORMAT_S24_LE\n",
 				__func__);
-			ret += sma1303_regmap_update_bits(
-					sma1303->regmap, component->dev,
+			ret += sma1303_regmap_update_bits(sma1303,
 					SMA1303_A4_TOP_MAN3,
 					SCK_RATE_MASK, SCK_64FS);
 			break;
@@ -1268,8 +1290,7 @@  static int sma1303_dai_hw_params_amp(struct snd_pcm_substream *substream,
 			dev_info(component->dev,
 				"%s set format SNDRV_PCM_FORMAT_S32_LE\n",
 				__func__);
-			ret += sma1303_regmap_update_bits(
-					sma1303->regmap, component->dev,
+			ret += sma1303_regmap_update_bits(sma1303,
 					SMA1303_A4_TOP_MAN3,
 					SCK_RATE_MASK, SCK_64FS);
 			break;
@@ -1317,8 +1338,7 @@  static int sma1303_dai_hw_params_amp(struct snd_pcm_substream *substream,
 		return -EINVAL;
 	}
 
-	ret += sma1303_regmap_update_bits(
-			sma1303->regmap, component->dev,
+	ret += sma1303_regmap_update_bits(sma1303,
 			SMA1303_01_INPUT1_CTRL1,
 			I2S_MODE_MASK, input_format);
 	return ret;
@@ -1365,15 +1385,13 @@  static int sma1303_dai_mute(struct snd_soc_dai *dai, int mute, int stream)
 	if (mute) {
 		dev_info(component->dev, "%s : %s\n", __func__, "MUTE");
 
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_0E_MUTE_VOL_CTRL,
 				SPK_MUTE_MASK, SPK_MUTE);
 	} else {
 		dev_info(component->dev, "%s : %s\n", __func__, "UNMUTE");
 
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_0E_MUTE_VOL_CTRL,
 				SPK_MUTE_MASK, SPK_UNMUTE);
 	}
@@ -1393,8 +1411,7 @@  static int sma1303_dai_set_fmt_amp(struct snd_soc_dai *dai,
 	case SND_SOC_DAIFMT_CBS_CFS:
 		dev_info(component->dev,
 				"%s : %s\n", __func__, "I2S/TDM Device mode");
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_01_INPUT1_CTRL1,
 				CONTROLLER_DEVICE_MASK, DEVICE_MODE);
 		break;
@@ -1402,8 +1419,7 @@  static int sma1303_dai_set_fmt_amp(struct snd_soc_dai *dai,
 	case SND_SOC_DAIFMT_CBM_CFM:
 		dev_info(component->dev,
 			"%s : %s\n", __func__, "I2S/TDM Controller mode");
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_01_INPUT1_CTRL1,
 				CONTROLLER_DEVICE_MASK, CONTROLLER_MODE);
 		break;
@@ -1434,16 +1450,14 @@  static int sma1303_dai_set_fmt_amp(struct snd_soc_dai *dai,
 	case SND_SOC_DAIFMT_IB_NF:
 		dev_info(component->dev, "%s : %s\n",
 			__func__, "Invert BCLK + Normal Frame");
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_01_INPUT1_CTRL1,
 				SCK_RISING_MASK, SCK_RISING_EDGE);
 		break;
 	case SND_SOC_DAIFMT_IB_IF:
 		dev_info(component->dev, "%s : %s\n",
 			__func__, "Invert BCLK + Invert Frame");
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_01_INPUT1_CTRL1,
 				LEFTPOL_MASK|SCK_RISING_MASK,
 				HIGH_FIRST_CH|SCK_RISING_EDGE);
@@ -1451,8 +1465,7 @@  static int sma1303_dai_set_fmt_amp(struct snd_soc_dai *dai,
 	case SND_SOC_DAIFMT_NB_IF:
 		dev_info(component->dev, "%s : %s\n",
 			__func__, "Normal BCLK + Invert Frame");
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_01_INPUT1_CTRL1,
 				LEFTPOL_MASK, HIGH_FIRST_CH);
 		break;
@@ -1482,21 +1495,18 @@  static int sma1303_dai_set_tdm_slot(struct snd_soc_dai *dai,
 
 	sma1303->frame_size = slot_width * slots;
 
-	ret += sma1303_regmap_update_bits(
-			sma1303->regmap, component->dev,
+	ret += sma1303_regmap_update_bits(sma1303,
 			SMA1303_A4_TOP_MAN3,
 			O_FORMAT_MASK, O_FMT_TDM);
 
 	switch (slot_width) {
 	case 16:
-	ret += sma1303_regmap_update_bits(
-			sma1303->regmap, component->dev,
+	ret += sma1303_regmap_update_bits(sma1303,
 			SMA1303_A6_TDM2,
 			TDM_DL_MASK, TDM_DL_16);
 	break;
 	case 32:
-	ret += sma1303_regmap_update_bits(
-			sma1303->regmap, component->dev,
+	ret += sma1303_regmap_update_bits(sma1303,
 			SMA1303_A6_TDM2,
 			TDM_DL_MASK, TDM_DL_32);
 	break;
@@ -1507,14 +1517,12 @@  static int sma1303_dai_set_tdm_slot(struct snd_soc_dai *dai,
 
 	switch (slots) {
 	case 4:
-	ret += sma1303_regmap_update_bits(
-			sma1303->regmap, component->dev,
+	ret += sma1303_regmap_update_bits(sma1303,
 			SMA1303_A6_TDM2,
 			TDM_N_SLOT_MASK, TDM_N_SLOT_4);
 	break;
 	case 8:
-	ret += sma1303_regmap_update_bits(
-			sma1303->regmap, component->dev,
+	ret += sma1303_regmap_update_bits(sma1303,
 			SMA1303_A6_TDM2,
 			TDM_N_SLOT_MASK, TDM_N_SLOT_8);
 	break;
@@ -1524,27 +1532,23 @@  static int sma1303_dai_set_tdm_slot(struct snd_soc_dai *dai,
 	}
 
 	if (sma1303->tdm_slot_rx < slots)
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_A5_TDM1, TDM_SLOT1_RX_POS_MASK,
 				(sma1303->tdm_slot_rx) << 3);
 	else
 		dev_err(component->dev, "%s Incorrect tdm-slot-rx %d set\n",
 				__func__, sma1303->tdm_slot_rx);
 
-	ret += sma1303_regmap_update_bits(
-			sma1303->regmap, component->dev,
+	ret += sma1303_regmap_update_bits(sma1303,
 			SMA1303_A5_TDM1,
 			TDM_CLK_POL_MASK, TDM_CLK_POL_RISE);
 
-	ret += sma1303_regmap_update_bits(
-			sma1303->regmap, component->dev,
+	ret += sma1303_regmap_update_bits(sma1303,
 			SMA1303_A5_TDM1,
 			TDM_TX_MODE_MASK, TDM_TX_MONO);
 
 	if (sma1303->tdm_slot_tx < slots)
-		ret += sma1303_regmap_update_bits(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_update_bits(sma1303,
 				SMA1303_A6_TDM2, TDM_SLOT1_TX_POS_MASK,
 				(sma1303->tdm_slot_tx) << 3);
 	else
@@ -1598,10 +1602,10 @@  static void sma1303_check_fault_worker(struct work_struct *work)
 	mutex_lock(&sma1303->lock);
 
 	if (sma1303->tsdw_cnt)
-		ret = regmap_read(sma1303->regmap,
+		ret = sma1303_regmap_read(sma1303,
 			SMA1303_0A_SPK_VOL, &sma1303->cur_vol);
 	else
-		ret = regmap_read(sma1303->regmap,
+		ret = sma1303_regmap_read(sma1303,
 			SMA1303_0A_SPK_VOL, &sma1303->init_vol);
 
 	if (ret != 0) {
@@ -1611,7 +1615,7 @@  static void sma1303_check_fault_worker(struct work_struct *work)
 		return;
 	}
 
-	ret = regmap_read(sma1303->regmap, SMA1303_FA_STATUS1, &over_temp);
+	ret = sma1303_regmap_read(sma1303, SMA1303_FA_STATUS1, &over_temp);
 	if (ret != 0) {
 		dev_err(sma1303->dev,
 			"failed to read SMA1303_FA_STATUS1 : %d\n", ret);
@@ -1619,7 +1623,7 @@  static void sma1303_check_fault_worker(struct work_struct *work)
 		return;
 	}
 
-	ret = regmap_read(sma1303->regmap, SMA1303_FB_STATUS2, &ocp_val);
+	ret = sma1303_regmap_read(sma1303, SMA1303_FB_STATUS2, &ocp_val);
 	if (ret != 0) {
 		dev_err(sma1303->dev,
 			"failed to read SMA1303_FB_STATUS2 : %d\n", ret);
@@ -1627,7 +1631,7 @@  static void sma1303_check_fault_worker(struct work_struct *work)
 		return;
 	}
 
-	ret = regmap_read(sma1303->regmap, SMA1303_FF_DEVICE_INDEX, &uvlo_val);
+	ret = sma1303_regmap_read(sma1303, SMA1303_FF_DEVICE_INDEX, &uvlo_val);
 	if (ret != 0) {
 		dev_err(sma1303->dev,
 			"failed to read SMA1303_FF_DEVICE_INDEX : %d\n", ret);
@@ -1640,14 +1644,12 @@  static void sma1303_check_fault_worker(struct work_struct *work)
 			"%s : OT1(Over Temperature Level 1)\n", __func__);
 
 		if ((sma1303->cur_vol + 6) <= 0xFF)
-			sma1303_regmap_write(
-				sma1303->regmap, sma1303->dev,
+			sma1303_regmap_write(sma1303,
 				SMA1303_0A_SPK_VOL, sma1303->cur_vol + 6);
 
 		sma1303->tsdw_cnt++;
 	} else if (sma1303->tsdw_cnt) {
-		sma1303_regmap_write(
-				sma1303->regmap, sma1303->dev,
+		sma1303_regmap_write(sma1303,
 				SMA1303_0A_SPK_VOL, sma1303->init_vol);
 		sma1303->tsdw_cnt = 0;
 		sma1303->cur_vol = sma1303->init_vol;
@@ -1761,12 +1763,11 @@  static int sma1303_probe(struct snd_soc_component *component)
 
 	snd_soc_dapm_sync(dapm);
 
-	ret += sma1303_regmap_update_bits(
-			sma1303->regmap, component->dev,
+	ret += sma1303_regmap_update_bits(sma1303,
 			SMA1303_00_SYSTEM_CTRL,
 			RESETBYI2C_MASK, RESETBYI2C_RESET);
 
-	ret += regmap_read(sma1303->regmap, SMA1303_FF_DEVICE_INDEX, &status);
+	ret += sma1303_regmap_read(sma1303, SMA1303_FF_DEVICE_INDEX, &status);
 	if (ret < 0) {
 		dev_err(sma1303->dev,
 			"failed to read, register: %02X, ret: %d\n",
@@ -1779,7 +1780,7 @@  static int sma1303_probe(struct snd_soc_component *component)
 	else if (sma1303->rev_num == REV_NUM_TV1)
 		dev_info(component->dev, "SMA1303 Trimming Version 1\n");
 
-	ret += regmap_read(sma1303->regmap, SMA1303_FB_STATUS2, &otp_stat);
+	ret += sma1303_regmap_read(sma1303, SMA1303_FB_STATUS2, &otp_stat);
 	if (ret < 0)
 		dev_err(sma1303->dev,
 			"failed to read, register: %02X, ret: %d\n",
@@ -1794,12 +1795,11 @@  static int sma1303_probe(struct snd_soc_component *component)
 		dev_info(component->dev, "SMA1303 OTP Status Fail\n");
 
 	for (i = 0; i < (unsigned int)ARRAY_SIZE(sma1303_reg_def); i++)
-		ret += sma1303_regmap_write(
-				sma1303->regmap, component->dev,
+		ret += sma1303_regmap_write(sma1303,
 				sma1303_reg_def[i].reg,
 				sma1303_reg_def[i].def);
 
-	ret += sma1303_regmap_write(sma1303->regmap, component->dev,
+	ret += sma1303_regmap_write(sma1303,
 			SMA1303_0A_SPK_VOL, sma1303->init_vol);
 
 	dev_info(component->dev,
@@ -1949,6 +1949,21 @@  static int sma1303_i2c_probe(struct i2c_client *client,
 	}
 
 	if (np) {
+		if (!of_property_read_u32(np, "i2c-retry", &value)) {
+			if (value > 50 || value < 0) {
+				sma1303->retry_cnt = SMA1303_I2C_RETRY_COUNT;
+				dev_info(&client->dev, "%s : %s\n", __func__,
+					"i2c-retry out of range (up to 50)");
+			} else {
+				sma1303->retry_cnt = value;
+				dev_info(&client->dev, "%s : %s = %d\n",
+					__func__, "i2c-retry count", value);
+			}
+		} else {
+			dev_info(&client->dev, "%s : %s = %d\n", __func__,
+				"i2c-retry count", SMA1303_I2C_RETRY_COUNT);
+			sma1303->retry_cnt = SMA1303_I2C_RETRY_COUNT;
+		}
 		if (!of_property_read_u32(np, "tdm-slot-rx", &value)) {
 			dev_info(&client->dev,
 				"tdm slot rx is '%d' from DT\n", value);
@@ -1995,8 +2010,8 @@  static int sma1303_i2c_probe(struct i2c_client *client,
 		return -ENODEV;
 	}
 
-	ret = regmap_read(sma1303->regmap,
-		SMA1303_FF_DEVICE_INDEX, &device_info);
+	ret = sma1303_regmap_read(sma1303,
+			SMA1303_FF_DEVICE_INDEX, &device_info);
 
 	if ((ret != 0) || ((device_info & 0xF8) != DEVICE_ID)) {
 		dev_err(&client->dev, "device initialization error (%d 0x%02X)",
diff --git a/sound/soc/codecs/sma1303.h b/sound/soc/codecs/sma1303.h
index d1fa2acaba85..186af18188e9 100644
--- a/sound/soc/codecs/sma1303.h
+++ b/sound/soc/codecs/sma1303.h
@@ -11,6 +11,13 @@ 
 #ifndef _SMA1303_H
 #define _SMA1303_H
 
+typedef void (*callback_fptr) (void *device, int err);
+struct callback_ops {
+	callback_fptr set_i2c_err;
+};
+
+void sma1303_set_callback_func(struct callback_ops ops);
+
 #define  SMA1303_I2C_ADDR_00		0x1e
 #define  SMA1303_I2C_ADDR_01		0x3e
 #define  SMA1303_I2C_ADDR_10		0x5e
@@ -26,6 +33,8 @@ 
 #define  LEFT_TWO_CHIP_SOLUTION		0x02
 #define  RIGHT_TWO_CHIP_SOLUTION	0x03
 
+#define SMA1303_I2C_RETRY_COUNT		3
+
 /*
  * SMA1303 Register Definition
  */