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

Commit 8194f4e6 authored by Yeleswarapu Nagaradhesh's avatar Yeleswarapu Nagaradhesh
Browse files

ASoC: wcd: change classh settings as per impedance value



Depending on the impedance across HPHL and HPHR, set classh
configurations so as to avoid false OCP events.
Move wcd9xxx_registers.h to uapi folder, as this header
file is used by userspace for tomtom codec.

CRs-Fixed: 963843
Change-Id: Ie2fb4b75b7f74013580bd3912372c64ddefc734e
Signed-off-by: default avatarYeleswarapu Nagaradhesh <nagaradh@codeaurora.org>
parent d3068532
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
header-y += wcd9xxx_registers.h
header-y += wcd9320_registers.h
+9 −0
Original line number Diff line number Diff line
@@ -341,4 +341,13 @@
#define WCD9XXX_CDC_RX2_RX_PATH_CTL			(0xB69)
#define WCD9XXX_CDC_CLK_RST_CTRL_MCLK_CONTROL		(0xD41)
#define WCD9XXX_CLASSH_CTRL_CCL_1                       (0x69C)

/* RX Gain control registers of codecs from and above WCD9335 */
#define WCD9XXX_CDC_RX1_RX_VOL_CTL			(0xB59)
#define WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL			(0xB5C)
#define WCD9XXX_CDC_RX1_RX_PATH_SEC1			(0xB5E)
#define WCD9XXX_CDC_RX2_RX_VOL_CTL			(0xB6D)
#define WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL			(0xB70)
#define WCD9XXX_CDC_RX2_RX_PATH_SEC1			(0xB72)

#endif
+22 −1
Original line number Diff line number Diff line
@@ -345,6 +345,7 @@ enum {
	CPE_NOMINAL,
	HPH_PA_DELAY,
	SB_CLK_GEAR,
	CLASSH_CONFIG,
};

enum {
@@ -4157,6 +4158,7 @@ static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
	int hph_mode = tasha->hph_mode;
	u8 dem_inp;
	int ret = 0;
	uint32_t impedl, impedr;

	dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__,
		w->name, event, hph_mode);
@@ -4190,6 +4192,16 @@ static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
			snd_soc_update_bits(codec,
				WCD9335_CDC_RX1_RX_PATH_CFG0, 0x10, 0x10);

		ret = wcd_mbhc_get_impedance(&tasha->mbhc,
					&impedl, &impedr);
		if (!ret) {
			wcd_clsh_imped_config(codec, impedl, false);
			set_bit(CLASSH_CONFIG, &tasha->status_mask);
		} else
			dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n",
						__func__, ret);


		break;
	case SND_SOC_DAPM_POST_PMU:
		/* 1000us required as per HW requirement */
@@ -4219,6 +4231,15 @@ static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
			     WCD_CLSH_STATE_HPHL,
			     ((hph_mode == CLS_H_LOHIFI) ?
			       CLS_H_HIFI : hph_mode));

		if (test_bit(CLASSH_CONFIG, &tasha->status_mask)) {
			wcd_clsh_imped_config(codec, impedl, true);
			clear_bit(CLASSH_CONFIG, &tasha->status_mask);
		} else
			dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n",
						__func__, ret);


		break;
	};

