Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7da83b2 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

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

parents c7e05720 7c53cb50
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
/* 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 */
+77 −0
Original line number Diff line number Diff line
@@ -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 *