diff options
author | Yeleswarapu Nagaradhesh <nagaradh@codeaurora.org> | 2016-06-15 11:30:19 +0530 |
---|---|---|
committer | Kyle Yan <kyan@codeaurora.org> | 2016-06-17 15:18:27 -0700 |
commit | 5eaa7f688fac14a9aefb9ae4db75f94309a37537 (patch) | |
tree | 756b927ff94314f0b76f982b340b8646a7a661eb /sound/soc/codecs | |
parent | 000c189cb63da500580c24b05e6b5559aade5e42 (diff) |
wcd9xxx: refactor wcd9xxx audio codec drivers
Refactor wcd9xxx audio codec driver for better handling
of codec specific functionalities.
CRs-fixed: 1028800
Change-Id: I229ee4a741c5a606e2eb045940f5ee3c4eabf512
Signed-off-by: Phani Kumar Uppalapati <phaniu@codeaurora.org>
Signed-off-by: Yeleswarapu Nagaradhesh <nagaradh@codeaurora.org>
Diffstat (limited to 'sound/soc/codecs')
-rwxr-xr-x | sound/soc/codecs/Kconfig | 1 | ||||
-rw-r--r-- | sound/soc/codecs/wcd9330.c | 156 | ||||
-rwxr-xr-x | sound/soc/codecs/wcd9335.c | 333 | ||||
-rw-r--r-- | sound/soc/codecs/wcd9335.h | 38 | ||||
-rw-r--r-- | sound/soc/codecs/wcd9xxx-mbhc.c | 4 | ||||
-rw-r--r-- | sound/soc/codecs/wcd9xxx-resmgr-v2.c | 40 | ||||
-rw-r--r-- | sound/soc/codecs/wcd9xxx-resmgr-v2.h | 4 | ||||
-rw-r--r-- | sound/soc/codecs/wcd9xxx-resmgr.h | 4 | ||||
-rw-r--r-- | sound/soc/codecs/wcd_cpe_core.c | 2 | ||||
-rw-r--r-- | sound/soc/codecs/wcd_cpe_core.h | 6 |
10 files changed, 503 insertions, 85 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 0f41d8ab1417..913bc0e06098 100755 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -722,6 +722,7 @@ config SND_SOC_WCD9330 config SND_SOC_WCD9335 tristate + depends on WCD9335_CODEC config SND_SOC_WSA881X tristate diff --git a/sound/soc/codecs/wcd9330.c b/sound/soc/codecs/wcd9330.c index e99337cb63d4..84368d817dc9 100644 --- a/sound/soc/codecs/wcd9330.c +++ b/sound/soc/codecs/wcd9330.c @@ -20,7 +20,9 @@ #include <linux/debugfs.h> #include <linux/wait.h> #include <linux/bitops.h> +#include <linux/regmap.h> #include <linux/mfd/wcd9xxx/core.h> +#include <linux/mfd/wcd9xxx/wcd9xxx-irq.h> #include <linux/mfd/wcd9xxx/wcd9xxx_registers.h> #include <linux/mfd/wcd9xxx/wcd9330_registers.h> #include <linux/mfd/wcd9xxx/pdata.h> @@ -521,6 +523,45 @@ static const u32 vport_i2s_check_table[NUM_CODEC_DAIS] = { 0, /* AIF2_CAP */ }; +/* + * Interrupt table for v3 corresponds to newer version + * codecs (wcd9330) + */ +static const struct intr_data wcd9330_intr_tbl[] = { + {WCD9XXX_IRQ_SLIMBUS, false}, + {WCD9XXX_IRQ_MBHC_INSERTION, true}, + {WCD9XXX_IRQ_MBHC_POTENTIAL, true}, + {WCD9XXX_IRQ_MBHC_RELEASE, true}, + {WCD9XXX_IRQ_MBHC_PRESS, true}, + {WCD9XXX_IRQ_MBHC_SHORT_TERM, true}, + {WCD9XXX_IRQ_MBHC_REMOVAL, true}, + {WCD9330_IRQ_MBHC_JACK_SWITCH, true}, + {WCD9XXX_IRQ_BG_PRECHARGE, false}, + {WCD9XXX_IRQ_PA1_STARTUP, false}, + {WCD9XXX_IRQ_PA2_STARTUP, false}, + {WCD9XXX_IRQ_PA3_STARTUP, false}, + {WCD9XXX_IRQ_PA4_STARTUP, false}, + {WCD9XXX_IRQ_PA5_STARTUP, false}, + {WCD9XXX_IRQ_MICBIAS1_PRECHARGE, false}, + {WCD9XXX_IRQ_MICBIAS2_PRECHARGE, false}, + {WCD9XXX_IRQ_MICBIAS3_PRECHARGE, false}, + {WCD9XXX_IRQ_HPH_PA_OCPL_FAULT, false}, + {WCD9XXX_IRQ_HPH_PA_OCPR_FAULT, false}, + {WCD9XXX_IRQ_EAR_PA_OCPL_FAULT, false}, + {WCD9XXX_IRQ_HPH_L_PA_STARTUP, false}, + {WCD9XXX_IRQ_HPH_R_PA_STARTUP, false}, + {WCD9320_IRQ_EAR_PA_STARTUP, false}, + {WCD9330_IRQ_SVASS_ERR_EXCEPTION, false}, + {WCD9330_IRQ_SVASS_ENGINE, true}, + {WCD9330_IRQ_MAD_AUDIO, false}, + {WCD9330_IRQ_MAD_BEACON, false}, + {WCD9330_IRQ_MAD_ULTRASOUND, false}, + {WCD9330_IRQ_SPEAKER1_CLIPPING, false}, + {WCD9330_IRQ_SPEAKER2_CLIPPING, false}, + {WCD9330_IRQ_VBAT_MONITOR_ATTACK, false}, + {WCD9330_IRQ_VBAT_MONITOR_RELEASE, false}, +}; + struct tomtom_priv { struct snd_soc_codec *codec; u32 adc_count; @@ -683,6 +724,121 @@ static unsigned short tx_digital_gain_reg[] = { TOMTOM_A_CDC_TX10_VOL_CTL_GAIN, }; +/* + * wcd9330_get_codec_info: Get codec specific information + * + * @wcd9xxx: pointer to wcd9xxx structure + * @wcd_type: pointer to wcd9xxx_codec_type structure + * + * Returns 0 for success or negative error code for failure + */ +int wcd9330_get_codec_info(struct wcd9xxx *wcd9xxx, + struct wcd9xxx_codec_type *wcd_type) +{ + u16 id_minor, id_major; + struct regmap *wcd_regmap; + int rc, val, version = 0; + + if (!wcd9xxx || !wcd_type) + return -EINVAL; + + if (!wcd9xxx->regmap) { + dev_err(wcd9xxx->dev, "%s: wcd9xxx regmap is null!\n", + __func__); + return -EINVAL; + } + wcd_regmap = wcd9xxx->regmap; + rc = regmap_bulk_read(wcd_regmap, TOMTOM_A_CHIP_ID_BYTE_0, + (u8 *)&id_minor, sizeof(u16)); + if (rc) + return -EINVAL; + + rc = regmap_bulk_read(wcd_regmap, TOMTOM_A_CHIP_ID_BYTE_2, + (u8 *)&id_major, sizeof(u16)); + if (rc) + return -EINVAL; + + dev_info(wcd9xxx->dev, "%s: wcd9xxx chip id major 0x%x, minor 0x%x\n", + __func__, id_major, id_minor); + + if (id_minor == cpu_to_le16(0x1)) + version = 2; + else if (id_minor == cpu_to_le16(0x0)) + version = 1; + else + dev_err(wcd9xxx->dev, "%s: wcd9330 version unknown (major 0x%x, minor 0x%x)\n", + __func__, id_major, id_minor); + + /* Fill codec type info */ + wcd_type->id_major = id_major; + wcd_type->id_minor = id_minor; + wcd_type->num_irqs = WCD9330_NUM_IRQS; + wcd_type->version = version; + wcd_type->slim_slave_type = WCD9XXX_SLIM_SLAVE_ADDR_TYPE_1; + wcd_type->i2c_chip_status = 0x01; + wcd_type->intr_tbl = wcd9330_intr_tbl; + wcd_type->intr_tbl_size = ARRAY_SIZE(wcd9330_intr_tbl); + + wcd_type->intr_reg[WCD9XXX_INTR_STATUS_BASE] = + TOMTOM_A_INTR1_STATUS0; + wcd_type->intr_reg[WCD9XXX_INTR_CLEAR_BASE] = + TOMTOM_A_INTR1_CLEAR0; + wcd_type->intr_reg[WCD9XXX_INTR_MASK_BASE] = + TOMTOM_A_INTR1_MASK0; + wcd_type->intr_reg[WCD9XXX_INTR_LEVEL_BASE] = + TOMTOM_A_INTR1_LEVEL0; + wcd_type->intr_reg[WCD9XXX_INTR_CLR_COMMIT] = + TOMTOM_A_INTR_MODE; + + return rc; +} +EXPORT_SYMBOL(wcd9330_get_codec_info); + +/* + * wcd9330_bringdown: Bringdown WCD Codec + * + * @wcd9xxx: Pointer to wcd9xxx structure + * + * Returns 0 for success or negative error code for failure + */ +int wcd9330_bringdown(struct wcd9xxx *wcd9xxx) +{ + if (!wcd9xxx || !wcd9xxx->regmap) + return -EINVAL; + + regmap_write(wcd9xxx->regmap, TOMTOM_A_LEAKAGE_CTL, 0x7); + regmap_write(wcd9xxx->regmap, TOMTOM_A_LEAKAGE_CTL, 0x6); + regmap_write(wcd9xxx->regmap, TOMTOM_A_LEAKAGE_CTL, 0xe); + regmap_write(wcd9xxx->regmap, TOMTOM_A_LEAKAGE_CTL, 0x8); + + return 0; +} +EXPORT_SYMBOL(wcd9330_bringdown); + +/* + * wcd9330_bringup: Bring up WCD Codec + * + * @wcd9xxx: Pointer to wcd9xxx structure + * + * Returns 0 for success or negative error code for failure + */ +int wcd9330_bringup(struct wcd9xxx *wcd9xxx) +{ + if (!wcd9xxx || !wcd9xxx->regmap) + return -EINVAL; + + regmap_write(wcd9xxx->regmap, TOMTOM_A_LEAKAGE_CTL, 0x4); + regmap_write(wcd9xxx->regmap, TOMTOM_A_CDC_CTL, 0x0); + /* wait for 5ms after codec reset for it to complete */ + usleep_range(5000, 5100); + regmap_write(wcd9xxx->regmap, TOMTOM_A_CDC_CTL, 0x1); + regmap_write(wcd9xxx->regmap, TOMTOM_A_LEAKAGE_CTL, 0x3); + regmap_write(wcd9xxx->regmap, TOMTOM_A_CDC_CTL, 0x3); + + return 0; +} +EXPORT_SYMBOL(wcd9330_bringup); + int tomtom_enable_qfuse_sensing(struct snd_soc_codec *codec) { struct tomtom_priv *tomtom = snd_soc_codec_get_drvdata(codec); diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 7ba7ec93b779..990d22fad45a 100755 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -21,7 +21,9 @@ #include <linux/debugfs.h> #include <linux/wait.h> #include <linux/bitops.h> +#include <linux/regmap.h> #include <linux/mfd/wcd9xxx/core.h> +#include <linux/mfd/wcd9xxx/wcd9xxx-irq.h> #include <linux/mfd/wcd9xxx/wcd9xxx_registers.h> #include <linux/mfd/wcd9335/registers.h> #include <linux/mfd/wcd9xxx/pdata.h> @@ -532,6 +534,38 @@ enum { SPLINE_SRC_MAX, }; +/* wcd9335 interrupt table */ +static const struct intr_data wcd9335_intr_table[] = { + {WCD9XXX_IRQ_SLIMBUS, false}, + {WCD9335_IRQ_MBHC_SW_DET, true}, + {WCD9335_IRQ_MBHC_BUTTON_PRESS_DET, true}, + {WCD9335_IRQ_MBHC_BUTTON_RELEASE_DET, true}, + {WCD9335_IRQ_MBHC_ELECT_INS_REM_DET, true}, + {WCD9335_IRQ_MBHC_ELECT_INS_REM_LEG_DET, true}, + {WCD9335_IRQ_FLL_LOCK_LOSS, false}, + {WCD9335_IRQ_HPH_PA_CNPL_COMPLETE, false}, + {WCD9335_IRQ_HPH_PA_CNPR_COMPLETE, false}, + {WCD9335_IRQ_EAR_PA_CNP_COMPLETE, false}, + {WCD9335_IRQ_LINE_PA1_CNP_COMPLETE, false}, + {WCD9335_IRQ_LINE_PA2_CNP_COMPLETE, false}, + {WCD9335_IRQ_LINE_PA3_CNP_COMPLETE, false}, + {WCD9335_IRQ_LINE_PA4_CNP_COMPLETE, false}, + {WCD9335_IRQ_HPH_PA_OCPL_FAULT, false}, + {WCD9335_IRQ_HPH_PA_OCPR_FAULT, false}, + {WCD9335_IRQ_EAR_PA_OCP_FAULT, false}, + {WCD9335_IRQ_SOUNDWIRE, false}, + {WCD9335_IRQ_VDD_DIG_RAMP_COMPLETE, false}, + {WCD9335_IRQ_RCO_ERROR, false}, + {WCD9335_IRQ_SVA_ERROR, false}, + {WCD9335_IRQ_MAD_AUDIO, false}, + {WCD9335_IRQ_MAD_BEACON, false}, + {WCD9335_IRQ_SVA_OUTBOX1, true}, + {WCD9335_IRQ_SVA_OUTBOX2, true}, + {WCD9335_IRQ_MAD_ULTRASOUND, false}, + {WCD9335_IRQ_VBAT_ATTACK, false}, + {WCD9335_IRQ_VBAT_RESTORE, false}, +}; + static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); @@ -816,6 +850,176 @@ static const struct tasha_reg_mask_val tasha_spkr_mode1[] = { {WCD9335_CDC_BOOST1_BOOST_CTL, 0x7C, 0x44}, }; +/* + * wcd9335_get_codec_info: Get codec specific information + * + * @wcd9xxx: pointer to wcd9xxx structure + * @wcd_type: pointer to wcd9xxx_codec_type structure + * + * Returns 0 for success or negative error code for failure + */ +int wcd9335_get_codec_info(struct wcd9xxx *wcd9xxx, + struct wcd9xxx_codec_type *wcd_type) +{ + u16 id_minor, id_major; + struct regmap *wcd_regmap; + int rc, val, version = 0; + + if (!wcd9xxx || !wcd_type) + return -EINVAL; + + if (!wcd9xxx->regmap) { + dev_err(wcd9xxx->dev, "%s: wcd9xxx regmap is null!\n", + __func__); + return -EINVAL; + } + wcd_regmap = wcd9xxx->regmap; + + rc = regmap_bulk_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0, + (u8 *)&id_minor, sizeof(u16)); + if (rc) + return -EINVAL; + + rc = regmap_bulk_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE2, + (u8 *)&id_major, sizeof(u16)); + if (rc) + return -EINVAL; + + dev_info(wcd9xxx->dev, "%s: wcd9xxx chip id major 0x%x, minor 0x%x\n", + __func__, id_major, id_minor); + + /* Version detection */ + if (id_major == TASHA_MAJOR) { + regmap_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0, + &val); + version = ((u8)val & 0x80) >> 7; + } else if (id_major == TASHA2P0_MAJOR) + version = 2; + else + dev_err(wcd9xxx->dev, "%s: wcd9335 version unknown (major 0x%x, minor 0x%x)\n", + __func__, id_major, id_minor); + + /* Fill codec type info */ + wcd_type->id_major = id_major; + wcd_type->id_minor = id_minor; + wcd_type->num_irqs = WCD9335_NUM_IRQS; + wcd_type->version = version; + wcd_type->slim_slave_type = WCD9XXX_SLIM_SLAVE_ADDR_TYPE_1; + wcd_type->i2c_chip_status = 0x01; + wcd_type->intr_tbl = wcd9335_intr_table; + wcd_type->intr_tbl_size = ARRAY_SIZE(wcd9335_intr_table); + + wcd_type->intr_reg[WCD9XXX_INTR_STATUS_BASE] = + WCD9335_INTR_PIN1_STATUS0; + wcd_type->intr_reg[WCD9XXX_INTR_CLEAR_BASE] = + WCD9335_INTR_PIN1_CLEAR0; + wcd_type->intr_reg[WCD9XXX_INTR_MASK_BASE] = + WCD9335_INTR_PIN1_MASK0; + wcd_type->intr_reg[WCD9XXX_INTR_LEVEL_BASE] = + WCD9335_INTR_LEVEL0; + wcd_type->intr_reg[WCD9XXX_INTR_CLR_COMMIT] = + WCD9335_INTR_CLR_COMMIT; + + return rc; +} +EXPORT_SYMBOL(wcd9335_get_codec_info); + +/* + * wcd9335_bringdown: Bringdown WCD Codec + * + * @wcd9xxx: Pointer to wcd9xxx structure + * + * Returns 0 for success or negative error code for failure + */ +int wcd9335_bringdown(struct wcd9xxx *wcd9xxx) +{ + if (!wcd9xxx || !wcd9xxx->regmap) + return -EINVAL; + + regmap_write(wcd9xxx->regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x04); + + return 0; +} +EXPORT_SYMBOL(wcd9335_bringdown); + +/* + * wcd9335_bringup: Bringup WCD Codec + * + * @wcd9xxx: Pointer to the wcd9xxx structure + * + * Returns 0 for success or negative error code for failure + */ +int wcd9335_bringup(struct wcd9xxx *wcd9xxx) +{ + int ret = 0; + int val, byte0; + struct regmap *wcd_regmap; + + if (!wcd9xxx) + return -EINVAL; + + if (!wcd9xxx->regmap) { + dev_err(wcd9xxx->dev, "%s: wcd9xxx regmap is null!\n", + __func__); + return -EINVAL; + } + wcd_regmap = wcd9xxx->regmap; + + regmap_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0, &val); + regmap_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0, &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__); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x01); + regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_2, 0xFC); + regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_4, 0x21); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x5); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x7); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x3); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x3); + } else if (byte0 == 0x1) { + dev_info(wcd9xxx->dev, "%s: wcd9335 codec version is v2.0\n", + __func__); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x01); + regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_TEST_2, 0x00); + regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_8, 0x6F); + regmap_write(wcd_regmap, WCD9335_BIAS_VBG_FINE_ADJ, 0x65); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x5); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x7); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x3); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x3); + } else if ((byte0 == 0) && (!(val & 0x80))) { + dev_info(wcd9xxx->dev, "%s: wcd9335 codec version is v1.0\n", + __func__); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x01); + regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_2, 0xFC); + regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_4, 0x21); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL, + 0x3); + regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x3); + } else { + dev_err(wcd9xxx->dev, "%s: tasha codec version unknown\n", + __func__); + ret = -EINVAL; + } + + return ret; +} +EXPORT_SYMBOL(wcd9335_bringup); + /** * tasha_set_spkr_gain_offset - offset the speaker path * gain with the given offset value. @@ -1592,7 +1796,7 @@ static inline void tasha_mbhc_get_result_params(struct wcd9xxx *wcd9xxx, int32_t *zdet) { int i; - u16 val; + int val, val1; s16 c1; s32 x1, d1; int32_t denom; @@ -1600,19 +1804,16 @@ static inline void tasha_mbhc_get_result_params(struct wcd9xxx *wcd9xxx, 3277, 1639, 820, 410, 205, 103, 52, 26 }; - wcd9xxx_reg_update_bits(&wcd9xxx->core_res, - WCD9335_ANA_MBHC_ZDET, 0x20, 0x20); + regmap_update_bits(wcd9xxx->regmap, WCD9335_ANA_MBHC_ZDET, 0x20, 0x20); for (i = 0; i < TASHA_ZDET_NUM_MEASUREMENTS; i++) { - val = wcd9xxx_reg_read(&wcd9xxx->core_res, - WCD9335_ANA_MBHC_RESULT_2); + regmap_read(wcd9xxx->regmap, WCD9335_ANA_MBHC_RESULT_2, &val); if (val & 0x80) break; } val = val << 0x8; - val |= wcd9xxx_reg_read(&wcd9xxx->core_res, - WCD9335_ANA_MBHC_RESULT_1); - wcd9xxx_reg_update_bits(&wcd9xxx->core_res, - WCD9335_ANA_MBHC_ZDET, 0x20, 0x00); + regmap_read(wcd9xxx->regmap, WCD9335_ANA_MBHC_RESULT_1, &val1); + val |= val1; + regmap_update_bits(wcd9xxx->regmap, WCD9335_ANA_MBHC_ZDET, 0x20, 0x00); x1 = TASHA_MBHC_GET_X1(val); c1 = TASHA_MBHC_GET_C1(val); /* If ramp is not complete, give additional 5ms */ @@ -1637,8 +1838,8 @@ static inline void tasha_mbhc_get_result_params(struct wcd9xxx *wcd9xxx, ramp_down: i = 0; while (x1) { - wcd9xxx_bulk_read(&wcd9xxx->core_res, - WCD9335_ANA_MBHC_RESULT_1, 2, (u8 *)&val); + regmap_bulk_read(wcd9xxx->regmap, + WCD9335_ANA_MBHC_RESULT_1, (u8 *)&val, 2); x1 = TASHA_MBHC_GET_X1(val); i++; if (i == TASHA_ZDET_NUM_MEASUREMENTS) @@ -1691,13 +1892,13 @@ static void tasha_mbhc_zdet_ramp(struct snd_soc_codec *codec, if (!zl) goto z_right; /* Start impedance measurement for HPH_L */ - wcd9xxx_reg_update_bits(&wcd9xxx->core_res, - WCD9335_ANA_MBHC_ZDET, 0x80, 0x80); + regmap_update_bits(wcd9xxx->regmap, + WCD9335_ANA_MBHC_ZDET, 0x80, 0x80); dev_dbg(wcd9xxx->dev, "%s: ramp for HPH_L, noff = %d\n", __func__, zdet_param->noff); tasha_mbhc_get_result_params(wcd9xxx, d1_a, zdet_param->noff, &zdet); - wcd9xxx_reg_update_bits(&wcd9xxx->core_res, - WCD9335_ANA_MBHC_ZDET, 0x80, 0x00); + regmap_update_bits(wcd9xxx->regmap, + WCD9335_ANA_MBHC_ZDET, 0x80, 0x00); *zl = zdet; @@ -1705,13 +1906,13 @@ z_right: if (!zr) return; /* Start impedance measurement for HPH_R */ - wcd9xxx_reg_update_bits(&wcd9xxx->core_res, - WCD9335_ANA_MBHC_ZDET, 0x40, 0x40); + regmap_update_bits(wcd9xxx->regmap, + WCD9335_ANA_MBHC_ZDET, 0x40, 0x40); dev_dbg(wcd9xxx->dev, "%s: ramp for HPH_R, noff = %d\n", __func__, zdet_param->noff); tasha_mbhc_get_result_params(wcd9xxx, d1_a, zdet_param->noff, &zdet); - wcd9xxx_reg_update_bits(&wcd9xxx->core_res, - WCD9335_ANA_MBHC_ZDET, 0x40, 0x00); + regmap_update_bits(wcd9xxx->regmap, + WCD9335_ANA_MBHC_ZDET, 0x40, 0x00); *zr = zdet; } @@ -1780,23 +1981,22 @@ static void tasha_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl, reg3 = snd_soc_read(codec, WCD9335_MBHC_CTL_1); reg4 = snd_soc_read(codec, WCD9335_MBHC_ZDET_ANA_CTL); - if (wcd9xxx_reg_read(&wcd9xxx->core_res, - WCD9335_ANA_MBHC_ELECT) & 0x80) { + if (snd_soc_read(codec, WCD9335_ANA_MBHC_ELECT) & 0x80) { is_fsm_disable = true; - wcd9xxx_reg_update_bits(&wcd9xxx->core_res, - WCD9335_ANA_MBHC_ELECT, 0x80, 0x00); + regmap_update_bits(wcd9xxx->regmap, + WCD9335_ANA_MBHC_ELECT, 0x80, 0x00); } /* For NO-jack, disable L_DET_EN before Z-det measurements */ if (mbhc->hphl_swh) - wcd9xxx_reg_update_bits(&wcd9xxx->core_res, - WCD9335_ANA_MBHC_MECH, 0x80, 0x00); + regmap_update_bits(wcd9xxx->regmap, + WCD9335_ANA_MBHC_MECH, 0x80, 0x00); /* Enable AZ */ snd_soc_update_bits(codec, WCD9335_MBHC_CTL_1, 0x0C, 0x04); /* Turn off 100k pull down on HPHL */ - wcd9xxx_reg_update_bits(&wcd9xxx->core_res, - WCD9335_ANA_MBHC_MECH, 0x01, 0x00); + regmap_update_bits(wcd9xxx->regmap, + WCD9335_ANA_MBHC_MECH, 0x01, 0x00); /* First get impedance on Left */ d1 = d1_a[1]; @@ -1911,19 +2111,19 @@ zdet_complete: snd_soc_write(codec, WCD9335_ANA_MBHC_BTN6, reg1); snd_soc_write(codec, WCD9335_ANA_MBHC_BTN7, reg2); /* Turn on 100k pull down on HPHL */ - wcd9xxx_reg_update_bits(&wcd9xxx->core_res, - WCD9335_ANA_MBHC_MECH, 0x01, 0x01); + regmap_update_bits(wcd9xxx->regmap, + WCD9335_ANA_MBHC_MECH, 0x01, 0x01); /* For NO-jack, re-enable L_DET_EN after Z-det measurements */ if (mbhc->hphl_swh) - wcd9xxx_reg_update_bits(&wcd9xxx->core_res, - WCD9335_ANA_MBHC_MECH, 0x80, 0x80); + regmap_update_bits(wcd9xxx->regmap, + WCD9335_ANA_MBHC_MECH, 0x80, 0x80); snd_soc_write(codec, WCD9335_MBHC_ZDET_ANA_CTL, reg4); snd_soc_write(codec, WCD9335_MBHC_CTL_1, reg3); if (is_fsm_disable) - wcd9xxx_reg_update_bits(&wcd9xxx->core_res, - WCD9335_ANA_MBHC_ELECT, 0x80, 0x80); + regmap_update_bits(wcd9xxx->regmap, + WCD9335_ANA_MBHC_ELECT, 0x80, 0x80); if (tasha->zdet_gpio_cb && is_change) tasha->zdet_gpio_cb(codec, false); } @@ -11776,18 +11976,18 @@ static void tasha_update_reg_defaults(struct tasha_priv *tasha) wcd9xxx = tasha->wcd9xxx; for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_defaults); i++) - wcd9xxx_reg_update_bits(&wcd9xxx->core_res, - tasha_codec_reg_defaults[i].reg, - tasha_codec_reg_defaults[i].mask, - tasha_codec_reg_defaults[i].val); + regmap_update_bits(wcd9xxx->regmap, + tasha_codec_reg_defaults[i].reg, + tasha_codec_reg_defaults[i].mask, + tasha_codec_reg_defaults[i].val); tasha->intf_type = wcd9xxx_get_intf_type(); if (tasha->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) for (i = 0; i < ARRAY_SIZE(tasha_codec_reg_i2c_defaults); i++) - wcd9xxx_reg_update_bits(&wcd9xxx->core_res, - tasha_codec_reg_i2c_defaults[i].reg, - tasha_codec_reg_i2c_defaults[i].mask, - tasha_codec_reg_i2c_defaults[i].val); + regmap_update_bits(wcd9xxx->regmap, + tasha_codec_reg_i2c_defaults[i].reg, + tasha_codec_reg_i2c_defaults[i].mask, + tasha_codec_reg_i2c_defaults[i].val); return; } @@ -12919,15 +13119,15 @@ static int tasha_swrm_read(void *handle, int reg) swr_rd_data_base = WCD9335_SWR_AHB_BRIDGE_RD_DATA_0; /* read_lock */ mutex_lock(&tasha->swr_read_lock); - ret = wcd9xxx_bulk_write(&wcd9xxx->core_res, swr_rd_addr_base, 4, - (u8 *)®); + ret = regmap_bulk_write(wcd9xxx->regmap, swr_rd_addr_base, + (u8 *)®, 4); if (ret < 0) { pr_err("%s: RD Addr Failure\n", __func__); goto err; } /* Check for RD status */ - ret = wcd9xxx_bulk_read(&wcd9xxx->core_res, swr_rd_data_base, 4, - (u8 *)&val); + ret = regmap_bulk_read(wcd9xxx->regmap, swr_rd_data_base, + (u8 *)&val, 4); if (ret < 0) { pr_err("%s: RD Data Failure\n", __func__); goto err; @@ -12952,16 +13152,16 @@ static int tasha_swrm_i2s_bulk_write(struct wcd9xxx *wcd9xxx, for (i = 0; i < (len * 2); i += 2) { /* First Write the Data to register */ - ret = wcd9xxx_bulk_write(&wcd9xxx->core_res, - swr_wr_data_base, 4, bulk_reg[i].buf); + ret = regmap_bulk_write(wcd9xxx->regmap, + swr_wr_data_base, bulk_reg[i].buf, 4); if (ret < 0) { dev_err(wcd9xxx->dev, "%s: WR Data Failure\n", __func__); break; } /* Next Write Address */ - ret = wcd9xxx_bulk_write(&wcd9xxx->core_res, - swr_wr_addr_base, 4, bulk_reg[i+1].buf); + ret = regmap_bulk_write(wcd9xxx->regmap, + swr_wr_addr_base, bulk_reg[i+1].buf, 4); if (ret < 0) { dev_err(wcd9xxx->dev, "%s: WR Addr Failure\n", __func__); @@ -13087,25 +13287,25 @@ static int tasha_swrm_clock(void *handle, bool enable) tasha->swr_clk_users++; if (tasha->swr_clk_users == 1) { if (TASHA_IS_2_0(tasha->wcd9xxx->version)) - wcd9xxx_reg_update_bits( - &tasha->wcd9xxx->core_res, + regmap_update_bits( + tasha->wcd9xxx->regmap, WCD9335_TEST_DEBUG_NPL_DLY_TEST_1, 0x10, 0x00); __tasha_cdc_mclk_enable(tasha, true); - wcd9xxx_reg_update_bits(&tasha->wcd9xxx->core_res, + regmap_update_bits(tasha->wcd9xxx->regmap, WCD9335_CDC_CLK_RST_CTRL_SWR_CONTROL, 0x01, 0x01); } } else { tasha->swr_clk_users--; if (tasha->swr_clk_users == 0) { - wcd9xxx_reg_update_bits(&tasha->wcd9xxx->core_res, + regmap_update_bits(tasha->wcd9xxx->regmap, WCD9335_CDC_CLK_RST_CTRL_SWR_CONTROL, 0x01, 0x00); __tasha_cdc_mclk_enable(tasha, false); if (TASHA_IS_2_0(tasha->wcd9xxx->version)) - wcd9xxx_reg_update_bits( - &tasha->wcd9xxx->core_res, + regmap_update_bits( + tasha->wcd9xxx->regmap, WCD9335_TEST_DEBUG_NPL_DLY_TEST_1, 0x10, 0x10); } @@ -13243,31 +13443,35 @@ EXPORT_SYMBOL(tasha_codec_ver); static int __tasha_enable_efuse_sensing(struct tasha_priv *tasha) { + int val, rc; + __tasha_cdc_mclk_enable(tasha, true); - wcd9xxx_reg_update_bits(&tasha->wcd9xxx->core_res, - WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, 0x1E, 0x20); - wcd9xxx_reg_update_bits(&tasha->wcd9xxx->core_res, - WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, 0x01, 0x01); + regmap_update_bits(tasha->wcd9xxx->regmap, + WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, 0x1E, 0x20); + regmap_update_bits(tasha->wcd9xxx->regmap, + WCD9335_CHIP_TIER_CTRL_EFUSE_CTL, 0x01, 0x01); /* * 5ms sleep required after enabling efuse control * before checking the status. */ usleep_range(5000, 5500); - if (!(wcd9xxx_reg_read(&tasha->wcd9xxx->core_res, - WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS) & 0x01)) + rc = regmap_read(tasha->wcd9xxx->regmap, + WCD9335_CHIP_TIER_CTRL_EFUSE_STATUS, &val); + + if (rc || (!(val & 0x01))) WARN(1, "%s: Efuse sense is not complete\n", __func__); __tasha_cdc_mclk_enable(tasha, false); - return 0; + return rc; } void tasha_get_codec_ver(struct tasha_priv *tasha) { int i; - u8 val; + int val; struct tasha_reg_mask_val codec_reg[] = { {WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT10, 0xFF, 0xFF}, {WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT11, 0xFF, 0x83}, @@ -13276,8 +13480,7 @@ void tasha_get_codec_ver(struct tasha_priv *tasha) __tasha_enable_efuse_sensing(tasha); for (i = 0; i < ARRAY_SIZE(codec_reg); i++) { - val = wcd9xxx_reg_read(&tasha->wcd9xxx->core_res, - codec_reg[i].reg); + regmap_read(tasha->wcd9xxx->regmap, codec_reg[i].reg, &val); if (!(val && codec_reg[i].val)) { codec_ver = WCD9335; goto ret; diff --git a/sound/soc/codecs/wcd9335.h b/sound/soc/codecs/wcd9335.h index 40cb70f05280..67280c583b2a 100644 --- a/sound/soc/codecs/wcd9335.h +++ b/sound/soc/codecs/wcd9335.h @@ -83,6 +83,44 @@ enum { TASHA_TX_MAX, }; +enum { + /* INTR_REG 0 */ + WCD9335_IRQ_FLL_LOCK_LOSS = 1, + WCD9335_IRQ_HPH_PA_OCPL_FAULT, + WCD9335_IRQ_HPH_PA_OCPR_FAULT, + WCD9335_IRQ_EAR_PA_OCP_FAULT, + WCD9335_IRQ_HPH_PA_CNPL_COMPLETE, + WCD9335_IRQ_HPH_PA_CNPR_COMPLETE, + WCD9335_IRQ_EAR_PA_CNP_COMPLETE, + /* INTR_REG 1 */ + WCD9335_IRQ_MBHC_SW_DET, + WCD9335_IRQ_MBHC_ELECT_INS_REM_DET, + WCD9335_IRQ_MBHC_BUTTON_PRESS_DET, + WCD9335_IRQ_MBHC_BUTTON_RELEASE_DET, + WCD9335_IRQ_MBHC_ELECT_INS_REM_LEG_DET, + WCD9335_IRQ_RESERVED_0, + WCD9335_IRQ_RESERVED_1, + WCD9335_IRQ_RESERVED_2, + /* INTR_REG 2 */ + WCD9335_IRQ_LINE_PA1_CNP_COMPLETE, + WCD9335_IRQ_LINE_PA2_CNP_COMPLETE, + WCD9335_IRQ_LINE_PA3_CNP_COMPLETE, + WCD9335_IRQ_LINE_PA4_CNP_COMPLETE, + WCD9335_IRQ_SOUNDWIRE, + WCD9335_IRQ_VDD_DIG_RAMP_COMPLETE, + WCD9335_IRQ_RCO_ERROR, + WCD9335_IRQ_SVA_ERROR, + /* INTR_REG 3 */ + WCD9335_IRQ_MAD_AUDIO, + WCD9335_IRQ_MAD_BEACON, + WCD9335_IRQ_MAD_ULTRASOUND, + WCD9335_IRQ_VBAT_ATTACK, + WCD9335_IRQ_VBAT_RESTORE, + WCD9335_IRQ_SVA_OUTBOX1, + WCD9335_IRQ_SVA_OUTBOX2, + WCD9335_NUM_IRQS, +}; + enum wcd9335_codec_event { WCD9335_CODEC_EVENT_CODEC_UP = 0, }; diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c index 168d1d5648be..52ca82fba8e9 100644 --- a/sound/soc/codecs/wcd9xxx-mbhc.c +++ b/sound/soc/codecs/wcd9xxx-mbhc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -20,7 +20,7 @@ #include <linux/debugfs.h> #include <linux/list.h> #include <linux/mfd/wcd9xxx/core.h> -#include <linux/mfd/wcd9xxx/core-resource.h> +#include <linux/mfd/wcd9xxx/wcd9xxx-irq.h> #include <linux/mfd/wcd9xxx/wcd9xxx_registers.h> #include <linux/mfd/wcd9xxx/wcd9320_registers.h> #include <linux/mfd/wcd9xxx/pdata.h> diff --git a/sound/soc/codecs/wcd9xxx-resmgr-v2.c b/sound/soc/codecs/wcd9xxx-resmgr-v2.c index 824758d9859a..9cd9736dc850 100644 --- a/sound/soc/codecs/wcd9xxx-resmgr-v2.c +++ b/sound/soc/codecs/wcd9xxx-resmgr-v2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -35,25 +35,41 @@ static const char *wcd_resmgr_clk_type_to_str(enum wcd_clock_type clk_type) static int wcd_resmgr_codec_reg_update_bits(struct wcd9xxx_resmgr_v2 *resmgr, u16 reg, u8 mask, u8 val) { - int change; - if (resmgr->codec) - change = snd_soc_update_bits(resmgr->codec, reg, mask, val); - else - change = wcd9xxx_reg_update_bits(resmgr->core_res, reg, - mask, val); + bool change; + int ret; + + if (resmgr->codec) { + ret = snd_soc_update_bits(resmgr->codec, reg, mask, val); + } else if (resmgr->core_res->wcd_core_regmap) { + ret = regmap_update_bits_check( + resmgr->core_res->wcd_core_regmap, + reg, mask, val, &change); + if (!ret) + ret = change; + } else { + pr_err("%s: codec/regmap not defined\n", __func__); + ret = -EINVAL; + } - return change; + return ret; } static int wcd_resmgr_codec_reg_read(struct wcd9xxx_resmgr_v2 *resmgr, unsigned int reg) { - int val; + int val, ret; - if (resmgr->codec) + if (resmgr->codec) { val = snd_soc_read(resmgr->codec, reg); - else - val = wcd9xxx_reg_read(resmgr->core_res, reg); + } else if (resmgr->core_res->wcd_core_regmap) { + ret = regmap_read(resmgr->core_res->wcd_core_regmap, + reg, &val); + if (ret) + val = ret; + } else { + pr_err("%s: wcd regmap is null\n", __func__); + return -EINVAL; + } return val; } diff --git a/sound/soc/codecs/wcd9xxx-resmgr-v2.h b/sound/soc/codecs/wcd9xxx-resmgr-v2.h index 5f44e6fdefbf..61e242d52c1e 100644 --- a/sound/soc/codecs/wcd9xxx-resmgr-v2.h +++ b/sound/soc/codecs/wcd9xxx-resmgr-v2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -13,7 +13,7 @@ #ifndef __WCD9XXX_COMMON_V2_H__ #define __WCD9XXX_COMMON_V2_H__ -#include <linux/mfd/wcd9xxx/core-resource.h> +#include <linux/mfd/wcd9xxx/core.h> #include <linux/mfd/wcd9xxx/wcd9xxx_registers.h> enum wcd_clock_type { diff --git a/sound/soc/codecs/wcd9xxx-resmgr.h b/sound/soc/codecs/wcd9xxx-resmgr.h index a334eadd9918..e35d6161d488 100644 --- a/sound/soc/codecs/wcd9xxx-resmgr.h +++ b/sound/soc/codecs/wcd9xxx-resmgr.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -13,7 +13,7 @@ #define __WCD9XXX_COMMON_H__ #include <linux/notifier.h> -#include <linux/mfd/wcd9xxx/core-resource.h> +#include <linux/mfd/wcd9xxx/core.h> #include <linux/mfd/wcd9xxx/wcd9xxx_registers.h> enum wcd9xxx_bandgap_type { diff --git a/sound/soc/codecs/wcd_cpe_core.c b/sound/soc/codecs/wcd_cpe_core.c index 58fca9131b3c..b1e105b3153a 100644 --- a/sound/soc/codecs/wcd_cpe_core.c +++ b/sound/soc/codecs/wcd_cpe_core.c @@ -28,7 +28,7 @@ #include <sound/cpe_err.h> #include <soc/qcom/pm.h> #include <linux/mfd/wcd9xxx/core.h> -#include <linux/mfd/wcd9xxx/core-resource.h> +#include <linux/mfd/wcd9xxx/wcd9xxx-irq.h> #include <sound/audio_cal_utils.h> #include "wcd_cpe_core.h" #include "wcd_cpe_services.h" diff --git a/sound/soc/codecs/wcd_cpe_core.h b/sound/soc/codecs/wcd_cpe_core.h index 77027d58b178..b09b03d2f81d 100644 --- a/sound/soc/codecs/wcd_cpe_core.h +++ b/sound/soc/codecs/wcd_cpe_core.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -10,6 +10,9 @@ * GNU General Public License for more details. */ +#ifndef WCD_CPE_CORE_H +#define WCD_CPE_CORE_H + #include <soc/qcom/ramdump.h> #include <linux/dma-mapping.h> #include "wcd_cpe_services.h" @@ -220,3 +223,4 @@ int wcd_cpe_ssr_event(void *core_handle, enum wcd_cpe_ssr_state_event event); struct wcd_cpe_core *wcd_cpe_init(const char *, struct snd_soc_codec *, struct wcd_cpe_params *params); +#endif |