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

Commit e6cc518d 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 support for MBHC hardware in AQT1000 codec"

parents b7da83b2 40270c47
Loading
Loading
Loading
Loading
+0 −11
Original line number Original line Diff line number Diff line
@@ -97,17 +97,6 @@ enum {
	ANC_MIC_AMIC3,
	ANC_MIC_AMIC3,
};
};


enum {
	MIC_BIAS_1 = 1,
};

enum {
	MICB_PULLUP_ENABLE,
	MICB_PULLUP_DISABLE,
	MICB_ENABLE,
	MICB_DISABLE,
};

enum {
enum {
	INTn_1_INP_SEL_ZERO = 0,
	INTn_1_INP_SEL_ZERO = 0,
	INTn_1_INP_SEL_DEC0,
	INTn_1_INP_SEL_DEC0,
+232 −307

File changed.

Preview size limit exceeded, changes collapsed.

+13 −26
Original line number Original line Diff line number Diff line
/*
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * 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
 * it under the terms of the GNU General Public License version 2 and
@@ -10,45 +9,32 @@
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * GNU General Public License for more details.
 */
 */
#ifndef __AQT_MBHC_H__
#ifndef __AQT1000_MBHC_H__
#define __AQT_MBHC_H__
#define __AQT1000_MBHC_H__
#include "../wcd-mbhc-v2.h"
#include "../wcd-mbhc-v2.h"


enum aqt_on_demand_supply_name {
struct aqt1000_mbhc {
	AQT_ON_DEMAND_MICBIAS = 0,
	AQT_ON_DEMAND_SUPPLIES_MAX,
};

struct aqt_on_demand_supply {
	struct regulator *supply;
	int ondemand_supply_count;
};

struct aqt_mbhc {
	struct wcd_mbhc wcd_mbhc;
	struct wcd_mbhc wcd_mbhc;
	struct blocking_notifier_head notifier;
	struct blocking_notifier_head notifier;
	struct aqt_on_demand_supply on_demand_list[
			AQT_ON_DEMAND_SUPPLIES_MAX];
	struct aqt1000 *aqt;
	struct aqt1000 *aqt;
	struct fw_info *fw_data;
	struct fw_info *fw_data;
	bool mbhc_started;
	bool mbhc_started;
	bool is_hph_recover;
};
};


#if IS_ENABLED(CONFIG_SND_SOC_AQT_MBHC)
#if IS_ENABLED(CONFIG_SND_SOC_AQT1000)
extern int aqt_mbhc_init(struct aqt_mbhc **mbhc,
extern int aqt_mbhc_init(struct aqt1000_mbhc **mbhc,
			   struct snd_soc_codec *codec,
			   struct snd_soc_codec *codec,
			   struct fw_info *fw_data);
			   struct fw_info *fw_data);
extern void aqt_mbhc_hs_detect_exit(struct snd_soc_codec *codec);
extern void aqt_mbhc_hs_detect_exit(struct snd_soc_codec *codec);
extern int aqt_mbhc_hs_detect(struct snd_soc_codec *codec,
extern int aqt_mbhc_hs_detect(struct snd_soc_codec *codec,
				struct wcd_mbhc_config *mbhc_cfg);
				struct wcd_mbhc_config *mbhc_cfg);
extern void aqt_mbhc_deinit(struct snd_soc_codec *codec);
extern void aqt_mbhc_deinit(struct snd_soc_codec *codec);
extern int aqt_mbhc_post_ssr_init(struct aqt_mbhc *mbhc,
extern int aqt_mbhc_post_ssr_init(struct aqt1000_mbhc *mbhc,
				    struct snd_soc_codec *codec);
				    struct snd_soc_codec *codec);
extern int aqt_mbhc_get_impedance(struct aqt_mbhc *aqt_mbhc,
extern int aqt_mbhc_get_impedance(struct aqt1000_mbhc *aqt_mbhc,
				    uint32_t *zl, uint32_t *zr);
				    uint32_t *zl, uint32_t *zr);
#else
#else
static inline int aqt_mbhc_init(struct aqt_mbhc **mbhc,
static inline int aqt_mbhc_init(struct aqt1000_mbhc **mbhc,
				  struct snd_soc_codec *codec,
				  struct snd_soc_codec *codec,
				  struct fw_info *fw_data)
				  struct fw_info *fw_data)
{
{
@@ -65,12 +51,13 @@ static inline int aqt_mbhc_hs_detect(struct snd_soc_codec *codec,
static inline void aqt_mbhc_deinit(struct snd_soc_codec *codec)
static inline void aqt_mbhc_deinit(struct snd_soc_codec *codec)
{
{
}
}
static inline int aqt_mbhc_post_ssr_init(struct aqt_mbhc *mbhc,
static inline int aqt_mbhc_post_ssr_init(struct aqt1000_mbhc *mbhc,
					   struct snd_soc_codec *codec)
					   struct snd_soc_codec *codec)
{
{
	return 0;
	return 0;
}
}
static inline int aqt_mbhc_get_impedance(struct aqt_mbhc *aqt_mbhc,

static inline int aqt_mbhc_get_impedance(struct aqt1000_mbhc *aqt_mbhc,
					   uint32_t *zl, uint32_t *zr)
					   uint32_t *zl, uint32_t *zr)
{
{
	if (zl)
	if (zl)
@@ -81,4 +68,4 @@ static inline int aqt_mbhc_get_impedance(struct aqt_mbhc *aqt_mbhc,
}
}
#endif
#endif


#endif /* __AQT_MBHC_H__ */
#endif /* __AQT1000_MBHC_H__ */
+71 −0
Original line number Original line Diff line number Diff line
@@ -36,6 +36,7 @@
#include "aqt1000-registers.h"
#include "aqt1000-registers.h"
#include "aqt1000.h"
#include "aqt1000.h"
#include "aqt1000-api.h"
#include "aqt1000-api.h"
#include "aqt1000-mbhc.h"
#include "aqt1000-routing.h"
#include "aqt1000-routing.h"
#include "../wcdcal-hwdep.h"
#include "../wcdcal-hwdep.h"
#include "aqt1000-internal.h"
#include "aqt1000-internal.h"
@@ -812,7 +813,15 @@ int aqt_micbias_control(struct snd_soc_codec *codec,
		aqt->micb_ref++;
		aqt->micb_ref++;
		if (aqt->micb_ref == 1) {
		if (aqt->micb_ref == 1) {
			snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40);
			snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40);
			if (post_on_event && aqt->mbhc)
				blocking_notifier_call_chain(
						&aqt->mbhc->notifier,
						post_on_event,
						&aqt->mbhc->wcd_mbhc);
		}
		}
		if (is_dapm && post_dapm_on && aqt->mbhc)
			blocking_notifier_call_chain(&aqt->mbhc->notifier,
					post_dapm_on, &aqt->mbhc->wcd_mbhc);
		break;
		break;
	case MICB_DISABLE:
	case MICB_DISABLE:
		if (aqt->micb_ref > 0)
		if (aqt->micb_ref > 0)
@@ -822,8 +831,21 @@ int aqt_micbias_control(struct snd_soc_codec *codec,
			snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80);
			snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80);
		else if ((aqt->micb_ref == 0) &&
		else if ((aqt->micb_ref == 0) &&
			 (aqt->pullup_ref == 0)) {
			 (aqt->pullup_ref == 0)) {
			if (pre_off_event && aqt->mbhc)
				blocking_notifier_call_chain(
						&aqt->mbhc->notifier,
						pre_off_event,
						&aqt->mbhc->wcd_mbhc);
			snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00);
			snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00);
			if (post_off_event && aqt->mbhc)
				blocking_notifier_call_chain(
						&aqt->mbhc->notifier,
						post_off_event,
						&aqt->mbhc->wcd_mbhc);
		}
		}
		if (is_dapm && post_dapm_off && aqt->mbhc)
			blocking_notifier_call_chain(&aqt->mbhc->notifier,
					post_dapm_off, &aqt->mbhc->wcd_mbhc);
		break;
		break;
	default:
	default:
		dev_err(codec->dev, "%s: Invalid micbias request: %d\n",
		dev_err(codec->dev, "%s: Invalid micbias request: %d\n",
@@ -2063,6 +2085,8 @@ static int aqt_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
	int hph_mode = aqt->hph_mode;
	int hph_mode = aqt->hph_mode;
	u8 dem_inp;
	u8 dem_inp;
	int ret = 0;
	int ret = 0;
	uint32_t impedl = 0;
	uint32_t impedr = 0;


	dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__,
	dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__,
		w->name, event, hph_mode);
		w->name, event, hph_mode);
@@ -2096,6 +2120,17 @@ static int aqt_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
			snd_soc_update_bits(codec,
			snd_soc_update_bits(codec,
					    AQT1000_CDC_RX1_RX_PATH_CFG0,
					    AQT1000_CDC_RX1_RX_PATH_CFG0,
					    0x10, 0x10);
					    0x10, 0x10);

