ASoC: AQT1000: Add API for adjusting the micbias voltage on AQT1000

AQT1000 codec supports multiple micbias voltage settings. Add an
API to client modules to adjust the micbias voltage based on their
desire voltage requirements.

Change-Id: If89b836ab60b66e9ec1000fe6d07f4b1a8484b01
Signed-off-by: Sudheer Papothi <spapothi@codeaurora.org>
Tento commit je obsažen v:
Sudheer Papothi
2017-12-29 02:12:47 +05:30
rodič db20f92cb3
revize 7c53cb5010
2 změnil soubory, kde provedl 105 přidání a 0 odebrání

Zobrazit soubor

@@ -35,6 +35,7 @@
#include <sound/info.h>
#include "aqt1000-registers.h"
#include "aqt1000.h"
#include "aqt1000-api.h"
#include "aqt1000-routing.h"
#include "../wcdcal-hwdep.h"
#include "aqt1000-internal.h"
@@ -46,6 +47,7 @@
#define CF_MIN_3DB_150HZ 0x2
#define AQT_VERSION_ENTRY_SIZE 17
#define AQT_VOUT_CTL_TO_MICB(x) (1000 + x *50)
static struct interp_sample_rate sr_val_tbl[] = {
{8000, 0x0}, {16000, 0x1}, {32000, 0x3}, {48000, 0x4}, {96000, 0x5},
@@ -682,6 +684,81 @@ static int aqt_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
return 0;
}
/*
* aqt_mbhc_micb_adjust_voltage: adjust specific micbias voltage
* @codec: handle to snd_soc_codec *
* @req_volt: micbias voltage to be set
* @micb_num: micbias to be set, e.g. micbias1 or micbias2
*
* return 0 if adjustment is success or error code in case of failure
*/
int aqt_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec,
int req_volt, int micb_num)
{
struct aqt1000 *aqt;
int cur_vout_ctl, req_vout_ctl;
int micb_reg, micb_val, micb_en;
int ret = 0;
if (!codec) {
pr_err("%s: Invalid codec pointer\n", __func__);
return -EINVAL;
}
if (micb_num != MIC_BIAS_1)
return -EINVAL;
else
micb_reg = AQT1000_ANA_MICB1;
aqt = snd_soc_codec_get_drvdata(codec);
mutex_lock(&aqt->micb_lock);
/*
* If requested micbias voltage is same as current micbias
* voltage, then just return. Otherwise, adjust voltage as
* per requested value. If micbias is already enabled, then
* to avoid slow micbias ramp-up or down enable pull-up
* momentarily, change the micbias value and then re-enable
* micbias.
*/
micb_val = snd_soc_read(codec, micb_reg);
micb_en = (micb_val & 0xC0) >> 6;
cur_vout_ctl = micb_val & 0x3F;
req_vout_ctl = aqt_get_micb_vout_ctl_val(req_volt);
if (req_vout_ctl < 0) {
ret = -EINVAL;
goto exit;
}
if (cur_vout_ctl == req_vout_ctl) {
ret = 0;
goto exit;
}
dev_dbg(codec->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n",
__func__, micb_num, AQT_VOUT_CTL_TO_MICB(cur_vout_ctl),
req_volt, micb_en);
if (micb_en == 0x1)
snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80);
snd_soc_update_bits(codec, micb_reg, 0x3F, req_vout_ctl);
if (micb_en == 0x1) {
snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40);
/*
* Add 2ms delay as per HW requirement after enabling
* micbias
*/
usleep_range(2000, 2100);
}
exit:
mutex_unlock(&aqt->micb_lock);
return ret;
}
EXPORT_SYMBOL(aqt_mbhc_micb_adjust_voltage);
/*
* aqt_micbias_control: enable/disable micbias
* @codec: handle to snd_soc_codec *