@@ -11582,7 +11603,7 @@ static const struct tasha_reg_mask_val tasha_codec_reg_init_val_2_0[] = {
	{WCD9335_RCO_CTRL_2, 0x0F, 0x08},
	{WCD9335_RX_BIAS_FLYB_MID_RST, 0xF0, 0x10},
	{WCD9335_FLYBACK_CTRL_1, 0x20, 0x20},
	{WCD9335_HPH_OCP_CTL, 0xFF, 0x5A},
	{WCD9335_HPH_OCP_CTL, 0xFF, 0x7A},
	{WCD9335_HPH_L_TEST, 0x01, 0x01},
	{WCD9335_HPH_R_TEST, 0x01, 0x01},
	{WCD9335_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12},
+152 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include "wcd9xxx-common-v2.h"

#define WCD_USLEEP_RANGE 50
#define MAX_IMPED_PARAMS 6

enum {
	DAC_GAIN_0DB = 0,
@@ -49,10 +50,161 @@ enum {
	DELTA_I_50MA,
};

struct wcd_imped_val {
	u32 imped_val;
	u8 index;
};

static const struct wcd_reg_mask_val imped_table[][MAX_IMPED_PARAMS] = {
	{
		{WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xf5},
		{WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf5},
		{WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01},
		{WCD9XXX_CDC_RX2_RX_VOL_CTL , 0xff, 0xf5},
		{WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf5},
		{WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01},
	},
	{
		{WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xf7},
		{WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf7},
		{WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01},
		{WCD9XXX_CDC_RX2_RX_VOL_CTL , 0xff, 0xf7},
		{WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf7},
		{WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01},
	},
	{
		{WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xf9},
		{WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf9},
		{WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x0},
		{WCD9XXX_CDC_RX2_RX_VOL_CTL , 0xff, 0xf9},
		{WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf9},
		{WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x0},
	},
	{
		{WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xfa},
		{WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfa},
		{WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01},
		{WCD9XXX_CDC_RX2_RX_VOL_CTL , 0xff, 0xfa},
		{WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfa},
		{WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01},
	},
	{
		{WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xfb},
		{WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfb},
		{WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01},
		{WCD9XXX_CDC_RX2_RX_VOL_CTL , 0xff, 0xfb},
		{WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfb},
		{WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01},
	},
	{
		{WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xfc},
		{WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfc},
		{WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01},
		{WCD9XXX_CDC_RX2_RX_VOL_CTL , 0xff, 0xfc},
		{WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfc},
		{WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01},
	},
	{
		{WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xfd},
		{WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd},
		{WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01},
		{WCD9XXX_CDC_RX2_RX_VOL_CTL , 0xff, 0xfd},
		{WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfd},
		{WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01},
	},
	{
		{WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xfe},
		{WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfe},
		{WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01},
		{WCD9XXX_CDC_RX2_RX_VOL_CTL , 0xff, 0xfe},
		{WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfe},
		{WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01},
	},
	{
		{WCD9XXX_CDC_RX1_RX_VOL_CTL, 0xff, 0xff},
		{WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xff},
		{WCD9XXX_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00},
		{WCD9XXX_CDC_RX2_RX_VOL_CTL , 0xff, 0xff},
		{WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xff},
		{WCD9XXX_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00},
	},
};

static const struct wcd_imped_val imped_index[] = {
	{4, 0},
	{5, 1},
	{6, 2},
	{7, 3},
	{8, 4},
	{9, 5},
	{10, 6},
	{11, 7},
	{12, 8},
	{13, 9},
};

static void (*clsh_state_fp[NUM_CLSH_STATES_V2])(struct snd_soc_codec *,
					      struct wcd_clsh_cdc_data *,
					      u8 req_state, bool en, int mode);

static int get_impedance_index(int imped)
{
	int i = 0;

	if (imped < imped_index[i].imped_val) {
		pr_debug("%s, detected impedance is less than 4 Ohm\n",
				__func__);
		i = 0;
		goto ret;
	}
	if (imped >= imped_index[ARRAY_SIZE(imped_index) - 1].imped_val) {
		pr_debug("%s, detected impedance is greater than 12 Ohm\n",
				__func__);
		i = ARRAY_SIZE(imped_index) - 1;
		goto ret;
	}
	for (i = 0; i < ARRAY_SIZE(imped_index) - 1; i++) {
		if (imped >= imped_index[i].imped_val &&
			imped < imped_index[i + 1].imped_val)
			break;
	}
ret:
	pr_debug("%s: selected impedance index = %d\n",
			__func__, imped_index[i].index);
	return imped_index[i].index;
}

/*
 * Function: wcd_clsh_imped_config
 * Params: codec, imped, reset
 * Description:
 * This function updates HPHL and HPHR gain settings
 * according to the impedance value.
 */
void wcd_clsh_imped_config(struct snd_soc_codec *codec, int imped, bool reset)
{
	int i;
	int index = 0;

	/* reset = 1, which means request is to reset the register values */
	if (reset) {
		for (i = 0; i < MAX_IMPED_PARAMS; i++)
			snd_soc_update_bits(codec, imped_table[index][i].reg,
				imped_table[index][i].mask, 0);
		return;
	}
	index = get_impedance_index(imped);
	if (index >= ARRAY_SIZE(imped_index)) {
		pr_debug("%s, impedance not in range = %d\n", __func__, imped);
		return;
	}
	for (i = 0; i < MAX_IMPED_PARAMS; i++)
		snd_soc_update_bits(codec, imped_table[index][i].reg,
				imped_table[index][i].mask,
				imped_table[index][i].val);
}
EXPORT_SYMBOL(wcd_clsh_imped_config);

static bool is_native_44_1_active(struct snd_soc_codec *codec)
{
	bool native_active = false;
+9 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2016, 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
@@ -136,6 +136,12 @@ struct vbat_monitor_reg {
	u32 writes[MAX_VBAT_MONITOR_WRITES];
} __packed;

struct wcd_reg_mask_val {
	u16	reg;
	u8	mask;
	u8	val;
};

extern void wcd_clsh_fsm(struct snd_soc_codec *codec,
		struct wcd_clsh_cdc_data *cdc_clsh_d,
		u8 clsh_event, u8 req_state,
@@ -143,6 +149,8 @@ extern void wcd_clsh_fsm(struct snd_soc_codec *codec,

extern void wcd_clsh_init(struct wcd_clsh_cdc_data *clsh);
extern int wcd_clsh_get_clsh_state(struct wcd_clsh_cdc_data *clsh);
extern void wcd_clsh_imped_config(struct snd_soc_codec *codec, int imped,
		bool reset);

enum {
	RESERVED = 0,