		ret = aqt_mbhc_get_impedance(aqt->mbhc,
					       &impedl, &impedr);
		if (!ret) {
			aqt_clsh_imped_config(codec, impedl, false);
			set_bit(CLSH_Z_CONFIG, &aqt->status_mask);
		} else {
			dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n",
				__func__, ret);
			ret = 0;
		}
		break;
		break;
	case SND_SOC_DAPM_POST_PMD:
	case SND_SOC_DAPM_POST_PMD:
		/* 1000us required as per HW requirement */
		/* 1000us required as per HW requirement */
@@ -2104,6 +2139,10 @@ static int aqt_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
			     AQT_CLSH_EVENT_POST_PA,
			     AQT_CLSH_EVENT_POST_PA,
			     AQT_CLSH_STATE_HPHL,
			     AQT_CLSH_STATE_HPHL,
			     hph_mode);
			     hph_mode);
		if (test_bit(CLSH_Z_CONFIG, &aqt->status_mask)) {
			aqt_clsh_imped_config(codec, impedl, true);
			clear_bit(CLSH_Z_CONFIG, &aqt->status_mask);
		}
		break;
		break;
	default:
	default:
		break;
		break;
@@ -2259,6 +2298,9 @@ static int aqt_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
		aqt_codec_override(codec, aqt->hph_mode, event);
		aqt_codec_override(codec, aqt->hph_mode, event);
		break;
		break;
	case SND_SOC_DAPM_PRE_PMD:
	case SND_SOC_DAPM_PRE_PMD:
		blocking_notifier_call_chain(&aqt->mbhc->notifier,
					     AQT_EVENT_PRE_HPHR_PA_OFF,
					     &aqt->mbhc->wcd_mbhc);
		snd_soc_update_bits(codec, AQT1000_HPH_R_TEST, 0x01, 0x00);
		snd_soc_update_bits(codec, AQT1000_HPH_R_TEST, 0x01, 0x00);
		snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_CTL,
		snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_CTL,
				    0x10, 0x10);
				    0x10, 0x10);
