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

Commit fbc1f4eb 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: Avoid query temp during suspend" into audio-drivers.lnx.3.0

parents 5f1a17dd c9dd3be3
Loading
Loading
Loading
Loading
+46 −1
Original line number Diff line number Diff line
/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
/* Copyright (c) 2015, 2017-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
@@ -12,6 +12,7 @@

#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/suspend.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/thermal.h>
@@ -61,6 +62,20 @@ int wsa881x_get_temp(struct thermal_zone_device *thermal,
		pr_err("%s: pdata is NULL\n", __func__);
		return -EINVAL;
	}
	if (atomic_cmpxchg(&pdata->is_suspend_spk, 1, 0)) {
		/*
		 * get_temp query happens as part of POST_PM_SUSPEND
		 * from thermal core. To avoid calls to slimbus
		 * as part of this thermal query, return default temp
		 * and reset the suspend flag.
		 */
		if (!pdata->t0_init) {
			if (temp)
				*temp = pdata->curr_temp;
			return 0;
		}
	}

temp_retry:
	if (pdata->wsa_temp_reg_read) {
		ret = pdata->wsa_temp_reg_read(codec, &reg);
@@ -108,6 +123,8 @@ int wsa881x_get_temp(struct thermal_zone_device *thermal,
			goto temp_retry;
		}
	}
	pdata->curr_temp = temp_val;

	if (temp)
		*temp = temp_val;
	pr_debug("%s: t0 measured: %d dmeas = %d, d1 = %d, d2 = %d\n",
@@ -120,6 +137,23 @@ static struct thermal_zone_device_ops wsa881x_thermal_ops = {
	.get_temp = wsa881x_get_temp,
};


static int wsa881x_pm_notify(struct notifier_block *nb,
				unsigned long mode, void *_unused)
{
	struct wsa881x_tz_priv *pdata =
			container_of(nb, struct wsa881x_tz_priv, pm_nb);

	switch (mode) {
	case PM_SUSPEND_PREPARE:
		atomic_set(&pdata->is_suspend_spk, 1);
		break;
	default:
		break;
	}
	return 0;
}

int wsa881x_init_thermal(struct wsa881x_tz_priv *tz_pdata)
{
	struct thermal_zone_device *tz_dev;
@@ -137,12 +171,23 @@ int wsa881x_init_thermal(struct wsa881x_tz_priv *tz_pdata)
		return -EINVAL;
	}
	tz_pdata->tz_dev = tz_dev;
	tz_pdata->pm_nb.notifier_call = wsa881x_pm_notify;
	register_pm_notifier(&tz_pdata->pm_nb);
	atomic_set(&tz_pdata->is_suspend_spk, 0);

	return 0;
}
EXPORT_SYMBOL(wsa881x_init_thermal);

void wsa881x_deinit_thermal(struct thermal_zone_device *tz_dev)
{
	struct wsa881x_tz_priv *pdata;

	if (tz_dev && tz_dev->devdata) {
		pdata = tz_dev->devdata;
		if (pdata)
			unregister_pm_notifier(&pdata->pm_nb);
	}
	if (tz_dev)
		thermal_zone_device_unregister(tz_dev);
}
+5 −1
Original line number Diff line number Diff line
/* Copyright (c) 2015, 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
 * it under the terms of the GNU General Public License version 2 and
@@ -31,6 +31,10 @@ struct wsa881x_tz_priv {
	struct wsa_temp_register *wsa_temp_reg;
	char name[80];
	wsa_temp_register_read wsa_temp_reg_read;
	struct notifier_block pm_nb;
	atomic_t is_suspend_spk;
	int t0_init;
	int curr_temp;
};

int wsa881x_get_temp(struct thermal_zone_device *tz_dev, int *temp);
+28 −0
Original line number Diff line number Diff line
@@ -200,12 +200,40 @@ static int wsa881x_set_mute(struct snd_kcontrol *kcontrol,
	return 0;
}

static int wsa881x_get_t0_init(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{

	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
	struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec);
	struct wsa881x_tz_priv *pdata = &wsa881x->tz_pdata;

	ucontrol->value.integer.value[0] = pdata->t0_init;
	dev_dbg(codec->dev, "%s: t0 init %d\n", __func__, pdata->t0_init);

	return 0;
}

static int wsa881x_set_t0_init(struct snd_kcontrol *kcontrol,
			       struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
	struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec);
	struct wsa881x_tz_priv *pdata = &wsa881x->tz_pdata;

	pdata->t0_init = ucontrol->value.integer.value[0];
	dev_dbg(codec->dev, "%s: t0 init %d\n", __func__, pdata->t0_init);

	return 0;
}

static const struct snd_kcontrol_new wsa_snd_controls[] = {
	SOC_ENUM_EXT("WSA PA Gain", wsa_pa_gain_enum,
		     wsa_pa_gain_get, wsa_pa_gain_put),
	SOC_SINGLE_EXT("WSA PA Mute", SND_SOC_NOPM, 0, 1, 0,
		wsa881x_get_mute, wsa881x_set_mute),
	SOC_SINGLE_EXT("WSA T0 Init", SND_SOC_NOPM, 0, 1, 0,
		wsa881x_get_t0_init, wsa881x_set_t0_init),
};

static int codec_debug_open(struct inode *inode, struct file *file)