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>
This commit is contained in:
parent
db20f92cb3
commit
7c53cb5010
2 changed files with 105 additions and 0 deletions
28
asoc/codecs/aqt1000/aqt1000-api.h
Normal file
28
asoc/codecs/aqt1000/aqt1000-api.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* Copyright (c) 2018, 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
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef AQT1000_API_H
|
||||
#define AQT1000_API_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
extern int aqt_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec,
|
||||
int volt, int micb_num);
|
||||
extern int aqt_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable);
|
||||
extern int aqt_get_micb_vout_ctl_val(u32 micb_mv);
|
||||
extern int aqt_micbias_control(struct snd_soc_codec *codec, int micb_num,
|
||||
int req, bool is_dapm);
|
||||
|
||||
#endif /* AQT1000_API_H */
|
|
@ -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 *
|
||||
|
|
Loading…
Add table
Reference in a new issue