mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-10-31 18:09:19 +00:00
ASoC: wsa881x: update temperature reading sequence
Temperature reading sequence is updated in wsa881x version 2.0. This change is to add new sequence for temperature reading. Change-Id: Ide1dbc5ef450c5e67f10ee038a5763b9d45008f6 Signed-off-by: Vidyakumar Athota <vathota@codeaurora.org>
This commit is contained in:
parent
9b4feaaedb
commit
665a1f966a
4 changed files with 114 additions and 92 deletions
|
@ -927,6 +927,39 @@ static int32_t wsa881x_resource_acquire(struct snd_soc_codec *codec,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec,
|
||||
struct wsa_temp_register *wsa_temp_reg)
|
||||
{
|
||||
struct wsa881x_pdata *wsa881x = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
if (!wsa881x) {
|
||||
dev_err(codec->dev, "%s: wsa881x is NULL\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
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);
|
||||
wsa_temp_reg->dmeas_lsb = snd_soc_read(codec, WSA881X_TEMP_LSB);
|
||||
snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x01);
|
||||
} else {
|
||||
wsa_temp_reg->dmeas_msb = snd_soc_read(codec,
|
||||
WSA881X_TEMP_DOUT_MSB);
|
||||
wsa_temp_reg->dmeas_lsb = snd_soc_read(codec,
|
||||
WSA881X_TEMP_DOUT_LSB);
|
||||
}
|
||||
wsa_temp_reg->d1_msb = snd_soc_read(codec, WSA881X_OTP_REG_1);
|
||||
wsa_temp_reg->d1_lsb = snd_soc_read(codec, WSA881X_OTP_REG_2);
|
||||
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);
|
||||
|
||||
wsa881x_resource_acquire(codec, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wsa881x_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct i2c_client *client;
|
||||
|
@ -950,10 +983,8 @@ static int wsa881x_probe(struct snd_soc_codec *codec)
|
|||
wsa_pdata[wsa881x_index].spk_pa_gain = SPK_GAIN_12DB;
|
||||
wsa_pdata[wsa881x_index].codec = codec;
|
||||
wsa_pdata[wsa881x_index].tz_pdata.codec = codec;
|
||||
wsa_pdata[wsa881x_index].tz_pdata.dig_base = WSA881X_DIGITAL_BASE;
|
||||
wsa_pdata[wsa881x_index].tz_pdata.ana_base = WSA881X_ANALOG_BASE;
|
||||
wsa_pdata[wsa881x_index].tz_pdata.wsa_resource_acquire =
|
||||
wsa881x_resource_acquire;
|
||||
wsa_pdata[wsa881x_index].tz_pdata.wsa_temp_reg_read =
|
||||
wsa881x_temp_reg_read;
|
||||
snd_soc_codec_set_drvdata(codec, &wsa_pdata[wsa881x_index]);
|
||||
wsa881x_init_thermal(&wsa_pdata[wsa881x_index].tz_pdata);
|
||||
|
||||
|
|
|
@ -22,65 +22,19 @@
|
|||
#define T2_TEMP 150
|
||||
#define LOW_TEMP_THRESHOLD 5
|
||||
#define HIGH_TEMP_THRESHOLD 45
|
||||
#define WSA881X_OTP_REG_1 0x0081
|
||||
#define WSA881X_OTP_REG_2 0x0082
|
||||
#define WSA881X_OTP_REG_3 0x0083
|
||||
#define WSA881X_OTP_REG_4 0x0084
|
||||
#define WSA881X_TEMP_DOUT_MSB 0x000A
|
||||
#define WSA881X_TEMP_DOUT_LSB 0x000B
|
||||
#define TEMP_INVALID 0xFFFF
|
||||
#define WSA881X_THERMAL_TEMP_OP 0x0003
|
||||
|
||||
static void calculate_temp(long *temp_val, int dmeas,
|
||||
struct snd_soc_codec *codec,
|
||||
int dig_base_addr)
|
||||
{
|
||||
/* Tmeas = T1 + ((Dmeas - D1)/(D2 - D1))(T2 - T1) */
|
||||
int t1 = T1_TEMP;
|
||||
int t2 = T2_TEMP;
|
||||
int d1_lsb, d1_msb, d2_lsb, d2_msb;
|
||||
int d1, d2;
|
||||
|
||||
d1_msb = snd_soc_read(codec, dig_base_addr + WSA881X_OTP_REG_1);
|
||||
d1_lsb = snd_soc_read(codec, dig_base_addr + WSA881X_OTP_REG_2);
|
||||
d2_msb = snd_soc_read(codec, dig_base_addr + WSA881X_OTP_REG_3);
|
||||
d2_lsb = snd_soc_read(codec, dig_base_addr + WSA881X_OTP_REG_4);
|
||||
|
||||
/*
|
||||
* Temperature register values are expected to be in the
|
||||
* following range.
|
||||
* d1_msb = 68 - 92 and d1_lsb = 0, 64, 128, 192
|
||||
* d2_msb = 185 -218 and d2_lsb = 0, 64, 128, 192
|
||||
*/
|
||||
if ((d1_msb < 68 || d1_msb > 92) ||
|
||||
(!(d1_lsb == 0 || d1_lsb == 64 || d1_lsb == 128 ||
|
||||
d1_lsb == 192)) ||
|
||||
(d2_msb < 185 || d2_msb > 218) ||
|
||||
(!(d2_lsb == 0 || d2_lsb == 64 || d2_lsb == 128 ||
|
||||
d2_lsb == 192))){
|
||||
printk_ratelimited("%s: Temperature registers[%d %d %d %d] are out of range\n",
|
||||
__func__, d1_msb, d1_lsb, d2_msb, d2_lsb);
|
||||
}
|
||||
|
||||
d1 = ((d1_msb << 0x8) | d1_lsb) >> 0x6;
|
||||
d2 = ((d2_msb << 0x8) | d2_lsb) >> 0x6;
|
||||
|
||||
if (d1 == d2) {
|
||||
*temp_val = TEMP_INVALID;
|
||||
return;
|
||||
}
|
||||
*temp_val = t1 + (((dmeas - d1) * (t2 - t1))/(d2 - d1));
|
||||
}
|
||||
|
||||
static int wsa881x_get_temp(struct thermal_zone_device *thermal,
|
||||
unsigned long *temp)
|
||||
{
|
||||
struct wsa881x_tz_priv *pdata;
|
||||
struct snd_soc_codec *codec;
|
||||
int dmeas_cur_msb, dmeas_cur_lsb;
|
||||
int dmeas;
|
||||
struct wsa_temp_register reg;
|
||||
int dmeas, d1, d2;
|
||||
int ret = 0;
|
||||
long temp_val;
|
||||
int t1 = T1_TEMP;
|
||||
int t2 = T2_TEMP;
|
||||
|
||||
if (thermal->devdata) {
|
||||
pdata = thermal->devdata;
|
||||
|
@ -94,37 +48,51 @@ static int wsa881x_get_temp(struct thermal_zone_device *thermal,
|
|||
pr_err("%s: pdata is NULL\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = pdata->wsa_resource_acquire(codec, true);
|
||||
if (ret) {
|
||||
pr_err("%s: wsa acquire failed: %d\n", __func__, ret);
|
||||
return ret;
|
||||
if (pdata->wsa_temp_reg_read) {
|
||||
ret = pdata->wsa_temp_reg_read(codec, ®);
|
||||
if (ret) {
|
||||
pr_err("%s: temperature register read failed: %d\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
pr_err("%s: wsa_temp_reg_read is NULL\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
snd_soc_update_bits(codec,
|
||||
pdata->ana_base + WSA881X_THERMAL_TEMP_OP,
|
||||
0x04, 0x04);
|
||||
dmeas_cur_msb =
|
||||
snd_soc_read(codec,
|
||||
pdata->ana_base + WSA881X_TEMP_DOUT_MSB);
|
||||
dmeas_cur_lsb =
|
||||
snd_soc_read(codec,
|
||||
pdata->ana_base + WSA881X_TEMP_DOUT_LSB);
|
||||
dmeas = ((dmeas_cur_msb << 0x8) | dmeas_cur_lsb) >> 0x6;
|
||||
pr_debug("%s: dmeas: %d\n", __func__, dmeas);
|
||||
calculate_temp(&temp_val, dmeas, codec, pdata->dig_base);
|
||||
*temp = temp_val;
|
||||
/*
|
||||
* Temperature register values are expected to be in the
|
||||
* following range.
|
||||
* d1_msb = 68 - 92 and d1_lsb = 0, 64, 128, 192
|
||||
* d2_msb = 185 -218 and d2_lsb = 0, 64, 128, 192
|
||||
*/
|
||||
if ((reg.d1_msb < 68 || reg.d1_msb > 92) ||
|
||||
(!(reg.d1_lsb == 0 || reg.d1_lsb == 64 || reg.d1_lsb == 128 ||
|
||||
reg.d1_lsb == 192)) ||
|
||||
(reg.d2_msb < 185 || reg.d2_msb > 218) ||
|
||||
(!(reg.d2_lsb == 0 || reg.d2_lsb == 64 || reg.d2_lsb == 128 ||
|
||||
reg.d2_lsb == 192))) {
|
||||
printk_ratelimited("%s: Temperature registers[%d %d %d %d] are out of range\n",
|
||||
__func__, reg.d1_msb, reg.d1_lsb, reg.d2_msb,
|
||||
reg.d2_lsb);
|
||||
}
|
||||
dmeas = ((reg.dmeas_msb << 0x8) | reg.dmeas_lsb) >> 0x6;
|
||||
d1 = ((reg.d1_msb << 0x8) | reg.d1_lsb) >> 0x6;
|
||||
d2 = ((reg.d2_msb << 0x8) | reg.d2_lsb) >> 0x6;
|
||||
|
||||
if (d1 == d2)
|
||||
temp_val = TEMP_INVALID;
|
||||
else
|
||||
temp_val = t1 + (((dmeas - d1) * (t2 - t1))/(d2 - d1));
|
||||
|
||||
if (temp_val <= LOW_TEMP_THRESHOLD ||
|
||||
temp_val >= HIGH_TEMP_THRESHOLD) {
|
||||
printk_ratelimited("%s: T0: %ld is out of range [%d, %d]\n",
|
||||
temp_val >= HIGH_TEMP_THRESHOLD) {
|
||||
printk_ratelimited("%s: T0: %ld is out of range[%d, %d]\n",
|
||||
__func__, temp_val, LOW_TEMP_THRESHOLD,
|
||||
HIGH_TEMP_THRESHOLD);
|
||||
ret = -EAGAIN;
|
||||
goto rel;
|
||||
}
|
||||
pr_debug("%s: t0 measured: %ld\n", __func__, temp_val);
|
||||
rel:
|
||||
ret = pdata->wsa_resource_acquire(codec, false);
|
||||
if (ret)
|
||||
pr_err("%s: wsa release failed: %d\n", __func__, ret);
|
||||
*temp = temp_val;
|
||||
pr_debug("%s: t0 measured: %ld dmeas = %d, d1 = %d, d2 = %d\n",
|
||||
__func__, temp_val, dmeas, d1, d2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,15 +15,22 @@
|
|||
#include <linux/thermal.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
typedef int32_t (*wsa_rsrc_acquire)(struct snd_soc_codec *codec, bool enable);
|
||||
|
||||
struct wsa_temp_register {
|
||||
u8 d1_msb;
|
||||
u8 d1_lsb;
|
||||
u8 d2_msb;
|
||||
u8 d2_lsb;
|
||||
u8 dmeas_msb;
|
||||
u8 dmeas_lsb;
|
||||
};
|
||||
typedef int32_t (*wsa_temp_register_read)(struct snd_soc_codec *codec,
|
||||
struct wsa_temp_register *wsa_temp_reg);
|
||||
struct wsa881x_tz_priv {
|
||||
struct thermal_zone_device *tz_dev;
|
||||
struct snd_soc_codec *codec;
|
||||
int dig_base;
|
||||
int ana_base;
|
||||
struct wsa_temp_register *wsa_temp_reg;
|
||||
char name[80];
|
||||
wsa_rsrc_acquire wsa_resource_acquire;
|
||||
wsa_temp_register_read wsa_temp_reg_read;
|
||||
};
|
||||
|
||||
int wsa881x_init_thermal(struct wsa881x_tz_priv *tz_pdata);
|
||||
|
|
|
@ -912,8 +912,8 @@ static int32_t wsa881x_resource_acquire(struct snd_soc_codec *codec,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t wsa881x_thermal_resource_acquire(struct snd_soc_codec *codec,
|
||||
bool enable)
|
||||
static int32_t wsa881x_temp_reg_read(struct snd_soc_codec *codec,
|
||||
struct wsa_temp_register *wsa_temp_reg)
|
||||
{
|
||||
struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec);
|
||||
struct swr_device *dev;
|
||||
|
@ -933,7 +933,26 @@ static int32_t wsa881x_thermal_resource_acquire(struct snd_soc_codec *codec,
|
|||
}
|
||||
regcache_sync(wsa881x->regmap);
|
||||
}
|
||||
wsa881x_resource_acquire(codec, enable);
|
||||
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);
|
||||
wsa_temp_reg->dmeas_lsb = snd_soc_read(codec, WSA881X_TEMP_LSB);
|
||||
snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x01);
|
||||
} else {
|
||||
wsa_temp_reg->dmeas_msb = snd_soc_read(codec,
|
||||
WSA881X_TEMP_DOUT_MSB);
|
||||
wsa_temp_reg->dmeas_lsb = snd_soc_read(codec,
|
||||
WSA881X_TEMP_DOUT_LSB);
|
||||
}
|
||||
wsa_temp_reg->d1_msb = snd_soc_read(codec, WSA881X_OTP_REG_1);
|
||||
wsa_temp_reg->d1_lsb = snd_soc_read(codec, WSA881X_OTP_REG_2);
|
||||
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);
|
||||
|
||||
wsa881x_resource_acquire(codec, DISABLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -979,10 +998,7 @@ static int wsa881x_probe(struct snd_soc_codec *codec)
|
|||
wsa881x->clk_cnt = 0;
|
||||
wsa881x->state = WSA881X_DEV_UP;
|
||||
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_thermal_resource_acquire;
|
||||
wsa881x->tz_pdata.wsa_temp_reg_read = wsa881x_temp_reg_read;
|
||||
wsa881x_init_thermal(&wsa881x->tz_pdata);
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue