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

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

Merge "ASoC: wsa881x: update ocp register based on temperature"

parents 67bdff96 dfc3a8e7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -281,6 +281,7 @@ static bool wsa881x_volatile_register(struct device *dev, unsigned int reg)
	case WSA881X_TEMP_DOUT_LSB:
	case WSA881X_TEMP_OP:
	case WSA881X_SPKR_PROT_SAR:
	case WSA881X_SPKR_OCP_CTL:
		return true;
	default:
		return false;
+32 −1
Original line number Diff line number Diff line
@@ -98,6 +98,7 @@ struct wsa881x_priv {
	struct snd_info_entry *entry;
	struct snd_info_entry *version_entry;
	int state;
	struct delayed_work ocp_ctl_work;
};

#define SWR_SLV_MAX_REG_ADDR	0x390
@@ -109,6 +110,8 @@ struct wsa881x_priv {
#define SWR_SLV_MAX_DEVICES	2

#define WSA881X_VERSION_ENTRY_SIZE 27
#define WSA881X_OCP_CTL_TIMER_SEC 2
#define WSA881X_OCP_CTL_TEMP_CELSIUS 25

static struct wsa881x_priv *dbgwsa881x;
static struct dentry *debugfs_wsa881x_dent;
@@ -487,12 +490,15 @@ static void wsa881x_bandgap_ctrl(struct snd_soc_codec *codec, bool enable)
					    0x08, 0x08);
			/* 400usec sleep is needed as per HW requirement */
			usleep_range(400, 410);
			snd_soc_update_bits(codec, WSA881X_TEMP_OP,
					    0x04, 0x04);
		}
	} else {
		--wsa881x->bg_cnt;
		if (wsa881x->bg_cnt <= 0) {
			WARN_ON(wsa881x->bg_cnt < 0);
			wsa881x->bg_cnt = 0;
			snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x04, 0x00);
			snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x08, 0x00);
		}
	}
@@ -738,6 +744,26 @@ static int wsa881x_ramp_pa_gain(struct snd_soc_codec *codec,
	return 0;
}

static void wsa881x_ocp_ctl_work(struct work_struct *work)
{
	struct wsa881x_priv *wsa881x;
	struct delayed_work *dwork;
	struct snd_soc_codec *codec;
	unsigned long temp_val;

	dwork = to_delayed_work(work);
	wsa881x = container_of(dwork, struct wsa881x_priv, ocp_ctl_work);

	codec = wsa881x->codec;
	wsa881x_get_temp(wsa881x->tz_pdata.tz_dev, &temp_val);
	dev_dbg(codec->dev, " temp = %ld\n", temp_val);

	if (temp_val <= WSA881X_OCP_CTL_TEMP_CELSIUS)
		snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0x00);
	else
		snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0xC0);
}

static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w,
			struct snd_kcontrol *kcontrol, int event)
{
@@ -747,6 +773,7 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w,
	dev_dbg(codec->dev, "%s: %s %d\n", __func__, w->name, event);
	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0x80);
		if (WSA881X_IS_2_0(wsa881x->version))
			regmap_multi_reg_write(wsa881x->regmap,
					wsa881x_pre_pmu_pa_2_0,
@@ -789,6 +816,8 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w,
					    0x07, 0x01);
			wsa881x_visense_adc_ctrl(codec, ENABLE);
		}
		schedule_delayed_work(&wsa881x->ocp_ctl_work,
			msecs_to_jiffies(WSA881X_OCP_CTL_TIMER_SEC * 1000));
		break;
	case SND_SOC_DAPM_POST_PMD:
		if (wsa881x->visense_enable) {
@@ -796,6 +825,8 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w,
			wsa881x_visense_txfe_ctrl(codec, DISABLE,
						0x00, 0x01, 0x01);
		}
		cancel_delayed_work_sync(&wsa881x->ocp_ctl_work);
		snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0xC0);
		break;
	}
	return 0;
@@ -940,7 +971,6 @@ static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec,
	regcache_sync(wsa881x->regmap);
	wsa881x_resource_acquire(codec, ENABLE);

	snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x04, 0x04);
	if (WSA881X_IS_2_0(wsa881x->version)) {
		snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x00);
		wsa_temp_reg->dmeas_msb = snd_soc_read(codec, WSA881X_TEMP_MSB);
@@ -984,6 +1014,7 @@ static int wsa881x_probe(struct snd_soc_codec *codec)
	wsa881x->tz_pdata.codec = codec;
	wsa881x->tz_pdata.wsa_temp_reg_read = wsa881x_temp_reg_read;
	wsa881x_init_thermal(&wsa881x->tz_pdata);
	INIT_DELAYED_WORK(&wsa881x->ocp_ctl_work, wsa881x_ocp_ctl_work);
	return 0;
}