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

Commit 6f0e2d72 authored by Sudheer Papothi's avatar Sudheer Papothi
Browse files

ASoC: wsa881x: Add support for temperature sensor



wsa881x has inbuilt temperature sensor. Temperature sensor
is used for speaker protection and over temperature protection.
Add support for temperature sensor in wsa881x driver.

Change-Id: I04de1301d3e107599ce9098231253265e86fc994
Signed-off-by: default avatarSudheer Papothi <spapothi@codeaurora.org>
parent 21bb23d1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -119,7 +119,7 @@ snd-soc-wcd9335-objs := wcd9335.o wcd9xxx-common-v2.o wcd9xxx-resmgr-v2.o
snd-soc-wcd9xxx-objs := wcd9xxx-resmgr.o wcd9xxx-mbhc.o wcd9xxx-common.o
audio-ext-clock-objs := audio-ext-clk.o
snd-soc-wcd-cpe-objs := wcd_cpe_services.o wcd_cpe_core.o
snd-soc-wsa881x-objs := wsa881x.o wsa881x-tables.o wsa881x-regmap.o
snd-soc-wsa881x-objs := wsa881x.o wsa881x-tables.o wsa881x-regmap.o wsa881x-temp-sensor.o
snd-soc-wcd-mbhc-objs := wcd-mbhc-v2.o
snd-soc-wl1273-objs := wl1273.o
snd-soc-wm-adsp-objs := wm_adsp.o
+9 −0
Original line number Diff line number Diff line
@@ -181,6 +181,15 @@ static bool wsa881x_volatile_register(struct device *dev, unsigned int reg)
	case WSA881X_SPKR_STATUS1:
	case WSA881X_SPKR_STATUS2:
	case WSA881X_SPKR_STATUS3:
	case WSA881X_OTP_REG_0:
	case WSA881X_OTP_REG_1:
	case WSA881X_OTP_REG_2:
	case WSA881X_OTP_REG_3:
	case WSA881X_OTP_REG_4:
	case WSA881X_OTP_REG_5:
	case WSA881X_TEMP_DOUT_MSB:
	case WSA881X_TEMP_DOUT_LSB:
	case WSA881X_TEMP_OP:
		return true;
	default:
		return false;
+45 −5
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include "wsa881x.h"
#include "wsa881x-temp-sensor.h"

enum {
	G_18DB = 0,
@@ -83,6 +84,9 @@ struct wsa881x_priv {
	bool visense_enable;
	struct swr_port port[WSA881X_MAX_SWR_PORTS];
	int pd_gpio;
	struct wsa881x_tz_priv tz_pdata;
	int bg_cnt;
	struct mutex bg_lock;
};

#define SWR_SLV_MAX_REG_ADDR	0x390
@@ -338,13 +342,28 @@ static int wsa881x_visense_adc_ctrl(struct snd_soc_codec *codec, bool enable)

static int wsa881x_bandgap_ctrl(struct snd_soc_codec *codec, bool enable)
{
	dev_dbg(codec->dev, "%s: enable:%d\n", __func__, enable);
	struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec);

	dev_dbg(codec->dev, "%s: enable:%d, bg_count:%d\n", __func__,
		enable, wsa881x->bg_cnt);
	mutex_lock(&wsa881x->bg_lock);
	if (enable) {
		snd_soc_update_bits(codec, WSA881X_TEMP_OP, 0x08, 0x08);
		++wsa881x->bg_cnt;
		if (wsa881x->bg_cnt == 1) {
			snd_soc_update_bits(codec, WSA881X_TEMP_OP,
					    0x08, 0x08);
			/* 400usec sleep is needed as per HW requirement */
			usleep_range(400, 410);
		}
	} 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, 0x08, 0x00);
		}
	}
	mutex_unlock(&wsa881x->bg_lock);
	return 0;
}

@@ -695,6 +714,12 @@ static void wsa881x_init(struct snd_soc_codec *codec)
	snd_soc_update_bits(codec, WSA881X_BOOST_ZX_CTL, 0x20, 0x00);
}

static int32_t wsa881x_resource_acquire(struct snd_soc_codec *codec,
						bool enable)
{
	return wsa881x_bandgap_ctrl(codec, enable);
}

static int wsa881x_probe(struct snd_soc_codec *codec)
{
	struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec);
@@ -720,13 +745,28 @@ static int wsa881x_probe(struct snd_soc_codec *codec)
		return ret;
	}
	dev->dev_num = devnum;
	mutex_init(&wsa881x->bg_lock);
	snprintf(wsa881x->tz_pdata.name, sizeof(wsa881x->tz_pdata.name),
		"%s.%x", "wsatz", (u8)dev->addr);
	wsa881x->bg_cnt = 0;
	wsa881x->tz_pdata.codec = codec;
	wsa881x->tz_pdata.dig_base = WSA881X_DIGITAL_BASE;
	wsa881x->tz_pdata.ana_base = WSA881X_ANALOG_BASE;
	wsa881x->tz_pdata.wsa_resource_acquire = wsa881x_resource_acquire;
	wsa881x_init_thermal(&wsa881x->tz_pdata);
	wsa881x_init(codec);

	return ret;
}

static int wsa881x_remove(struct snd_soc_codec *codec)
{
	/* Add codec shutdown sequence */
	struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec);

	if (wsa881x->tz_pdata.tz_dev)
		wsa881x_deinit_thermal(wsa881x->tz_pdata.tz_dev);
	mutex_destroy(&wsa881x->bg_lock);

	return 0;
}