Merge "ASoC: AQT1000: Add API for adjusting the micbias voltage on AQT1000"
This commit is contained in:
commit
b7da83b2b8
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