@@ -2277,6 +2319,9 @@ static int aqt_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
		else
		else
			usleep_range(5000, 5100);
			usleep_range(5000, 5100);
		aqt_codec_override(codec, aqt->hph_mode, event);
		aqt_codec_override(codec, aqt->hph_mode, event);
		blocking_notifier_call_chain(&aqt->mbhc->notifier,
					     AQT_EVENT_POST_HPHR_PA_OFF,
					     &aqt->mbhc->wcd_mbhc);
		if (!(strcmp(w->name, "AQT ANC HPHR PA"))) {
		if (!(strcmp(w->name, "AQT ANC HPHR PA"))) {
			ret = aqt_codec_enable_anc(w, kcontrol, event);
			ret = aqt_codec_enable_anc(w, kcontrol, event);
			snd_soc_update_bits(codec,
			snd_soc_update_bits(codec,
@@ -2379,6 +2424,9 @@ static int aqt_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
		aqt_codec_override(codec, aqt->hph_mode, event);
		aqt_codec_override(codec, aqt->hph_mode, event);
		break;
		break;
	case SND_SOC_DAPM_PRE_PMD:
	case SND_SOC_DAPM_PRE_PMD:
		blocking_notifier_call_chain(&aqt->mbhc->notifier,
					     AQT_EVENT_PRE_HPHL_PA_OFF,
					     &aqt->mbhc->wcd_mbhc);
		snd_soc_update_bits(codec, AQT1000_HPH_L_TEST, 0x01, 0x00);
		snd_soc_update_bits(codec, AQT1000_HPH_L_TEST, 0x01, 0x00);
		snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CTL,
		snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CTL,
				    0x10, 0x10);
				    0x10, 0x10);
@@ -2398,6 +2446,9 @@ static int aqt_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
		else
		else
			usleep_range(5000, 5100);
			usleep_range(5000, 5100);
		aqt_codec_override(codec, aqt->hph_mode, event);
		aqt_codec_override(codec, aqt->hph_mode, event);
		blocking_notifier_call_chain(&aqt->mbhc->notifier,
					     AQT_EVENT_POST_HPHL_PA_OFF,
					     &aqt->mbhc->wcd_mbhc);
		if (!(strcmp(w->name, "AQT ANC HPHL PA"))) {
		if (!(strcmp(w->name, "AQT ANC HPHL PA"))) {
			ret = aqt_codec_enable_anc(w, kcontrol, event);
			ret = aqt_codec_enable_anc(w, kcontrol, event);
			snd_soc_update_bits(codec,
			snd_soc_update_bits(codec,
@@ -3247,6 +3298,14 @@ static int aqt_soc_codec_probe(struct snd_soc_codec *codec)
	set_bit(WCD9XXX_ANC_CAL, aqt->fw_data->cal_bit);
	set_bit(WCD9XXX_ANC_CAL, aqt->fw_data->cal_bit);
	set_bit(WCD9XXX_MBHC_CAL, aqt->fw_data->cal_bit);
	set_bit(WCD9XXX_MBHC_CAL, aqt->fw_data->cal_bit);


	/* Register for Clock */
	aqt->ext_clk = clk_get(aqt->dev, "aqt_clk");
	if (IS_ERR(aqt->ext_clk)) {
		dev_err(aqt->dev, "%s: clk get %s failed\n",
			__func__, "aqt_ext_clk");
		goto err_clk;
	}

	ret = wcd_cal_create_hwdep(aqt->fw_data,
	ret = wcd_cal_create_hwdep(aqt->fw_data,
				   AQT1000_CODEC_HWDEP_NODE, codec);
				   AQT1000_CODEC_HWDEP_NODE, codec);
	if (ret < 0) {
	if (ret < 0) {
@@ -3254,6 +3313,12 @@ static int aqt_soc_codec_probe(struct snd_soc_codec *codec)
		goto err_hwdep;
		goto err_hwdep;
	}
	}


	/* Initialize MBHC module */
	ret = aqt_mbhc_init(&aqt->mbhc, codec, aqt->fw_data);
	if (ret) {
		pr_err("%s: mbhc initialization failed\n", __func__);
		goto err_hwdep;
	}
	aqt->codec = codec;
	aqt->codec = codec;
	for (i = 0; i < COMPANDER_MAX; i++)
	for (i = 0; i < COMPANDER_MAX; i++)
		aqt->comp_enabled[i] = 0;
		aqt->comp_enabled[i] = 0;
@@ -3317,6 +3382,8 @@ static int aqt_soc_codec_probe(struct snd_soc_codec *codec)
	return ret;
	return ret;


err_hwdep:
err_hwdep:
	clk_put(aqt->ext_clk);
err_clk:
	devm_kfree(codec->dev, aqt->fw_data);
	devm_kfree(codec->dev, aqt->fw_data);
	aqt->fw_data = NULL;
	aqt->fw_data = NULL;
err:
err:
@@ -3329,8 +3396,12 @@ static int aqt_soc_codec_remove(struct snd_soc_codec *codec)
{
{
	struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
	struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);


	/* Deinitialize MBHC module */
	aqt_mbhc_deinit(codec);
	aqt->mbhc = NULL;
	mutex_destroy(&aqt->i2s_lock);
	mutex_destroy(&aqt->i2s_lock);
	mutex_destroy(&aqt->codec_mutex);
	mutex_destroy(&aqt->codec_mutex);
	clk_put(aqt->ext_clk);


	return 0;
	return 0;
}
}
+9 −3
Original line number Original line Diff line number Diff line
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * 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
 * it under the terms of the GNU General Public License version 2 and
@@ -1274,7 +1274,10 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc)
	WCD_MBHC_RSC_LOCK(mbhc);
	WCD_MBHC_RSC_LOCK(mbhc);


	/* enable HS detection */
	/* enable HS detection */
	if (mbhc->mbhc_cb->hph_pull_up_control)
	if (mbhc->mbhc_cb->hph_pull_up_control_v2)
		mbhc->mbhc_cb->hph_pull_up_control_v2(codec,
						      HS_PULLUP_I_DEFAULT);
	else if (mbhc->mbhc_cb->hph_pull_up_control)
		mbhc->mbhc_cb->hph_pull_up_control(codec, I_DEFAULT);
		mbhc->mbhc_cb->hph_pull_up_control(codec, I_DEFAULT);
	else
	else
		WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, 3);
		WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, 3);
@@ -1291,7 +1294,10 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc)
		mbhc->hphl_swh = 1;
		mbhc->hphl_swh = 1;
		mbhc->gnd_swh = 1;
		mbhc->gnd_swh = 1;


		if (mbhc->mbhc_cb->hph_pull_up_control)
		if (mbhc->mbhc_cb->hph_pull_up_control_v2)
			mbhc->mbhc_cb->hph_pull_up_control_v2(codec,
							      HS_PULLUP_I_OFF);
		else if (mbhc->mbhc_cb->hph_pull_up_control)
			mbhc->mbhc_cb->hph_pull_up_control(codec, I_OFF);
			mbhc->mbhc_cb->hph_pull_up_control(codec, I_OFF);
		else
		else
			WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_L_DET_PULL_UP_CTRL,
			WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_L_DET_PULL_UP_CTRL,
Loading