12d71d8deSAmit Kucheria // SPDX-License-Identifier: GPL-2.0
220d4fd84SRajendra Nayak /*
320d4fd84SRajendra Nayak  * Copyright (c) 2015, The Linux Foundation. All rights reserved.
420d4fd84SRajendra Nayak  */
520d4fd84SRajendra Nayak 
620d4fd84SRajendra Nayak #include <linux/platform_device.h>
720d4fd84SRajendra Nayak #include <linux/delay.h>
820d4fd84SRajendra Nayak #include <linux/bitops.h>
920d4fd84SRajendra Nayak #include <linux/regmap.h>
1020d4fd84SRajendra Nayak #include <linux/thermal.h>
1120d4fd84SRajendra Nayak #include "tsens.h"
1220d4fd84SRajendra Nayak 
1320d4fd84SRajendra Nayak #define CAL_MDEGC		30000
1420d4fd84SRajendra Nayak 
1520d4fd84SRajendra Nayak #define CONFIG_ADDR		0x3640
1620d4fd84SRajendra Nayak #define CONFIG_ADDR_8660	0x3620
1720d4fd84SRajendra Nayak /* CONFIG_ADDR bitmasks */
1820d4fd84SRajendra Nayak #define CONFIG			0x9b
1920d4fd84SRajendra Nayak #define CONFIG_MASK		0xf
2020d4fd84SRajendra Nayak #define CONFIG_8660		1
2120d4fd84SRajendra Nayak #define CONFIG_SHIFT_8660	28
2220d4fd84SRajendra Nayak #define CONFIG_MASK_8660	(3 << CONFIG_SHIFT_8660)
2320d4fd84SRajendra Nayak 
2420d4fd84SRajendra Nayak #define STATUS_CNTL_ADDR_8064	0x3660
2520d4fd84SRajendra Nayak #define CNTL_ADDR		0x3620
2620d4fd84SRajendra Nayak /* CNTL_ADDR bitmasks */
2720d4fd84SRajendra Nayak #define EN			BIT(0)
2820d4fd84SRajendra Nayak #define SW_RST			BIT(1)
2920d4fd84SRajendra Nayak #define SENSOR0_EN		BIT(3)
3020d4fd84SRajendra Nayak #define SLP_CLK_ENA		BIT(26)
3120d4fd84SRajendra Nayak #define SLP_CLK_ENA_8660	BIT(24)
3220d4fd84SRajendra Nayak #define MEASURE_PERIOD		1
3320d4fd84SRajendra Nayak #define SENSOR0_SHIFT		3
3420d4fd84SRajendra Nayak 
3520d4fd84SRajendra Nayak /* INT_STATUS_ADDR bitmasks */
3620d4fd84SRajendra Nayak #define MIN_STATUS_MASK		BIT(0)
3720d4fd84SRajendra Nayak #define LOWER_STATUS_CLR	BIT(1)
3820d4fd84SRajendra Nayak #define UPPER_STATUS_CLR	BIT(2)
3920d4fd84SRajendra Nayak #define MAX_STATUS_MASK		BIT(3)
4020d4fd84SRajendra Nayak 
4120d4fd84SRajendra Nayak #define THRESHOLD_ADDR		0x3624
4220d4fd84SRajendra Nayak /* THRESHOLD_ADDR bitmasks */
4320d4fd84SRajendra Nayak #define THRESHOLD_MAX_LIMIT_SHIFT	24
4420d4fd84SRajendra Nayak #define THRESHOLD_MIN_LIMIT_SHIFT	16
4520d4fd84SRajendra Nayak #define THRESHOLD_UPPER_LIMIT_SHIFT	8
4620d4fd84SRajendra Nayak #define THRESHOLD_LOWER_LIMIT_SHIFT	0
4720d4fd84SRajendra Nayak 
4820d4fd84SRajendra Nayak /* Initial temperature threshold values */
4920d4fd84SRajendra Nayak #define LOWER_LIMIT_TH		0x50
5020d4fd84SRajendra Nayak #define UPPER_LIMIT_TH		0xdf
5120d4fd84SRajendra Nayak #define MIN_LIMIT_TH		0x0
5220d4fd84SRajendra Nayak #define MAX_LIMIT_TH		0xff
5320d4fd84SRajendra Nayak 
5420d4fd84SRajendra Nayak #define INT_STATUS_ADDR		0x363c
5520d4fd84SRajendra Nayak #define TRDY_MASK		BIT(7)
5620d4fd84SRajendra Nayak #define TIMEOUT_US		100
5720d4fd84SRajendra Nayak 
58a0ed1411SAnsuel Smith #define S0_STATUS_OFF		0x3628
59a0ed1411SAnsuel Smith #define S1_STATUS_OFF		0x362c
60a0ed1411SAnsuel Smith #define S2_STATUS_OFF		0x3630
61a0ed1411SAnsuel Smith #define S3_STATUS_OFF		0x3634
62a0ed1411SAnsuel Smith #define S4_STATUS_OFF		0x3638
63a0ed1411SAnsuel Smith #define S5_STATUS_OFF		0x3664  /* Sensors 5-10 found on apq8064/msm8960 */
64a0ed1411SAnsuel Smith #define S6_STATUS_OFF		0x3668
65a0ed1411SAnsuel Smith #define S7_STATUS_OFF		0x366c
66a0ed1411SAnsuel Smith #define S8_STATUS_OFF		0x3670
67a0ed1411SAnsuel Smith #define S9_STATUS_OFF		0x3674
68a0ed1411SAnsuel Smith #define S10_STATUS_OFF		0x3678
69a0ed1411SAnsuel Smith 
7069b628acSAmit Kucheria static int suspend_8960(struct tsens_priv *priv)
7120d4fd84SRajendra Nayak {
7220d4fd84SRajendra Nayak 	int ret;
7320d4fd84SRajendra Nayak 	unsigned int mask;
7469b628acSAmit Kucheria 	struct regmap *map = priv->tm_map;
7520d4fd84SRajendra Nayak 
7669b628acSAmit Kucheria 	ret = regmap_read(map, THRESHOLD_ADDR, &priv->ctx.threshold);
7720d4fd84SRajendra Nayak 	if (ret)
7820d4fd84SRajendra Nayak 		return ret;
7920d4fd84SRajendra Nayak 
8069b628acSAmit Kucheria 	ret = regmap_read(map, CNTL_ADDR, &priv->ctx.control);
8120d4fd84SRajendra Nayak 	if (ret)
8220d4fd84SRajendra Nayak 		return ret;
8320d4fd84SRajendra Nayak 
8469b628acSAmit Kucheria 	if (priv->num_sensors > 1)
8520d4fd84SRajendra Nayak 		mask = SLP_CLK_ENA | EN;
8620d4fd84SRajendra Nayak 	else
8720d4fd84SRajendra Nayak 		mask = SLP_CLK_ENA_8660 | EN;
8820d4fd84SRajendra Nayak 
8920d4fd84SRajendra Nayak 	ret = regmap_update_bits(map, CNTL_ADDR, mask, 0);
9020d4fd84SRajendra Nayak 	if (ret)
9120d4fd84SRajendra Nayak 		return ret;
9220d4fd84SRajendra Nayak 
9320d4fd84SRajendra Nayak 	return 0;
9420d4fd84SRajendra Nayak }
9520d4fd84SRajendra Nayak 
9669b628acSAmit Kucheria static int resume_8960(struct tsens_priv *priv)
9720d4fd84SRajendra Nayak {
9820d4fd84SRajendra Nayak 	int ret;
9969b628acSAmit Kucheria 	struct regmap *map = priv->tm_map;
10020d4fd84SRajendra Nayak 
10120d4fd84SRajendra Nayak 	ret = regmap_update_bits(map, CNTL_ADDR, SW_RST, SW_RST);
10220d4fd84SRajendra Nayak 	if (ret)
10320d4fd84SRajendra Nayak 		return ret;
10420d4fd84SRajendra Nayak 
10520d4fd84SRajendra Nayak 	/*
10620d4fd84SRajendra Nayak 	 * Separate CONFIG restore is not needed only for 8660 as
10720d4fd84SRajendra Nayak 	 * config is part of CTRL Addr and its restored as such
10820d4fd84SRajendra Nayak 	 */
10969b628acSAmit Kucheria 	if (priv->num_sensors > 1) {
11020d4fd84SRajendra Nayak 		ret = regmap_update_bits(map, CONFIG_ADDR, CONFIG_MASK, CONFIG);
11120d4fd84SRajendra Nayak 		if (ret)
11220d4fd84SRajendra Nayak 			return ret;
11320d4fd84SRajendra Nayak 	}
11420d4fd84SRajendra Nayak 
11569b628acSAmit Kucheria 	ret = regmap_write(map, THRESHOLD_ADDR, priv->ctx.threshold);
11620d4fd84SRajendra Nayak 	if (ret)
11720d4fd84SRajendra Nayak 		return ret;
11820d4fd84SRajendra Nayak 
11969b628acSAmit Kucheria 	ret = regmap_write(map, CNTL_ADDR, priv->ctx.control);
12020d4fd84SRajendra Nayak 	if (ret)
12120d4fd84SRajendra Nayak 		return ret;
12220d4fd84SRajendra Nayak 
12320d4fd84SRajendra Nayak 	return 0;
12420d4fd84SRajendra Nayak }
12520d4fd84SRajendra Nayak 
12669b628acSAmit Kucheria static int enable_8960(struct tsens_priv *priv, int id)
12720d4fd84SRajendra Nayak {
12820d4fd84SRajendra Nayak 	int ret;
12920d4fd84SRajendra Nayak 	u32 reg, mask;
13020d4fd84SRajendra Nayak 
13169b628acSAmit Kucheria 	ret = regmap_read(priv->tm_map, CNTL_ADDR, &reg);
13220d4fd84SRajendra Nayak 	if (ret)
13320d4fd84SRajendra Nayak 		return ret;
13420d4fd84SRajendra Nayak 
13520d4fd84SRajendra Nayak 	mask = BIT(id + SENSOR0_SHIFT);
13669b628acSAmit Kucheria 	ret = regmap_write(priv->tm_map, CNTL_ADDR, reg | SW_RST);
13720d4fd84SRajendra Nayak 	if (ret)
13820d4fd84SRajendra Nayak 		return ret;
13920d4fd84SRajendra Nayak 
14069b628acSAmit Kucheria 	if (priv->num_sensors > 1)
14120d4fd84SRajendra Nayak 		reg |= mask | SLP_CLK_ENA | EN;
14220d4fd84SRajendra Nayak 	else
14320d4fd84SRajendra Nayak 		reg |= mask | SLP_CLK_ENA_8660 | EN;
14420d4fd84SRajendra Nayak 
14569b628acSAmit Kucheria 	ret = regmap_write(priv->tm_map, CNTL_ADDR, reg);
14620d4fd84SRajendra Nayak 	if (ret)
14720d4fd84SRajendra Nayak 		return ret;
14820d4fd84SRajendra Nayak 
14920d4fd84SRajendra Nayak 	return 0;
15020d4fd84SRajendra Nayak }
15120d4fd84SRajendra Nayak 
15269b628acSAmit Kucheria static void disable_8960(struct tsens_priv *priv)
15320d4fd84SRajendra Nayak {
15420d4fd84SRajendra Nayak 	int ret;
15520d4fd84SRajendra Nayak 	u32 reg_cntl;
15620d4fd84SRajendra Nayak 	u32 mask;
15720d4fd84SRajendra Nayak 
15869b628acSAmit Kucheria 	mask = GENMASK(priv->num_sensors - 1, 0);
15920d4fd84SRajendra Nayak 	mask <<= SENSOR0_SHIFT;
16020d4fd84SRajendra Nayak 	mask |= EN;
16120d4fd84SRajendra Nayak 
16269b628acSAmit Kucheria 	ret = regmap_read(priv->tm_map, CNTL_ADDR, &reg_cntl);
16320d4fd84SRajendra Nayak 	if (ret)
16420d4fd84SRajendra Nayak 		return;
16520d4fd84SRajendra Nayak 
16620d4fd84SRajendra Nayak 	reg_cntl &= ~mask;
16720d4fd84SRajendra Nayak 
16869b628acSAmit Kucheria 	if (priv->num_sensors > 1)
16920d4fd84SRajendra Nayak 		reg_cntl &= ~SLP_CLK_ENA;
17020d4fd84SRajendra Nayak 	else
17120d4fd84SRajendra Nayak 		reg_cntl &= ~SLP_CLK_ENA_8660;
17220d4fd84SRajendra Nayak 
17369b628acSAmit Kucheria 	regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
17420d4fd84SRajendra Nayak }
17520d4fd84SRajendra Nayak 
17669b628acSAmit Kucheria static int init_8960(struct tsens_priv *priv)
17720d4fd84SRajendra Nayak {
17820d4fd84SRajendra Nayak 	int ret, i;
17920d4fd84SRajendra Nayak 	u32 reg_cntl;
18020d4fd84SRajendra Nayak 
18169b628acSAmit Kucheria 	priv->tm_map = dev_get_regmap(priv->dev, NULL);
18269b628acSAmit Kucheria 	if (!priv->tm_map)
18320d4fd84SRajendra Nayak 		return -ENODEV;
18420d4fd84SRajendra Nayak 
18520d4fd84SRajendra Nayak 	/*
18620d4fd84SRajendra Nayak 	 * The status registers for each sensor are discontiguous
18720d4fd84SRajendra Nayak 	 * because some SoCs have 5 sensors while others have more
18820d4fd84SRajendra Nayak 	 * but the control registers stay in the same place, i.e
18920d4fd84SRajendra Nayak 	 * directly after the first 5 status registers.
19020d4fd84SRajendra Nayak 	 */
19169b628acSAmit Kucheria 	for (i = 0; i < priv->num_sensors; i++) {
19220d4fd84SRajendra Nayak 		if (i >= 5)
193a0ed1411SAnsuel Smith 			priv->sensor[i].status = S0_STATUS_OFF + 40;
19469b628acSAmit Kucheria 		priv->sensor[i].status += i * 4;
19520d4fd84SRajendra Nayak 	}
19620d4fd84SRajendra Nayak 
19720d4fd84SRajendra Nayak 	reg_cntl = SW_RST;
19869b628acSAmit Kucheria 	ret = regmap_update_bits(priv->tm_map, CNTL_ADDR, SW_RST, reg_cntl);
19920d4fd84SRajendra Nayak 	if (ret)
20020d4fd84SRajendra Nayak 		return ret;
20120d4fd84SRajendra Nayak 
20269b628acSAmit Kucheria 	if (priv->num_sensors > 1) {
20320d4fd84SRajendra Nayak 		reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18);
20420d4fd84SRajendra Nayak 		reg_cntl &= ~SW_RST;
20569b628acSAmit Kucheria 		ret = regmap_update_bits(priv->tm_map, CONFIG_ADDR,
20620d4fd84SRajendra Nayak 					 CONFIG_MASK, CONFIG);
20720d4fd84SRajendra Nayak 	} else {
20820d4fd84SRajendra Nayak 		reg_cntl |= SLP_CLK_ENA_8660 | (MEASURE_PERIOD << 16);
20920d4fd84SRajendra Nayak 		reg_cntl &= ~CONFIG_MASK_8660;
21020d4fd84SRajendra Nayak 		reg_cntl |= CONFIG_8660 << CONFIG_SHIFT_8660;
21120d4fd84SRajendra Nayak 	}
21220d4fd84SRajendra Nayak 
21369b628acSAmit Kucheria 	reg_cntl |= GENMASK(priv->num_sensors - 1, 0) << SENSOR0_SHIFT;
21469b628acSAmit Kucheria 	ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
21520d4fd84SRajendra Nayak 	if (ret)
21620d4fd84SRajendra Nayak 		return ret;
21720d4fd84SRajendra Nayak 
21820d4fd84SRajendra Nayak 	reg_cntl |= EN;
21969b628acSAmit Kucheria 	ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
22020d4fd84SRajendra Nayak 	if (ret)
22120d4fd84SRajendra Nayak 		return ret;
22220d4fd84SRajendra Nayak 
22320d4fd84SRajendra Nayak 	return 0;
22420d4fd84SRajendra Nayak }
22520d4fd84SRajendra Nayak 
22669b628acSAmit Kucheria static int calibrate_8960(struct tsens_priv *priv)
22720d4fd84SRajendra Nayak {
22820d4fd84SRajendra Nayak 	int i;
22920d4fd84SRajendra Nayak 	char *data;
23020d4fd84SRajendra Nayak 
23169b628acSAmit Kucheria 	ssize_t num_read = priv->num_sensors;
23269b628acSAmit Kucheria 	struct tsens_sensor *s = priv->sensor;
23320d4fd84SRajendra Nayak 
23469b628acSAmit Kucheria 	data = qfprom_read(priv->dev, "calib");
23520d4fd84SRajendra Nayak 	if (IS_ERR(data))
23669b628acSAmit Kucheria 		data = qfprom_read(priv->dev, "calib_backup");
23720d4fd84SRajendra Nayak 	if (IS_ERR(data))
23820d4fd84SRajendra Nayak 		return PTR_ERR(data);
23920d4fd84SRajendra Nayak 
24020d4fd84SRajendra Nayak 	for (i = 0; i < num_read; i++, s++)
24120d4fd84SRajendra Nayak 		s->offset = data[i];
24220d4fd84SRajendra Nayak 
2436b8249abSSrinivas Kandagatla 	kfree(data);
2446b8249abSSrinivas Kandagatla 
24520d4fd84SRajendra Nayak 	return 0;
24620d4fd84SRajendra Nayak }
24720d4fd84SRajendra Nayak 
24820d4fd84SRajendra Nayak /* Temperature on y axis and ADC-code on x-axis */
24920d4fd84SRajendra Nayak static inline int code_to_mdegC(u32 adc_code, const struct tsens_sensor *s)
25020d4fd84SRajendra Nayak {
25120d4fd84SRajendra Nayak 	int slope, offset;
25220d4fd84SRajendra Nayak 
25320d4fd84SRajendra Nayak 	slope = thermal_zone_get_slope(s->tzd);
25420d4fd84SRajendra Nayak 	offset = CAL_MDEGC - slope * s->offset;
25520d4fd84SRajendra Nayak 
25620d4fd84SRajendra Nayak 	return adc_code * slope + offset;
25720d4fd84SRajendra Nayak }
25820d4fd84SRajendra Nayak 
259e604bdd2SAmit Kucheria static int get_temp_8960(const struct tsens_sensor *s, int *temp)
26020d4fd84SRajendra Nayak {
26120d4fd84SRajendra Nayak 	int ret;
26220d4fd84SRajendra Nayak 	u32 code, trdy;
2638b71bce4SAmit Kucheria 	struct tsens_priv *priv = s->priv;
26420d4fd84SRajendra Nayak 	unsigned long timeout;
26520d4fd84SRajendra Nayak 
26620d4fd84SRajendra Nayak 	timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
26720d4fd84SRajendra Nayak 	do {
26869b628acSAmit Kucheria 		ret = regmap_read(priv->tm_map, INT_STATUS_ADDR, &trdy);
26920d4fd84SRajendra Nayak 		if (ret)
27020d4fd84SRajendra Nayak 			return ret;
27120d4fd84SRajendra Nayak 		if (!(trdy & TRDY_MASK))
27220d4fd84SRajendra Nayak 			continue;
27369b628acSAmit Kucheria 		ret = regmap_read(priv->tm_map, s->status, &code);
27420d4fd84SRajendra Nayak 		if (ret)
27520d4fd84SRajendra Nayak 			return ret;
27620d4fd84SRajendra Nayak 		*temp = code_to_mdegC(code, s);
27720d4fd84SRajendra Nayak 		return 0;
27820d4fd84SRajendra Nayak 	} while (time_before(jiffies, timeout));
27920d4fd84SRajendra Nayak 
28020d4fd84SRajendra Nayak 	return -ETIMEDOUT;
28120d4fd84SRajendra Nayak }
28220d4fd84SRajendra Nayak 
283a0ed1411SAnsuel Smith static const struct reg_field tsens_8960_regfields[MAX_REGFIELDS] = {
284a0ed1411SAnsuel Smith 	/* ----- SROT ------ */
285a0ed1411SAnsuel Smith 	/* No VERSION information */
286a0ed1411SAnsuel Smith 
287a0ed1411SAnsuel Smith 	/* CNTL */
288a0ed1411SAnsuel Smith 	[TSENS_EN]     = REG_FIELD(CNTL_ADDR,  0, 0),
289a0ed1411SAnsuel Smith 	[TSENS_SW_RST] = REG_FIELD(CNTL_ADDR,  1, 1),
290a0ed1411SAnsuel Smith 	/* 8960 has 5 sensors, 8660 has 11, we only handle 5 */
291a0ed1411SAnsuel Smith 	[SENSOR_EN]    = REG_FIELD(CNTL_ADDR,  3, 7),
292a0ed1411SAnsuel Smith 
293a0ed1411SAnsuel Smith 	/* ----- TM ------ */
294a0ed1411SAnsuel Smith 	/* INTERRUPT ENABLE */
295a0ed1411SAnsuel Smith 	/* NO INTERRUPT ENABLE */
296a0ed1411SAnsuel Smith 
297a0ed1411SAnsuel Smith 	/* Single UPPER/LOWER TEMPERATURE THRESHOLD for all sensors */
298a0ed1411SAnsuel Smith 	[LOW_THRESH_0]   = REG_FIELD(THRESHOLD_ADDR,  0,  7),
299a0ed1411SAnsuel Smith 	[UP_THRESH_0]    = REG_FIELD(THRESHOLD_ADDR,  8, 15),
300a0ed1411SAnsuel Smith 	/* MIN_THRESH_0 and MAX_THRESH_0 are not present in the regfield
301a0ed1411SAnsuel Smith 	 * Recycle CRIT_THRESH_0 and 1 to set the required regs to hardcoded temp
302a0ed1411SAnsuel Smith 	 * MIN_THRESH_0 -> CRIT_THRESH_1
303a0ed1411SAnsuel Smith 	 * MAX_THRESH_0 -> CRIT_THRESH_0
304a0ed1411SAnsuel Smith 	 */
305a0ed1411SAnsuel Smith 	[CRIT_THRESH_1]   = REG_FIELD(THRESHOLD_ADDR, 16, 23),
306a0ed1411SAnsuel Smith 	[CRIT_THRESH_0]   = REG_FIELD(THRESHOLD_ADDR, 24, 31),
307a0ed1411SAnsuel Smith 
308a0ed1411SAnsuel Smith 	/* UPPER/LOWER INTERRUPT [CLEAR/STATUS] */
309a0ed1411SAnsuel Smith 	/* 1 == clear, 0 == normal operation */
310a0ed1411SAnsuel Smith 	[LOW_INT_CLEAR_0]   = REG_FIELD(CNTL_ADDR,  9,  9),
311a0ed1411SAnsuel Smith 	[UP_INT_CLEAR_0]    = REG_FIELD(CNTL_ADDR, 10, 10),
312a0ed1411SAnsuel Smith 
313a0ed1411SAnsuel Smith 	/* NO CRITICAL INTERRUPT SUPPORT on 8960 */
314a0ed1411SAnsuel Smith 
315a0ed1411SAnsuel Smith 	/* Sn_STATUS */
316a0ed1411SAnsuel Smith 	[LAST_TEMP_0]  = REG_FIELD(S0_STATUS_OFF,  0,  7),
317a0ed1411SAnsuel Smith 	[LAST_TEMP_1]  = REG_FIELD(S1_STATUS_OFF,  0,  7),
318a0ed1411SAnsuel Smith 	[LAST_TEMP_2]  = REG_FIELD(S2_STATUS_OFF,  0,  7),
319a0ed1411SAnsuel Smith 	[LAST_TEMP_3]  = REG_FIELD(S3_STATUS_OFF,  0,  7),
320a0ed1411SAnsuel Smith 	[LAST_TEMP_4]  = REG_FIELD(S4_STATUS_OFF,  0,  7),
321a0ed1411SAnsuel Smith 	[LAST_TEMP_5]  = REG_FIELD(S5_STATUS_OFF,  0,  7),
322a0ed1411SAnsuel Smith 	[LAST_TEMP_6]  = REG_FIELD(S6_STATUS_OFF,  0,  7),
323a0ed1411SAnsuel Smith 	[LAST_TEMP_7]  = REG_FIELD(S7_STATUS_OFF,  0,  7),
324a0ed1411SAnsuel Smith 	[LAST_TEMP_8]  = REG_FIELD(S8_STATUS_OFF,  0,  7),
325a0ed1411SAnsuel Smith 	[LAST_TEMP_9]  = REG_FIELD(S9_STATUS_OFF,  0,  7),
326a0ed1411SAnsuel Smith 	[LAST_TEMP_10] = REG_FIELD(S10_STATUS_OFF, 0,  7),
327a0ed1411SAnsuel Smith 
328a0ed1411SAnsuel Smith 	/* No VALID field on 8960 */
329a0ed1411SAnsuel Smith 	/* TSENS_INT_STATUS bits: 1 == threshold violated */
330a0ed1411SAnsuel Smith 	[MIN_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 0, 0),
331a0ed1411SAnsuel Smith 	[LOWER_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 1, 1),
332a0ed1411SAnsuel Smith 	[UPPER_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 2, 2),
333a0ed1411SAnsuel Smith 	/* No CRITICAL field on 8960 */
334a0ed1411SAnsuel Smith 	[MAX_STATUS_0] = REG_FIELD(INT_STATUS_ADDR, 3, 3),
335a0ed1411SAnsuel Smith 
336a0ed1411SAnsuel Smith 	/* TRDY: 1=ready, 0=in progress */
337a0ed1411SAnsuel Smith 	[TRDY] = REG_FIELD(INT_STATUS_ADDR, 7, 7),
338a0ed1411SAnsuel Smith };
339a0ed1411SAnsuel Smith 
340032d4057SEduardo Valentin static const struct tsens_ops ops_8960 = {
34120d4fd84SRajendra Nayak 	.init		= init_8960,
34220d4fd84SRajendra Nayak 	.calibrate	= calibrate_8960,
34320d4fd84SRajendra Nayak 	.get_temp	= get_temp_8960,
34420d4fd84SRajendra Nayak 	.enable		= enable_8960,
34520d4fd84SRajendra Nayak 	.disable	= disable_8960,
34620d4fd84SRajendra Nayak 	.suspend	= suspend_8960,
34720d4fd84SRajendra Nayak 	.resume		= resume_8960,
34820d4fd84SRajendra Nayak };
34920d4fd84SRajendra Nayak 
350*53e2a20eSAnsuel Smith static struct tsens_features tsens_8960_feat = {
351*53e2a20eSAnsuel Smith 	.ver_major	= VER_0,
352*53e2a20eSAnsuel Smith 	.crit_int	= 0,
353*53e2a20eSAnsuel Smith 	.adc		= 1,
354*53e2a20eSAnsuel Smith 	.srot_split	= 0,
355*53e2a20eSAnsuel Smith 	.max_sensors	= 11,
356*53e2a20eSAnsuel Smith };
357*53e2a20eSAnsuel Smith 
3580aef1ee5SAmit Kucheria struct tsens_plat_data data_8960 = {
35920d4fd84SRajendra Nayak 	.num_sensors	= 11,
36020d4fd84SRajendra Nayak 	.ops		= &ops_8960,
361*53e2a20eSAnsuel Smith 	.feat		= &tsens_8960_feat,
362a0ed1411SAnsuel Smith 	.fields		= tsens_8960_regfields,
36320d4fd84SRajendra Nayak };
364