Commit 634e11d5 authored by Amit Kucheria's avatar Amit Kucheria Committed by Daniel Lezcano

drivers: thermal: tsens: Add interrupt support

Depending on the IP version, TSENS supports upper, lower and critical
threshold interrupts. We only add support for upper and lower threshold
interrupts for now.

TSENSv2 has an irq [status|clear|mask] bit tuple for each sensor while
earlier versions only have a single bit per sensor to denote status and
clear. These differences are handled transparently by the interrupt
handler. At each interrupt, we reprogram the new upper and lower threshold
in the .set_trip callback.
Signed-off-by: default avatarAmit Kucheria <amit.kucheria@linaro.org>
Reviewed-by: default avatarStephen Boyd <swboyd@chromium.org>
Signed-off-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/7508ba143f144407e5dd546107ddae65c380a76f.1572526427.git.amit.kucheria@linaro.org
parent bd93ee3c
This diff is collapsed.
...@@ -347,9 +347,20 @@ static const struct reg_field tsens_v0_1_regfields[MAX_REGFIELDS] = { ...@@ -347,9 +347,20 @@ static const struct reg_field tsens_v0_1_regfields[MAX_REGFIELDS] = {
/* INTERRUPT ENABLE */ /* INTERRUPT ENABLE */
[INT_EN] = REG_FIELD(TM_INT_EN_OFF, 0, 0), [INT_EN] = REG_FIELD(TM_INT_EN_OFF, 0, 0),
/* UPPER/LOWER TEMPERATURE THRESHOLDS */
REG_FIELD_FOR_EACH_SENSOR11(LOW_THRESH, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 0, 9),
REG_FIELD_FOR_EACH_SENSOR11(UP_THRESH, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 10, 19),
/* UPPER/LOWER INTERRUPTS [CLEAR/STATUS] */
REG_FIELD_FOR_EACH_SENSOR11(LOW_INT_CLEAR, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 20, 20),
REG_FIELD_FOR_EACH_SENSOR11(UP_INT_CLEAR, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 21, 21),
/* NO CRITICAL INTERRUPT SUPPORT on v0.1 */
/* Sn_STATUS */ /* Sn_STATUS */
REG_FIELD_FOR_EACH_SENSOR11(LAST_TEMP, TM_Sn_STATUS_OFF, 0, 9), REG_FIELD_FOR_EACH_SENSOR11(LAST_TEMP, TM_Sn_STATUS_OFF, 0, 9),
/* No VALID field on v0.1 */ /* No VALID field on v0.1 */
/* xxx_STATUS bits: 1 == threshold violated */
REG_FIELD_FOR_EACH_SENSOR11(MIN_STATUS, TM_Sn_STATUS_OFF, 10, 10), REG_FIELD_FOR_EACH_SENSOR11(MIN_STATUS, TM_Sn_STATUS_OFF, 10, 10),
REG_FIELD_FOR_EACH_SENSOR11(LOWER_STATUS, TM_Sn_STATUS_OFF, 11, 11), REG_FIELD_FOR_EACH_SENSOR11(LOWER_STATUS, TM_Sn_STATUS_OFF, 11, 11),
REG_FIELD_FOR_EACH_SENSOR11(UPPER_STATUS, TM_Sn_STATUS_OFF, 12, 12), REG_FIELD_FOR_EACH_SENSOR11(UPPER_STATUS, TM_Sn_STATUS_OFF, 12, 12),
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#define TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF 0x0004 #define TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF 0x0004
#define TM_Sn_STATUS_OFF 0x0044 #define TM_Sn_STATUS_OFF 0x0044
#define TM_TRDY_OFF 0x0084 #define TM_TRDY_OFF 0x0084
#define TM_HIGH_LOW_INT_STATUS_OFF 0x0088
#define TM_HIGH_LOW_Sn_INT_THRESHOLD_OFF 0x0090
/* eeprom layout data for qcs404/405 (v1) */ /* eeprom layout data for qcs404/405 (v1) */
#define BASE0_MASK 0x000007f8 #define BASE0_MASK 0x000007f8
...@@ -168,9 +170,36 @@ static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = { ...@@ -168,9 +170,36 @@ static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
/* INTERRUPT ENABLE */ /* INTERRUPT ENABLE */
[INT_EN] = REG_FIELD(TM_INT_EN_OFF, 0, 0), [INT_EN] = REG_FIELD(TM_INT_EN_OFF, 0, 0),
/* UPPER/LOWER TEMPERATURE THRESHOLDS */
REG_FIELD_FOR_EACH_SENSOR11(LOW_THRESH, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 0, 9),
REG_FIELD_FOR_EACH_SENSOR11(UP_THRESH, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 10, 19),
/* UPPER/LOWER INTERRUPTS [CLEAR/STATUS] */
REG_FIELD_FOR_EACH_SENSOR11(LOW_INT_CLEAR, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 20, 20),
REG_FIELD_FOR_EACH_SENSOR11(UP_INT_CLEAR, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 21, 21),
[LOW_INT_STATUS_0] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 0, 0),
[LOW_INT_STATUS_1] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 1, 1),
[LOW_INT_STATUS_2] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 2, 2),
[LOW_INT_STATUS_3] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 3, 3),
[LOW_INT_STATUS_4] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 4, 4),
[LOW_INT_STATUS_5] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 5, 5),
[LOW_INT_STATUS_6] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 6, 6),
[LOW_INT_STATUS_7] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 7, 7),
[UP_INT_STATUS_0] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 8, 8),
[UP_INT_STATUS_1] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 9, 9),
[UP_INT_STATUS_2] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 10, 10),
[UP_INT_STATUS_3] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 11, 11),
[UP_INT_STATUS_4] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 12, 12),
[UP_INT_STATUS_5] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 13, 13),
[UP_INT_STATUS_6] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 14, 14),
[UP_INT_STATUS_7] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 15, 15),
/* NO CRITICAL INTERRUPT SUPPORT on v1 */
/* Sn_STATUS */ /* Sn_STATUS */
REG_FIELD_FOR_EACH_SENSOR11(LAST_TEMP, TM_Sn_STATUS_OFF, 0, 9), REG_FIELD_FOR_EACH_SENSOR11(LAST_TEMP, TM_Sn_STATUS_OFF, 0, 9),
REG_FIELD_FOR_EACH_SENSOR11(VALID, TM_Sn_STATUS_OFF, 14, 14), REG_FIELD_FOR_EACH_SENSOR11(VALID, TM_Sn_STATUS_OFF, 14, 14),
/* xxx_STATUS bits: 1 == threshold violated */
REG_FIELD_FOR_EACH_SENSOR11(MIN_STATUS, TM_Sn_STATUS_OFF, 10, 10), REG_FIELD_FOR_EACH_SENSOR11(MIN_STATUS, TM_Sn_STATUS_OFF, 10, 10),
REG_FIELD_FOR_EACH_SENSOR11(LOWER_STATUS, TM_Sn_STATUS_OFF, 11, 11), REG_FIELD_FOR_EACH_SENSOR11(LOWER_STATUS, TM_Sn_STATUS_OFF, 11, 11),
REG_FIELD_FOR_EACH_SENSOR11(UPPER_STATUS, TM_Sn_STATUS_OFF, 12, 12), REG_FIELD_FOR_EACH_SENSOR11(UPPER_STATUS, TM_Sn_STATUS_OFF, 12, 12),
......
...@@ -50,9 +50,22 @@ static const struct reg_field tsens_v2_regfields[MAX_REGFIELDS] = { ...@@ -50,9 +50,22 @@ static const struct reg_field tsens_v2_regfields[MAX_REGFIELDS] = {
/* v2 has separate enables for UPPER/LOWER/CRITICAL interrupts */ /* v2 has separate enables for UPPER/LOWER/CRITICAL interrupts */
[INT_EN] = REG_FIELD(TM_INT_EN_OFF, 0, 2), [INT_EN] = REG_FIELD(TM_INT_EN_OFF, 0, 2),
/* TEMPERATURE THRESHOLDS */
REG_FIELD_FOR_EACH_SENSOR16(LOW_THRESH, TM_Sn_UPPER_LOWER_THRESHOLD_OFF, 0, 11),
REG_FIELD_FOR_EACH_SENSOR16(UP_THRESH, TM_Sn_UPPER_LOWER_THRESHOLD_OFF, 12, 23),
/* INTERRUPTS [CLEAR/STATUS/MASK] */
REG_FIELD_SPLIT_BITS_0_15(LOW_INT_STATUS, TM_UPPER_LOWER_INT_STATUS_OFF),
REG_FIELD_SPLIT_BITS_0_15(LOW_INT_CLEAR, TM_UPPER_LOWER_INT_CLEAR_OFF),
REG_FIELD_SPLIT_BITS_0_15(LOW_INT_MASK, TM_UPPER_LOWER_INT_MASK_OFF),
REG_FIELD_SPLIT_BITS_16_31(UP_INT_STATUS, TM_UPPER_LOWER_INT_STATUS_OFF),
REG_FIELD_SPLIT_BITS_16_31(UP_INT_CLEAR, TM_UPPER_LOWER_INT_CLEAR_OFF),
REG_FIELD_SPLIT_BITS_16_31(UP_INT_MASK, TM_UPPER_LOWER_INT_MASK_OFF),
/* Sn_STATUS */ /* Sn_STATUS */
REG_FIELD_FOR_EACH_SENSOR16(LAST_TEMP, TM_Sn_STATUS_OFF, 0, 11), REG_FIELD_FOR_EACH_SENSOR16(LAST_TEMP, TM_Sn_STATUS_OFF, 0, 11),
REG_FIELD_FOR_EACH_SENSOR16(VALID, TM_Sn_STATUS_OFF, 21, 21), REG_FIELD_FOR_EACH_SENSOR16(VALID, TM_Sn_STATUS_OFF, 21, 21),
/* xxx_STATUS bits: 1 == threshold violated */
REG_FIELD_FOR_EACH_SENSOR16(MIN_STATUS, TM_Sn_STATUS_OFF, 16, 16), REG_FIELD_FOR_EACH_SENSOR16(MIN_STATUS, TM_Sn_STATUS_OFF, 16, 16),
REG_FIELD_FOR_EACH_SENSOR16(LOWER_STATUS, TM_Sn_STATUS_OFF, 17, 17), REG_FIELD_FOR_EACH_SENSOR16(LOWER_STATUS, TM_Sn_STATUS_OFF, 17, 17),
REG_FIELD_FOR_EACH_SENSOR16(UPPER_STATUS, TM_Sn_STATUS_OFF, 18, 18), REG_FIELD_FOR_EACH_SENSOR16(UPPER_STATUS, TM_Sn_STATUS_OFF, 18, 18),
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -78,12 +79,14 @@ MODULE_DEVICE_TABLE(of, tsens_table); ...@@ -78,12 +79,14 @@ MODULE_DEVICE_TABLE(of, tsens_table);
static const struct thermal_zone_of_device_ops tsens_of_ops = { static const struct thermal_zone_of_device_ops tsens_of_ops = {
.get_temp = tsens_get_temp, .get_temp = tsens_get_temp,
.get_trend = tsens_get_trend, .get_trend = tsens_get_trend,
.set_trips = tsens_set_trips,
}; };
static int tsens_register(struct tsens_priv *priv) static int tsens_register(struct tsens_priv *priv)
{ {
int i; int i, ret, irq;
struct thermal_zone_device *tzd; struct thermal_zone_device *tzd;
struct platform_device *pdev;
for (i = 0; i < priv->num_sensors; i++) { for (i = 0; i < priv->num_sensors; i++) {
priv->sensor[i].priv = priv; priv->sensor[i].priv = priv;
...@@ -96,7 +99,31 @@ static int tsens_register(struct tsens_priv *priv) ...@@ -96,7 +99,31 @@ static int tsens_register(struct tsens_priv *priv)
if (priv->ops->enable) if (priv->ops->enable)
priv->ops->enable(priv, i); priv->ops->enable(priv, i);
} }
return 0;
pdev = of_find_device_by_node(priv->dev->of_node);
if (!pdev)
return -ENODEV;
irq = platform_get_irq_byname(pdev, "uplow");
if (irq < 0) {
ret = irq;
goto err_put_device;
}
ret = devm_request_threaded_irq(&pdev->dev, irq,
NULL, tsens_irq_thread,
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
dev_name(&pdev->dev), priv);
if (ret) {
dev_err(&pdev->dev, "%s: failed to get irq\n", __func__);
goto err_put_device;
}
enable_irq_wake(irq);
err_put_device:
put_device(&pdev->dev);
return ret;
} }
static int tsens_probe(struct platform_device *pdev) static int tsens_probe(struct platform_device *pdev)
...@@ -178,6 +205,7 @@ static int tsens_remove(struct platform_device *pdev) ...@@ -178,6 +205,7 @@ static int tsens_remove(struct platform_device *pdev)
struct tsens_priv *priv = platform_get_drvdata(pdev); struct tsens_priv *priv = platform_get_drvdata(pdev);
debugfs_remove_recursive(priv->debug_root); debugfs_remove_recursive(priv->debug_root);
tsens_disable_irq(priv);
if (priv->ops->disable) if (priv->ops->disable)
priv->ops->disable(priv); priv->ops->disable(priv);
......
...@@ -13,8 +13,10 @@ ...@@ -13,8 +13,10 @@
#define CAL_DEGC_PT2 120 #define CAL_DEGC_PT2 120
#define SLOPE_FACTOR 1000 #define SLOPE_FACTOR 1000
#define SLOPE_DEFAULT 3200 #define SLOPE_DEFAULT 3200
#define THRESHOLD_MAX_ADC_CODE 0x3ff
#define THRESHOLD_MIN_ADC_CODE 0x0
#include <linux/interrupt.h>
#include <linux/thermal.h> #include <linux/thermal.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -27,6 +29,11 @@ enum tsens_ver { ...@@ -27,6 +29,11 @@ enum tsens_ver {
VER_2_X, VER_2_X,
}; };
enum tsens_irq_type {
LOWER,
UPPER,
};
/** /**
* struct tsens_sensor - data for each sensor connected to the tsens device * struct tsens_sensor - data for each sensor connected to the tsens device
* @priv: tsens device instance that this sensor is connected to * @priv: tsens device instance that this sensor is connected to
...@@ -100,22 +107,66 @@ struct tsens_ops { ...@@ -100,22 +107,66 @@ struct tsens_ops {
[_name##_##14] = REG_FIELD(_offset + 56, _startbit, _stopbit), \ [_name##_##14] = REG_FIELD(_offset + 56, _startbit, _stopbit), \
[_name##_##15] = REG_FIELD(_offset + 60, _startbit, _stopbit) [_name##_##15] = REG_FIELD(_offset + 60, _startbit, _stopbit)
/* reg_field IDs to use as an index into an array */ #define REG_FIELD_SPLIT_BITS_0_15(_name, _offset) \
[_name##_##0] = REG_FIELD(_offset, 0, 0), \
[_name##_##1] = REG_FIELD(_offset, 1, 1), \
[_name##_##2] = REG_FIELD(_offset, 2, 2), \
[_name##_##3] = REG_FIELD(_offset, 3, 3), \
[_name##_##4] = REG_FIELD(_offset, 4, 4), \
[_name##_##5] = REG_FIELD(_offset, 5, 5), \
[_name##_##6] = REG_FIELD(_offset, 6, 6), \
[_name##_##7] = REG_FIELD(_offset, 7, 7), \
[_name##_##8] = REG_FIELD(_offset, 8, 8), \
[_name##_##9] = REG_FIELD(_offset, 9, 9), \
[_name##_##10] = REG_FIELD(_offset, 10, 10), \
[_name##_##11] = REG_FIELD(_offset, 11, 11), \
[_name##_##12] = REG_FIELD(_offset, 12, 12), \
[_name##_##13] = REG_FIELD(_offset, 13, 13), \
[_name##_##14] = REG_FIELD(_offset, 14, 14), \
[_name##_##15] = REG_FIELD(_offset, 15, 15)
#define REG_FIELD_SPLIT_BITS_16_31(_name, _offset) \
[_name##_##0] = REG_FIELD(_offset, 16, 16), \
[_name##_##1] = REG_FIELD(_offset, 17, 17), \
[_name##_##2] = REG_FIELD(_offset, 18, 18), \
[_name##_##3] = REG_FIELD(_offset, 19, 19), \
[_name##_##4] = REG_FIELD(_offset, 20, 20), \
[_name##_##5] = REG_FIELD(_offset, 21, 21), \
[_name##_##6] = REG_FIELD(_offset, 22, 22), \
[_name##_##7] = REG_FIELD(_offset, 23, 23), \
[_name##_##8] = REG_FIELD(_offset, 24, 24), \
[_name##_##9] = REG_FIELD(_offset, 25, 25), \
[_name##_##10] = REG_FIELD(_offset, 26, 26), \
[_name##_##11] = REG_FIELD(_offset, 27, 27), \
[_name##_##12] = REG_FIELD(_offset, 28, 28), \
[_name##_##13] = REG_FIELD(_offset, 29, 29), \
[_name##_##14] = REG_FIELD(_offset, 30, 30), \
[_name##_##15] = REG_FIELD(_offset, 31, 31)
/*
* reg_field IDs to use as an index into an array
* If you change the order of the entries, check the devm_regmap_field_alloc()
* calls in init_common()
*/
enum regfield_ids { enum regfield_ids {
/* ----- SROT ------ */ /* ----- SROT ------ */
/* HW_VER */ /* HW_VER */
VER_MAJOR = 0, VER_MAJOR,
VER_MINOR, VER_MINOR,
VER_STEP, VER_STEP,
/* CTRL_OFFSET */ /* CTRL_OFFSET */
TSENS_EN = 3, TSENS_EN,
TSENS_SW_RST, TSENS_SW_RST,
SENSOR_EN, SENSOR_EN,
CODE_OR_TEMP, CODE_OR_TEMP,
/* ----- TM ------ */ /* ----- TM ------ */
/* TRDY */
TRDY,
/* INTERRUPT ENABLE */
INT_EN, /* v2+ has separate enables for crit, upper and lower irq */
/* STATUS */ /* STATUS */
LAST_TEMP_0 = 7, /* Last temperature reading */ LAST_TEMP_0, /* Last temperature reading */
LAST_TEMP_1, LAST_TEMP_1,
LAST_TEMP_2, LAST_TEMP_2,
LAST_TEMP_3, LAST_TEMP_3,
...@@ -131,7 +182,7 @@ enum regfield_ids { ...@@ -131,7 +182,7 @@ enum regfield_ids {
LAST_TEMP_13, LAST_TEMP_13,
LAST_TEMP_14, LAST_TEMP_14,
LAST_TEMP_15, LAST_TEMP_15,
VALID_0 = 23, /* VALID reading or not */ VALID_0, /* VALID reading or not */
VALID_1, VALID_1,
VALID_2, VALID_2,
VALID_3, VALID_3,
...@@ -147,38 +198,6 @@ enum regfield_ids { ...@@ -147,38 +198,6 @@ enum regfield_ids {
VALID_13, VALID_13,
VALID_14, VALID_14,
VALID_15, VALID_15,
MIN_STATUS_0, /* MIN threshold violated */
MIN_STATUS_1,
MIN_STATUS_2,
MIN_STATUS_3,
MIN_STATUS_4,
MIN_STATUS_5,
MIN_STATUS_6,
MIN_STATUS_7,
MIN_STATUS_8,
MIN_STATUS_9,
MIN_STATUS_10,
MIN_STATUS_11,
MIN_STATUS_12,
MIN_STATUS_13,
MIN_STATUS_14,
MIN_STATUS_15,
MAX_STATUS_0, /* MAX threshold violated */
MAX_STATUS_1,
MAX_STATUS_2,
MAX_STATUS_3,
MAX_STATUS_4,
MAX_STATUS_5,
MAX_STATUS_6,
MAX_STATUS_7,
MAX_STATUS_8,
MAX_STATUS_9,
MAX_STATUS_10,
MAX_STATUS_11,
MAX_STATUS_12,
MAX_STATUS_13,
MAX_STATUS_14,
MAX_STATUS_15,
LOWER_STATUS_0, /* LOWER threshold violated */ LOWER_STATUS_0, /* LOWER threshold violated */
LOWER_STATUS_1, LOWER_STATUS_1,
LOWER_STATUS_2, LOWER_STATUS_2,
...@@ -195,6 +214,70 @@ enum regfield_ids { ...@@ -195,6 +214,70 @@ enum regfield_ids {
LOWER_STATUS_13, LOWER_STATUS_13,
LOWER_STATUS_14, LOWER_STATUS_14,
LOWER_STATUS_15, LOWER_STATUS_15,
LOW_INT_STATUS_0, /* LOWER interrupt status */
LOW_INT_STATUS_1,
LOW_INT_STATUS_2,
LOW_INT_STATUS_3,
LOW_INT_STATUS_4,
LOW_INT_STATUS_5,
LOW_INT_STATUS_6,
LOW_INT_STATUS_7,
LOW_INT_STATUS_8,
LOW_INT_STATUS_9,
LOW_INT_STATUS_10,
LOW_INT_STATUS_11,
LOW_INT_STATUS_12,
LOW_INT_STATUS_13,
LOW_INT_STATUS_14,
LOW_INT_STATUS_15,
LOW_INT_CLEAR_0, /* LOWER interrupt clear */
LOW_INT_CLEAR_1,
LOW_INT_CLEAR_2,
LOW_INT_CLEAR_3,
LOW_INT_CLEAR_4,
LOW_INT_CLEAR_5,
LOW_INT_CLEAR_6,
LOW_INT_CLEAR_7,
LOW_INT_CLEAR_8,
LOW_INT_CLEAR_9,
LOW_INT_CLEAR_10,
LOW_INT_CLEAR_11,
LOW_INT_CLEAR_12,
LOW_INT_CLEAR_13,
LOW_INT_CLEAR_14,
LOW_INT_CLEAR_15,
LOW_INT_MASK_0, /* LOWER interrupt mask */
LOW_INT_MASK_1,
LOW_INT_MASK_2,
LOW_INT_MASK_3,
LOW_INT_MASK_4,
LOW_INT_MASK_5,
LOW_INT_MASK_6,
LOW_INT_MASK_7,
LOW_INT_MASK_8,
LOW_INT_MASK_9,
LOW_INT_MASK_10,
LOW_INT_MASK_11,
LOW_INT_MASK_12,
LOW_INT_MASK_13,
LOW_INT_MASK_14,
LOW_INT_MASK_15,
LOW_THRESH_0, /* LOWER threshold values */
LOW_THRESH_1,
LOW_THRESH_2,
LOW_THRESH_3,
LOW_THRESH_4,
LOW_THRESH_5,
LOW_THRESH_6,
LOW_THRESH_7,
LOW_THRESH_8,
LOW_THRESH_9,
LOW_THRESH_10,
LOW_THRESH_11,
LOW_THRESH_12,
LOW_THRESH_13,
LOW_THRESH_14,
LOW_THRESH_15,
UPPER_STATUS_0, /* UPPER threshold violated */ UPPER_STATUS_0, /* UPPER threshold violated */
UPPER_STATUS_1, UPPER_STATUS_1,
UPPER_STATUS_2, UPPER_STATUS_2,
...@@ -211,6 +294,70 @@ enum regfield_ids { ...@@ -211,6 +294,70 @@ enum regfield_ids {
UPPER_STATUS_13, UPPER_STATUS_13,
UPPER_STATUS_14, UPPER_STATUS_14,
UPPER_STATUS_15, UPPER_STATUS_15,
UP_INT_STATUS_0, /* UPPER interrupt status */
UP_INT_STATUS_1,
UP_INT_STATUS_2,
UP_INT_STATUS_3,
UP_INT_STATUS_4,
UP_INT_STATUS_5,
UP_INT_STATUS_6,
UP_INT_STATUS_7,
UP_INT_STATUS_8,
UP_INT_STATUS_9,
UP_INT_STATUS_10,
UP_INT_STATUS_11,
UP_INT_STATUS_12,
UP_INT_STATUS_13,
UP_INT_STATUS_14,
UP_INT_STATUS_15,
UP_INT_CLEAR_0, /* UPPER interrupt clear */
UP_INT_CLEAR_1,
UP_INT_CLEAR_2,
UP_INT_CLEAR_3,
UP_INT_CLEAR_4,
UP_INT_CLEAR_5,
UP_INT_CLEAR_6,
UP_INT_CLEAR_7,
UP_INT_CLEAR_8,
UP_INT_CLEAR_9,
UP_INT_CLEAR_10,
UP_INT_CLEAR_11,
UP_INT_CLEAR_12,
UP_INT_CLEAR_13,
UP_INT_CLEAR_14,
UP_INT_CLEAR_15,
UP_INT_MASK_0, /* UPPER interrupt mask */
UP_INT_MASK_1,
UP_INT_MASK_2,
UP_INT_MASK_3,
UP_INT_MASK_4,
UP_INT_MASK_5,
UP_INT_MASK_6,
UP_INT_MASK_7,
UP_INT_MASK_8,
UP_INT_MASK_9,
UP_INT_MASK_10,
UP_INT_MASK_11,
UP_INT_MASK_12,
UP_INT_MASK_13,
UP_INT_MASK_14,
UP_INT_MASK_15,
UP_THRESH_0, /* UPPER threshold values */
UP_THRESH_1,
UP_THRESH_2,
UP_THRESH_3,
UP_THRESH_4,
UP_THRESH_5,
UP_THRESH_6,
UP_THRESH_7,
UP_THRESH_8,
UP_THRESH_9,
UP_THRESH_10,
UP_THRESH_11,
UP_THRESH_12,
UP_THRESH_13,
UP_THRESH_14,
UP_THRESH_15,
CRITICAL_STATUS_0, /* CRITICAL threshold violated */ CRITICAL_STATUS_0, /* CRITICAL threshold violated */
CRITICAL_STATUS_1, CRITICAL_STATUS_1,
CRITICAL_STATUS_2, CRITICAL_STATUS_2,
...@@ -227,13 +374,38 @@ enum regfield_ids { ...@@ -227,13 +374,38 @@ enum regfield_ids {
CRITICAL_STATUS_13, CRITICAL_STATUS_13,
CRITICAL_STATUS_14, CRITICAL_STATUS_14,
CRITICAL_STATUS_15, CRITICAL_STATUS_15,
/* TRDY */ MIN_STATUS_0, /* MIN threshold violated */
TRDY, MIN_STATUS_1,
/* INTERRUPT ENABLE */ MIN_STATUS_2,
INT_EN, /* Pre-V1, V1.x */ MIN_STATUS_3,
LOW_INT_EN, /* V2.x */ MIN_STATUS_4,
UP_INT_EN, /* V2.x */ MIN_STATUS_5,
CRIT_INT_EN, /* V2.x */ MIN_STATUS_6,
MIN_STATUS_7,
MIN_STATUS_8,
MIN_STATUS_9,
MIN_STATUS_10,
MIN_STATUS_11,
MIN_STATUS_12,
MIN_STATUS_13,
MIN_STATUS_14,
MIN_STATUS_15,
MAX_STATUS_0, /* MAX threshold violated */
MAX_STATUS_1,
MAX_STATUS_2,
MAX_STATUS_3,
MAX_STATUS_4,
MAX_STATUS_5,
MAX_STATUS_6,
MAX_STATUS_7,
MAX_STATUS_8,
MAX_STATUS_9,
MAX_STATUS_10,
MAX_STATUS_11,
MAX_STATUS_12,
MAX_STATUS_13,
MAX_STATUS_14,
MAX_STATUS_15,
/* Keep last */ /* Keep last */
MAX_REGFIELDS MAX_REGFIELDS
...@@ -303,6 +475,10 @@ struct tsens_priv { ...@@ -303,6 +475,10 @@ struct tsens_priv {
struct regmap *tm_map; struct regmap *tm_map;
struct regmap *srot_map; struct regmap *srot_map;
u32 tm_offset; u32 tm_offset;
/* lock for upper/lower threshold interrupts */
spinlock_t ul_lock;
struct regmap_field *rf[MAX_REGFIELDS]; struct regmap_field *rf[MAX_REGFIELDS];
struct tsens_context ctx; struct tsens_context ctx;
const struct tsens_features *feat; const struct tsens_features *feat;
...@@ -320,6 +496,10 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 *pt1, u32 *pt2, u32 mo ...@@ -320,6 +496,10 @@ void compute_intercept_slope(struct tsens_priv *priv, u32 *pt1, u32 *pt2, u32 mo
int init_common(struct tsens_priv *priv); int init_common(struct tsens_priv *priv);
int get_temp_tsens_valid(struct tsens_sensor *s, int *temp); int get_temp_tsens_valid(struct tsens_sensor *s, int *temp);
int get_temp_common(struct tsens_sensor *s, int *temp); int get_temp_common(struct tsens_sensor *s, int *temp);
int tsens_enable_irq(struct tsens_priv *priv);
void tsens_disable_irq(struct tsens_priv *priv);
int tsens_set_trips(void *_sensor, int low, int high);
irqreturn_t tsens_irq_thread(int irq, void *data);
/* TSENS target */ /* TSENS target */
extern const struct tsens_plat_data data_8960; extern const struct tsens_plat_data data_8960;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment