From 2275c544cb824b469a386e411cbcaa01a19d4f55 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 10 Sep 2012 13:46:22 +0300 Subject: mfd: twl-core: Add API to query the HFCLK rate CFG_BOOT register's HFCLK_FREQ field hold information about the used HFCLK frequency. Add possibility for users to get the configured rate based on this register. This register was configured during boot, without it the chip would not operate correctly, so we can trust on this information. Signed-off-by: Peter Ujfalusi Signed-off-by: Samuel Ortiz --- include/linux/i2c/twl.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux/i2c/twl.h') diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index 7ea898c55a6..ac6488c9f25 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h @@ -188,6 +188,7 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); int twl_get_type(void); int twl_get_version(void); +int twl_get_hfclk_rate(void); int twl6030_interrupt_unmask(u8 bit_mask, u8 offset); int twl6030_interrupt_mask(u8 bit_mask, u8 offset); -- cgit v1.2.3-70-g09d2 From 4cd7a2f1aedb2008004e110d31ce831895139fa0 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 10 Sep 2012 13:46:22 +0300 Subject: mfd: twl-core: Add API to query the HFCLK rate CFG_BOOT register's HFCLK_FREQ field hold information about the used HFCLK frequency. Add possibility for users to get the configured rate based on this register. This register was configured during boot, without it the chip would not operate correctly, so we can trust on this information. Signed-off-by: Peter Ujfalusi Acked-by: Samuel Ortiz Signed-off-by: Mark Brown --- drivers/mfd/twl-core.c | 32 ++++++++++++++++++++++++++++++++ include/linux/i2c/twl.h | 1 + 2 files changed, 33 insertions(+) (limited to 'include/linux/i2c/twl.h') diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 1c32afed28a..f162b68e78a 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -552,6 +552,38 @@ int twl_get_version(void) } EXPORT_SYMBOL_GPL(twl_get_version); +/** + * twl_get_hfclk_rate - API to get TWL external HFCLK clock rate. + * + * Api to get the TWL HFCLK rate based on BOOT_CFG register. + */ +int twl_get_hfclk_rate(void) +{ + u8 ctrl; + int rate; + + twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &ctrl, R_CFG_BOOT); + + switch (ctrl & 0x3) { + case HFCLK_FREQ_19p2_MHZ: + rate = 19200000; + break; + case HFCLK_FREQ_26_MHZ: + rate = 26000000; + break; + case HFCLK_FREQ_38p4_MHZ: + rate = 38400000; + break; + default: + pr_err("TWL4030: HFCLK is not configured\n"); + rate = -EINVAL; + break; + } + + return rate; +} +EXPORT_SYMBOL_GPL(twl_get_hfclk_rate); + static struct device * add_numbered_child(unsigned chip, const char *name, int num, void *pdata, unsigned pdata_len, diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index 7ea898c55a6..ac6488c9f25 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h @@ -188,6 +188,7 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); int twl_get_type(void); int twl_get_version(void); +int twl_get_hfclk_rate(void); int twl6030_interrupt_unmask(u8 bit_mask, u8 offset); int twl6030_interrupt_mask(u8 bit_mask, u8 offset); -- cgit v1.2.3-70-g09d2 From 281ecd1611654cdcdec0ffcb55e8f285b8199727 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 10 Sep 2012 13:46:27 +0300 Subject: ASoC: twl4030: Move hs_extmute GPIO handling to driver The external mute (if it is in use) is handled by a GPIO line. Prepare to remove the set_hs_extmute callback and replace it with: hs_extmute_gpio: the GPIO number to use for external mute When the users of set_hs_extmute has been converted the callback can be removed. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- include/linux/i2c/twl.h | 4 +++- sound/soc/codecs/twl4030.c | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) (limited to 'include/linux/i2c/twl.h') diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index ac6488c9f25..2040309a46b 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h @@ -667,7 +667,9 @@ struct twl4030_codec_data { unsigned int check_defaults:1; unsigned int reset_registers:1; unsigned int hs_extmute:1; - void (*set_hs_extmute)(int mute); + void (*set_hs_extmute)(int mute); /* Deprecated, use hs_extmute_gpio and + hs_extmute_disable_level */ + int hs_extmute_gpio; }; struct twl4030_vibra_data { diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 962341df7dd..0c83c9263f4 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -302,6 +303,22 @@ static void twl4030_init_chip(struct snd_soc_codec *codec) u8 reg, byte; int i = 0; + if (pdata && pdata->hs_extmute && + gpio_is_valid(pdata->hs_extmute_gpio)) { + int ret; + + if (!pdata->hs_extmute_gpio) + dev_warn(codec->dev, + "Extmute GPIO is 0 is this correct?\n"); + + ret = gpio_request_one(pdata->hs_extmute_gpio, + GPIOF_OUT_INIT_LOW, "hs_extmute"); + if (ret) { + dev_err(codec->dev, "Failed to get hs_extmute GPIO\n"); + pdata->hs_extmute_gpio = -1; + } + } + /* Check defaults, if instructed before anything else */ if (pdata && pdata->check_defaults) twl4030_check_defaults(codec); @@ -748,7 +765,10 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) /* Enable external mute control, this dramatically reduces * the pop-noise */ if (pdata && pdata->hs_extmute) { - if (pdata->set_hs_extmute) { + if (gpio_is_valid(pdata->hs_extmute_gpio)) { + gpio_set_value(pdata->hs_extmute_gpio, 1); + } else if (pdata->set_hs_extmute) { + dev_warn(codec->dev, "set_hs_extmute is deprecated\n"); pdata->set_hs_extmute(1); } else { hs_pop |= TWL4030_EXTMUTE; @@ -786,7 +806,10 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) /* Disable external mute */ if (pdata && pdata->hs_extmute) { - if (pdata->set_hs_extmute) { + if (gpio_is_valid(pdata->hs_extmute_gpio)) { + gpio_set_value(pdata->hs_extmute_gpio, 0); + } else if (pdata->set_hs_extmute) { + dev_warn(codec->dev, "set_hs_extmute is deprecated\n"); pdata->set_hs_extmute(0); } else { hs_pop &= ~TWL4030_EXTMUTE; @@ -2236,12 +2259,17 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec) static int twl4030_soc_remove(struct snd_soc_codec *codec) { + struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev); struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); /* Reset registers to their chip default before leaving */ twl4030_reset_registers(codec); twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); kfree(twl4030); + + if (pdata && pdata->hs_extmute && gpio_is_valid(pdata->hs_extmute_gpio)) + gpio_free(pdata->hs_extmute_gpio); + return 0; } -- cgit v1.2.3-70-g09d2 From d0b3847b40f8da4b90b22db0f3678ba68bcd1b4e Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 10 Sep 2012 13:46:29 +0300 Subject: ASoC/mfd: twl4030: Remove set_hs_extmute callback from platform data We no longer have users for the set_hs_extmute callback which has been replaced by hs_extmute_gpio so the codec driver can handle the external mute if it is needed by the board. Signed-off-by: Peter Ujfalusi Acked-by: Samuel Ortiz Signed-off-by: Mark Brown --- include/linux/i2c/twl.h | 2 -- sound/soc/codecs/twl4030.c | 6 ------ 2 files changed, 8 deletions(-) (limited to 'include/linux/i2c/twl.h') diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index 2040309a46b..a4885a6cd10 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h @@ -667,8 +667,6 @@ struct twl4030_codec_data { unsigned int check_defaults:1; unsigned int reset_registers:1; unsigned int hs_extmute:1; - void (*set_hs_extmute)(int mute); /* Deprecated, use hs_extmute_gpio and - hs_extmute_disable_level */ int hs_extmute_gpio; }; diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 0c83c9263f4..aa96788c867 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -767,9 +767,6 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) if (pdata && pdata->hs_extmute) { if (gpio_is_valid(pdata->hs_extmute_gpio)) { gpio_set_value(pdata->hs_extmute_gpio, 1); - } else if (pdata->set_hs_extmute) { - dev_warn(codec->dev, "set_hs_extmute is deprecated\n"); - pdata->set_hs_extmute(1); } else { hs_pop |= TWL4030_EXTMUTE; twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); @@ -808,9 +805,6 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) if (pdata && pdata->hs_extmute) { if (gpio_is_valid(pdata->hs_extmute_gpio)) { gpio_set_value(pdata->hs_extmute_gpio, 0); - } else if (pdata->set_hs_extmute) { - dev_warn(codec->dev, "set_hs_extmute is deprecated\n"); - pdata->set_hs_extmute(0); } else { hs_pop &= ~TWL4030_EXTMUTE; twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); -- cgit v1.2.3-70-g09d2