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

Commit e2d23cf3 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-analog: ocp register update during playback"

parents 2f254f41 1dbd54de
Loading
Loading
Loading
Loading
+53 −3
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ struct wsa881x_pdata {
	int version;
	struct mutex bg_lock;
	struct mutex res_lock;
	struct delayed_work ocp_ctl_work;
};

enum {
@@ -72,6 +73,15 @@ enum {
	WSA881X_STATUS_I2C,
};

#define WSA881X_OCP_CTL_TIMER_SEC 2
#define WSA881X_OCP_CTL_TEMP_CELSIUS 25
#define WSA881X_OCP_CTL_POLL_TIMER_SEC 60

static int wsa881x_ocp_poll_timer_sec = WSA881X_OCP_CTL_POLL_TIMER_SEC;
module_param(wsa881x_ocp_poll_timer_sec, int,
		S_IRUGO | S_IWUSR | S_IWGRP);
MODULE_PARM_DESC(wsa881x_ocp_poll_timer_sec, "timer for ocp ctl polling");

static int32_t wsa881x_resource_acquire(struct snd_soc_codec *codec,
						bool enable);

@@ -483,12 +493,14 @@ 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);
		}
	}
@@ -780,20 +792,56 @@ static int wsa881x_rdac_event(struct snd_soc_dapm_widget *w,
	return 0;
}

static void wsa881x_ocp_ctl_work(struct work_struct *work)
{
	struct wsa881x_pdata *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_pdata, ocp_ctl_work);

	if (!wsa881x)
		return;

	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);

		schedule_delayed_work(&wsa881x->ocp_ctl_work,
			msecs_to_jiffies(wsa881x_ocp_poll_timer_sec * 1000));
}

static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w,
			struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_codec *codec = w->codec;
	struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec);

	pr_debug("%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);
		break;
	case SND_SOC_DAPM_POST_PMU:
		wsa881x_spkr_pa_ctrl(codec, true);
		schedule_delayed_work(&wsa881x->ocp_ctl_work,
			msecs_to_jiffies(WSA881X_OCP_CTL_TIMER_SEC * 1000));
		break;
	case SND_SOC_DAPM_PRE_PMD:
		wsa881x_spkr_pa_ctrl(codec, false);
		break;
	case SND_SOC_DAPM_POST_PMD:
		cancel_delayed_work_sync(&wsa881x->ocp_ctl_work);
		snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0xC0);
		break;
	default:
		pr_err("%s: invalid event:%d\n", __func__, event);
		return -EINVAL;
@@ -815,7 +863,9 @@ static const struct snd_soc_dapm_widget wsa881x_dapm_widgets[] = {

	SND_SOC_DAPM_PGA_S("WSA_SPKR PGA", 1, SND_SOC_NOPM, 0, 0,
			wsa881x_spkr_pa_event,
			SND_SOC_DAPM_POST_PMU |	SND_SOC_DAPM_PRE_PMD),
			SND_SOC_DAPM_PRE_PMU |
			SND_SOC_DAPM_POST_PMU |	SND_SOC_DAPM_PRE_PMD |
			SND_SOC_DAPM_POST_PMD),

	SND_SOC_DAPM_OUTPUT("WSA_SPKR"),
};
@@ -930,7 +980,6 @@ static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec,
	}
	wsa881x_resource_acquire(codec, true);

	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);
@@ -947,7 +996,6 @@ static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec,
	wsa_temp_reg->d2_msb = snd_soc_read(codec, WSA881X_OTP_REG_3);
	wsa_temp_reg->d2_lsb = snd_soc_read(codec, WSA881X_OTP_REG_4);

	snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x04, 0x00);
	wsa881x_resource_acquire(codec, false);

	return 0;
@@ -982,6 +1030,8 @@ static int wsa881x_probe(struct snd_soc_codec *codec)
						wsa881x_temp_reg_read;
	snd_soc_codec_set_drvdata(codec, &wsa_pdata[wsa881x_index]);
	wsa881x_init_thermal(&wsa_pdata[wsa881x_index].tz_pdata);
	INIT_DELAYED_WORK(&wsa_pdata[wsa881x_index].ocp_ctl_work,
				wsa881x_ocp_ctl_work);

	if (codec_conf->name_prefix) {
		widget_name = kcalloc(WIDGET_NAME_MAX_SIZE, sizeof(char),
+3 −0
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ const u8 wsa881x_ana_reg_readable[WSA881X_CACHE_SIZE] = {
	[WSA881X_CLOCK_CONFIG] = 1,
	[WSA881X_ANA_CTL] = 1,
	[WSA881X_SWR_RESET_EN] = 1,
	[WSA881X_RESET_CTL] = 1,
	[WSA881X_TADC_VALUE_CTL] = 1,
	[WSA881X_TEMP_DETECT_CTL] = 1,
	[WSA881X_TEMP_MSB] = 1,
	[WSA881X_TEMP_LSB] = 1,
@@ -66,6 +68,7 @@ const u8 wsa881x_ana_reg_readable[WSA881X_CACHE_SIZE] = {
	[WSA881X_TEMP_DEBUG_MSB] = 1,
	[WSA881X_TEMP_DEBUG_LSB] = 1,
	[WSA881X_SAMPLE_EDGE_SEL] = 1,
	[WSA881X_IOPAD_CTL] = 1,
	[WSA881X_SPARE_0] = 1,
	[WSA881X_SPARE_1] = 1,
	[WSA881X_SPARE_2] = 1,