aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ipq806x/patches-4.9/0063-1-ipq806x-tsens-driver.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/ipq806x/patches-4.9/0063-1-ipq806x-tsens-driver.patch')
-rw-r--r--target/linux/ipq806x/patches-4.9/0063-1-ipq806x-tsens-driver.patch627
1 files changed, 0 insertions, 627 deletions
diff --git a/target/linux/ipq806x/patches-4.9/0063-1-ipq806x-tsens-driver.patch b/target/linux/ipq806x/patches-4.9/0063-1-ipq806x-tsens-driver.patch
deleted file mode 100644
index 685b0c3ce1..0000000000
--- a/target/linux/ipq806x/patches-4.9/0063-1-ipq806x-tsens-driver.patch
+++ /dev/null
@@ -1,627 +0,0 @@
-From 3302e1e1a3cfa4e67fda2a61d6f0c42205d40932 Mon Sep 17 00:00:00 2001
-From: Rajith Cherian <rajith@codeaurora.org>
-Date: Tue, 14 Feb 2017 18:30:43 +0530
-Subject: [PATCH] ipq8064: tsens: Base tsens driver for IPQ8064
-
-Add TSENS driver template to support IPQ8064.
-This is a base file copied from tsens-8960.c
-
-Change-Id: I47c573fdfa2d898243c6a6ba952d1632f91391f7
-Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
-
-ipq8064: tsens: TSENS driver support for IPQ8064
-
-Support for IPQ8064 tsens driver. The driver works
-with the thermal framework. The driver overrides the
-following fucntionalities:
-
-1. Get current temperature.
-2. Get/Set trip temperatures.
-3. Enabled/Disable trip points.
-4. ISR for threshold generated interrupt.
-5. Notify userspace when trip points are hit.
-
-Change-Id: I8bc7204fd627d10875ab13fc1de8cb6c2ed7a918
-Signed-off-by: Rajith Cherian <rajith@codeaurora.org>
----
- .../devicetree/bindings/thermal/qcom-tsens.txt | 1 +
- drivers/thermal/qcom/Makefile | 3 +-
- drivers/thermal/qcom/tsens-ipq8064.c | 551 +++++++++++++++++++++
- drivers/thermal/qcom/tsens.c | 3 +
- drivers/thermal/qcom/tsens.h | 2 +-
- 5 files changed, 558 insertions(+), 2 deletions(-)
- create mode 100644 drivers/thermal/qcom/tsens-ipq8064.c
-
---- a/Documentation/devicetree/bindings/thermal/qcom-tsens.txt
-+++ b/Documentation/devicetree/bindings/thermal/qcom-tsens.txt
-@@ -5,6 +5,7 @@ Required properties:
- - "qcom,msm8916-tsens" : For 8916 Family of SoCs
- - "qcom,msm8974-tsens" : For 8974 Family of SoCs
- - "qcom,msm8996-tsens" : For 8996 Family of SoCs
-+ - "qcom,ipq8064-tsens" : For IPQ8064
-
- - reg: Address range of the thermal registers
- - #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description.
---- a/drivers/thermal/qcom/Makefile
-+++ b/drivers/thermal/qcom/Makefile
-@@ -1,2 +1,3 @@
- obj-$(CONFIG_QCOM_TSENS) += qcom_tsens.o
--qcom_tsens-y += tsens.o tsens-common.o tsens-8916.o tsens-8974.o tsens-8960.o tsens-8996.o
-+qcom_tsens-y += tsens.o tsens-common.o tsens-8916.o tsens-8974.o tsens-8960.o tsens-8996.o \
-+ tsens-ipq8064.o
---- /dev/null
-+++ b/drivers/thermal/qcom/tsens-ipq8064.c
-@@ -0,0 +1,551 @@
-+/*
-+ * Copyright (c) 2015, 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
-+ * only version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ */
-+
-+#include <linux/platform_device.h>
-+#include <linux/delay.h>
-+#include <linux/bitops.h>
-+#include <linux/regmap.h>
-+#include <linux/thermal.h>
-+#include <linux/nvmem-consumer.h>
-+#include <linux/io.h>
-+#include <linux/interrupt.h>
-+#include "tsens.h"
-+
-+#define CAL_MDEGC 30000
-+
-+#define CONFIG_ADDR 0x3640
-+/* CONFIG_ADDR bitmasks */
-+#define CONFIG 0x9b
-+#define CONFIG_MASK 0xf
-+#define CONFIG_SHIFT 0
-+
-+#define STATUS_CNTL_8064 0x3660
-+#define CNTL_ADDR 0x3620
-+/* CNTL_ADDR bitmasks */
-+#define EN BIT(0)
-+#define SW_RST BIT(1)
-+#define SENSOR0_EN BIT(3)
-+#define SLP_CLK_ENA BIT(26)
-+#define MEASURE_PERIOD 1
-+#define SENSOR0_SHIFT 3
-+
-+/* INT_STATUS_ADDR bitmasks */
-+#define MIN_STATUS_MASK BIT(0)
-+#define LOWER_STATUS_CLR BIT(1)
-+#define UPPER_STATUS_CLR BIT(2)
-+#define MAX_STATUS_MASK BIT(3)
-+
-+#define THRESHOLD_ADDR 0x3624
-+/* THRESHOLD_ADDR bitmasks */
-+#define THRESHOLD_MAX_CODE 0x20000
-+#define THRESHOLD_MIN_CODE 0
-+#define THRESHOLD_MAX_LIMIT_SHIFT 24
-+#define THRESHOLD_MIN_LIMIT_SHIFT 16
-+#define THRESHOLD_UPPER_LIMIT_SHIFT 8
-+#define THRESHOLD_LOWER_LIMIT_SHIFT 0
-+#define THRESHOLD_MAX_LIMIT_MASK (THRESHOLD_MAX_CODE << \
-+ THRESHOLD_MAX_LIMIT_SHIFT)
-+#define THRESHOLD_MIN_LIMIT_MASK (THRESHOLD_MAX_CODE << \
-+ THRESHOLD_MIN_LIMIT_SHIFT)
-+#define THRESHOLD_UPPER_LIMIT_MASK (THRESHOLD_MAX_CODE << \
-+ THRESHOLD_UPPER_LIMIT_SHIFT)
-+#define THRESHOLD_LOWER_LIMIT_MASK (THRESHOLD_MAX_CODE << \
-+ THRESHOLD_LOWER_LIMIT_SHIFT)
-+
-+/* Initial temperature threshold values */
-+#define LOWER_LIMIT_TH 0x9d /* 95C */
-+#define UPPER_LIMIT_TH 0xa6 /* 105C */
-+#define MIN_LIMIT_TH 0x0
-+#define MAX_LIMIT_TH 0xff
-+
-+#define S0_STATUS_ADDR 0x3628
-+#define STATUS_ADDR_OFFSET 2
-+#define SENSOR_STATUS_SIZE 4
-+#define INT_STATUS_ADDR 0x363c
-+#define TRDY_MASK BIT(7)
-+#define TIMEOUT_US 100
-+
-+#define TSENS_EN BIT(0)
-+#define TSENS_SW_RST BIT(1)
-+#define TSENS_ADC_CLK_SEL BIT(2)
-+#define SENSOR0_EN BIT(3)
-+#define SENSOR1_EN BIT(4)
-+#define SENSOR2_EN BIT(5)
-+#define SENSOR3_EN BIT(6)
-+#define SENSOR4_EN BIT(7)
-+#define SENSORS_EN (SENSOR0_EN | SENSOR1_EN | \
-+ SENSOR2_EN | SENSOR3_EN | SENSOR4_EN)
-+#define TSENS_8064_SENSOR5_EN BIT(8)
-+#define TSENS_8064_SENSOR6_EN BIT(9)
-+#define TSENS_8064_SENSOR7_EN BIT(10)
-+#define TSENS_8064_SENSOR8_EN BIT(11)
-+#define TSENS_8064_SENSOR9_EN BIT(12)
-+#define TSENS_8064_SENSOR10_EN BIT(13)
-+#define TSENS_8064_SENSORS_EN (SENSORS_EN | \
-+ TSENS_8064_SENSOR5_EN | \
-+ TSENS_8064_SENSOR6_EN | \
-+ TSENS_8064_SENSOR7_EN | \
-+ TSENS_8064_SENSOR8_EN | \
-+ TSENS_8064_SENSOR9_EN | \
-+ TSENS_8064_SENSOR10_EN)
-+
-+#define TSENS_8064_SEQ_SENSORS 5
-+#define TSENS_8064_S4_S5_OFFSET 40
-+#define TSENS_FACTOR 1
-+
-+/* Trips: from very hot to very cold */
-+enum tsens_trip_type {
-+ TSENS_TRIP_STAGE3 = 0,
-+ TSENS_TRIP_STAGE2,
-+ TSENS_TRIP_STAGE1,
-+ TSENS_TRIP_STAGE0,
-+ TSENS_TRIP_NUM,
-+};
-+
-+u32 tsens_8064_slope[] = {
-+ 1176, 1176, 1154, 1176,
-+ 1111, 1132, 1132, 1199,
-+ 1132, 1199, 1132
-+ };
-+
-+/* Temperature on y axis and ADC-code on x-axis */
-+static inline int code_to_degC(u32 adc_code, const struct tsens_sensor *s)
-+{
-+ int degcbeforefactor, degc;
-+
-+ degcbeforefactor = (adc_code * s->slope) + s->offset;
-+
-+ if (degcbeforefactor == 0)
-+ degc = degcbeforefactor;
-+ else if (degcbeforefactor > 0)
-+ degc = (degcbeforefactor + TSENS_FACTOR/2)
-+ / TSENS_FACTOR;
-+ else
-+ degc = (degcbeforefactor - TSENS_FACTOR/2)
-+ / TSENS_FACTOR;
-+
-+ return degc;
-+}
-+
-+static int degC_to_code(int degC, const struct tsens_sensor *s)
-+{
-+ int code = ((degC * TSENS_FACTOR - s->offset) + (s->slope/2))
-+ / s->slope;
-+
-+ if (code > THRESHOLD_MAX_CODE)
-+ code = THRESHOLD_MAX_CODE;
-+ else if (code < THRESHOLD_MIN_CODE)
-+ code = THRESHOLD_MIN_CODE;
-+ return code;
-+}
-+
-+static int suspend_ipq8064(struct tsens_device *tmdev)
-+{
-+ int ret;
-+ unsigned int mask;
-+ struct regmap *map = tmdev->map;
-+
-+ ret = regmap_read(map, THRESHOLD_ADDR, &tmdev->ctx.threshold);
-+ if (ret)
-+ return ret;
-+
-+ ret = regmap_read(map, CNTL_ADDR, &tmdev->ctx.control);
-+ if (ret)
-+ return ret;
-+
-+ mask = SLP_CLK_ENA | EN;
-+
-+ ret = regmap_update_bits(map, CNTL_ADDR, mask, 0);
-+ if (ret)
-+ return ret;
-+
-+ return 0;
-+}
-+
-+static int resume_ipq8064(struct tsens_device *tmdev)
-+{
-+ int ret;
-+ struct regmap *map = tmdev->map;
-+
-+ ret = regmap_update_bits(map, CNTL_ADDR, SW_RST, SW_RST);
-+ if (ret)
-+ return ret;
-+
-+ ret = regmap_update_bits(map, CONFIG_ADDR, CONFIG_MASK, CONFIG);
-+ if (ret)
-+ return ret;
-+
-+ ret = regmap_write(map, THRESHOLD_ADDR, tmdev->ctx.threshold);
-+ if (ret)
-+ return ret;
-+
-+ ret = regmap_write(map, CNTL_ADDR, tmdev->ctx.control);
-+ if (ret)
-+ return ret;
-+
-+ return 0;
-+}
-+
-+static void notify_uspace_tsens_fn(struct work_struct *work)
-+{
-+ struct tsens_sensor *s = container_of(work, struct tsens_sensor,
-+ notify_work);
-+
-+ sysfs_notify(&s->tzd->device.kobj, NULL, "type");
-+}
-+
-+static void tsens_scheduler_fn(struct work_struct *work)
-+{
-+ struct tsens_device *tmdev = container_of(work, struct tsens_device,
-+ tsens_work);
-+ unsigned int threshold, threshold_low, code, reg, sensor, mask;
-+ unsigned int sensor_addr;
-+ bool upper_th_x, lower_th_x;
-+ int adc_code, ret;
-+
-+ ret = regmap_read(tmdev->map, STATUS_CNTL_8064, &reg);
-+ if (ret)
-+ return;
-+ reg = reg | LOWER_STATUS_CLR | UPPER_STATUS_CLR;
-+ ret = regmap_write(tmdev->map, STATUS_CNTL_8064, reg);
-+ if (ret)
-+ return;
-+
-+ mask = ~(LOWER_STATUS_CLR | UPPER_STATUS_CLR);
-+ ret = regmap_read(tmdev->map, THRESHOLD_ADDR, &threshold);
-+ if (ret)
-+ return;
-+ threshold_low = (threshold & THRESHOLD_LOWER_LIMIT_MASK)
-+ >> THRESHOLD_LOWER_LIMIT_SHIFT;
-+ threshold = (threshold & THRESHOLD_UPPER_LIMIT_MASK)
-+ >> THRESHOLD_UPPER_LIMIT_SHIFT;
-+
-+ ret = regmap_read(tmdev->map, STATUS_CNTL_8064, &reg);
-+ if (ret)
-+ return;
-+
-+ ret = regmap_read(tmdev->map, CNTL_ADDR, &sensor);
-+ if (ret)
-+ return;
-+ sensor &= (uint32_t) TSENS_8064_SENSORS_EN;
-+ sensor >>= SENSOR0_SHIFT;
-+
-+ /* Constraint: There is only 1 interrupt control register for all
-+ * 11 temperature sensor. So monitoring more than 1 sensor based
-+ * on interrupts will yield inconsistent result. To overcome this
-+ * issue we will monitor only sensor 0 which is the master sensor.
-+ */
-+
-+ /* Skip if the sensor is disabled */
-+ if (sensor & 1) {
-+ ret = regmap_read(tmdev->map, tmdev->sensor[0].status, &code);
-+ if (ret)
-+ return;
-+ upper_th_x = code >= threshold;
-+ lower_th_x = code <= threshold_low;
-+ if (upper_th_x)
-+ mask |= UPPER_STATUS_CLR;
-+ if (lower_th_x)
-+ mask |= LOWER_STATUS_CLR;
-+ if (upper_th_x || lower_th_x) {
-+ /* Notify user space */
-+ schedule_work(&tmdev->sensor[0].notify_work);
-+ regmap_read(tmdev->map, sensor_addr, &adc_code);
-+ pr_debug("Trigger (%d degrees) for sensor %d\n",
-+ code_to_degC(adc_code, &tmdev->sensor[0]), 0);
-+ }
-+ }
-+ regmap_write(tmdev->map, STATUS_CNTL_8064, reg & mask);
-+
-+ /* force memory to sync */
-+ mb();
-+}
-+
-+static irqreturn_t tsens_isr(int irq, void *data)
-+{
-+ struct tsens_device *tmdev = data;
-+
-+ schedule_work(&tmdev->tsens_work);
-+ return IRQ_HANDLED;
-+}
-+
-+static void hw_init(struct tsens_device *tmdev)
-+{
-+ int ret;
-+ unsigned int reg_cntl = 0, reg_cfg = 0, reg_thr = 0;
-+ unsigned int reg_status_cntl = 0;
-+
-+ regmap_read(tmdev->map, CNTL_ADDR, &reg_cntl);
-+ regmap_write(tmdev->map, CNTL_ADDR, reg_cntl | TSENS_SW_RST);
-+
-+ reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18)
-+ | (((1 << tmdev->num_sensors) - 1) << SENSOR0_SHIFT);
-+ regmap_write(tmdev->map, CNTL_ADDR, reg_cntl);
-+ regmap_read(tmdev->map, STATUS_CNTL_8064, &reg_status_cntl);
-+ reg_status_cntl |= LOWER_STATUS_CLR | UPPER_STATUS_CLR
-+ | MIN_STATUS_MASK | MAX_STATUS_MASK;
-+ regmap_write(tmdev->map, STATUS_CNTL_8064, reg_status_cntl);
-+ reg_cntl |= TSENS_EN;
-+ regmap_write(tmdev->map, CNTL_ADDR, reg_cntl);
-+
-+ regmap_read(tmdev->map, CONFIG_ADDR, &reg_cfg);
-+ reg_cfg = (reg_cfg & ~CONFIG_MASK) | (CONFIG << CONFIG_SHIFT);
-+ regmap_write(tmdev->map, CONFIG_ADDR, reg_cfg);
-+
-+ reg_thr |= (LOWER_LIMIT_TH << THRESHOLD_LOWER_LIMIT_SHIFT)
-+ | (UPPER_LIMIT_TH << THRESHOLD_UPPER_LIMIT_SHIFT)
-+ | (MIN_LIMIT_TH << THRESHOLD_MIN_LIMIT_SHIFT)
-+ | (MAX_LIMIT_TH << THRESHOLD_MAX_LIMIT_SHIFT);
-+
-+ regmap_write(tmdev->map, THRESHOLD_ADDR, reg_thr);
-+
-+ ret = devm_request_irq(tmdev->dev, tmdev->tsens_irq, tsens_isr,
-+ IRQF_TRIGGER_RISING, "tsens_interrupt", tmdev);
-+ if (ret < 0) {
-+ pr_err("%s: request_irq FAIL: %d\n", __func__, ret);
-+ return;
-+ }
-+
-+ INIT_WORK(&tmdev->tsens_work, tsens_scheduler_fn);
-+}
-+
-+static int init_ipq8064(struct tsens_device *tmdev)
-+{
-+ int ret, i;
-+ u32 reg_cntl, offset = 0;
-+
-+ init_common(tmdev);
-+ if (!tmdev->map)
-+ return -ENODEV;
-+
-+ /*
-+ * The status registers for each sensor are discontiguous
-+ * because some SoCs have 5 sensors while others have more
-+ * but the control registers stay in the same place, i.e
-+ * directly after the first 5 status registers.
-+ */
-+ for (i = 0; i < tmdev->num_sensors; i++) {
-+ if (i >= TSENS_8064_SEQ_SENSORS)
-+ offset = TSENS_8064_S4_S5_OFFSET;
-+
-+ tmdev->sensor[i].status = S0_STATUS_ADDR + offset
-+ + (i << STATUS_ADDR_OFFSET);
-+ tmdev->sensor[i].slope = tsens_8064_slope[i];
-+ INIT_WORK(&tmdev->sensor[i].notify_work,
-+ notify_uspace_tsens_fn);
-+ }
-+
-+ reg_cntl = SW_RST;
-+ ret = regmap_update_bits(tmdev->map, CNTL_ADDR, SW_RST, reg_cntl);
-+ if (ret)
-+ return ret;
-+
-+ reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18);
-+ reg_cntl &= ~SW_RST;
-+ ret = regmap_update_bits(tmdev->map, CONFIG_ADDR,
-+ CONFIG_MASK, CONFIG);
-+
-+ reg_cntl |= GENMASK(tmdev->num_sensors - 1, 0) << SENSOR0_SHIFT;
-+ ret = regmap_write(tmdev->map, CNTL_ADDR, reg_cntl);
-+ if (ret)
-+ return ret;
-+
-+ reg_cntl |= EN;
-+ ret = regmap_write(tmdev->map, CNTL_ADDR, reg_cntl);
-+ if (ret)
-+ return ret;
-+
-+ return 0;
-+}
-+
-+static int calibrate_ipq8064(struct tsens_device *tmdev)
-+{
-+ int i;
-+ char *data, *data_backup;
-+
-+ ssize_t num_read = tmdev->num_sensors;
-+ struct tsens_sensor *s = tmdev->sensor;
-+
-+ data = qfprom_read(tmdev->dev, "calib");
-+ if (IS_ERR(data)) {
-+ pr_err("Calibration not found.\n");
-+ return PTR_ERR(data);
-+ }
-+
-+ data_backup = qfprom_read(tmdev->dev, "calib_backup");
-+ if (IS_ERR(data_backup)) {
-+ pr_err("Backup calibration not found.\n");
-+ return PTR_ERR(data_backup);
-+ }
-+
-+ for (i = 0; i < num_read; i++) {
-+ s[i].calib_data = readb_relaxed(data + i);
-+ s[i].calib_data_backup = readb_relaxed(data_backup + i);
-+
-+ if (s[i].calib_data_backup)
-+ s[i].calib_data = s[i].calib_data_backup;
-+ if (!s[i].calib_data) {
-+ pr_err("QFPROM TSENS calibration data not present\n");
-+ return -ENODEV;
-+ }
-+ s[i].slope = tsens_8064_slope[i];
-+ s[i].offset = CAL_MDEGC - (s[i].calib_data * s[i].slope);
-+ }
-+
-+ hw_init(tmdev);
-+
-+ return 0;
-+}
-+
-+static int get_temp_ipq8064(struct tsens_device *tmdev, int id, int *temp)
-+{
-+ int ret;
-+ u32 code, trdy;
-+ const struct tsens_sensor *s = &tmdev->sensor[id];
-+ unsigned long timeout;
-+
-+ timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
-+ do {
-+ ret = regmap_read(tmdev->map, INT_STATUS_ADDR, &trdy);
-+ if (ret)
-+ return ret;
-+ if (!(trdy & TRDY_MASK))
-+ continue;
-+ ret = regmap_read(tmdev->map, s->status, &code);
-+ if (ret)
-+ return ret;
-+ *temp = code_to_degC(code, s);
-+ return 0;
-+ } while (time_before(jiffies, timeout));
-+
-+ return -ETIMEDOUT;
-+}
-+
-+static int set_trip_temp_ipq8064(void *data, int trip, int temp)
-+{
-+ unsigned int reg_th, reg_cntl;
-+ int ret, code, code_chk, hi_code, lo_code;
-+ const struct tsens_sensor *s = data;
-+ struct tsens_device *tmdev = s->tmdev;
-+
-+ code_chk = code = degC_to_code(temp, s);
-+
-+ if (code < THRESHOLD_MIN_CODE || code > THRESHOLD_MAX_CODE)
-+ return -EINVAL;
-+
-+ ret = regmap_read(tmdev->map, STATUS_CNTL_8064, &reg_cntl);
-+ if (ret)
-+ return ret;
-+
-+ ret = regmap_read(tmdev->map, THRESHOLD_ADDR, &reg_th);
-+ if (ret)
-+ return ret;
-+
-+ hi_code = (reg_th & THRESHOLD_UPPER_LIMIT_MASK)
-+ >> THRESHOLD_UPPER_LIMIT_SHIFT;
-+ lo_code = (reg_th & THRESHOLD_LOWER_LIMIT_MASK)
-+ >> THRESHOLD_LOWER_LIMIT_SHIFT;
-+
-+ switch (trip) {
-+ case TSENS_TRIP_STAGE3:
-+ code <<= THRESHOLD_MAX_LIMIT_SHIFT;
-+ reg_th &= ~THRESHOLD_MAX_LIMIT_MASK;
-+ break;
-+ case TSENS_TRIP_STAGE2:
-+ if (code_chk <= lo_code)
-+ return -EINVAL;
-+ code <<= THRESHOLD_UPPER_LIMIT_SHIFT;
-+ reg_th &= ~THRESHOLD_UPPER_LIMIT_MASK;
-+ break;
-+ case TSENS_TRIP_STAGE1:
-+ if (code_chk >= hi_code)
-+ return -EINVAL;
-+ code <<= THRESHOLD_LOWER_LIMIT_SHIFT;
-+ reg_th &= ~THRESHOLD_LOWER_LIMIT_MASK;
-+ break;
-+ case TSENS_TRIP_STAGE0:
-+ code <<= THRESHOLD_MIN_LIMIT_SHIFT;
-+ reg_th &= ~THRESHOLD_MIN_LIMIT_MASK;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ ret = regmap_write(tmdev->map, THRESHOLD_ADDR, reg_th | code);
-+ if (ret)
-+ return ret;
-+
-+ return 0;
-+}
-+
-+static int set_trip_activate_ipq8064(void *data, int trip,
-+ enum thermal_trip_activation_mode mode)
-+{
-+ unsigned int reg_cntl, mask, val;
-+ const struct tsens_sensor *s = data;
-+ struct tsens_device *tmdev = s->tmdev;
-+ int ret;
-+
-+ if (!tmdev || trip < 0)
-+ return -EINVAL;
-+
-+ ret = regmap_read(tmdev->map, STATUS_CNTL_8064, &reg_cntl);
-+ if (ret)
-+ return ret;
-+
-+ switch (trip) {
-+ case TSENS_TRIP_STAGE3:
-+ mask = MAX_STATUS_MASK;
-+ break;
-+ case TSENS_TRIP_STAGE2:
-+ mask = UPPER_STATUS_CLR;
-+ break;
-+ case TSENS_TRIP_STAGE1:
-+ mask = LOWER_STATUS_CLR;
-+ break;
-+ case TSENS_TRIP_STAGE0:
-+ mask = MIN_STATUS_MASK;
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ if (mode == THERMAL_TRIP_ACTIVATION_DISABLED)
-+ val = reg_cntl | mask;
-+ else
-+ val = reg_cntl & ~mask;
-+
-+ ret = regmap_write(tmdev->map, STATUS_CNTL_8064, val);
-+ if (ret)
-+ return ret;
-+
-+ /* force memory to sync */
-+ mb();
-+ return 0;
-+}
-+
-+const struct tsens_ops ops_ipq8064 = {
-+ .init = init_ipq8064,
-+ .calibrate = calibrate_ipq8064,
-+ .get_temp = get_temp_ipq8064,
-+ .suspend = suspend_ipq8064,
-+ .resume = resume_ipq8064,
-+ .set_trip_temp = set_trip_temp_ipq8064,
-+ .set_trip_activate = set_trip_activate_ipq8064,
-+};
-+
-+const struct tsens_data data_ipq8064 = {
-+ .num_sensors = 11,
-+ .ops = &ops_ipq8064,
-+};
---- a/drivers/thermal/qcom/tsens.c
-+++ b/drivers/thermal/qcom/tsens.c
-@@ -72,6 +72,9 @@ static const struct of_device_id tsens_t
- }, {
- .compatible = "qcom,msm8996-tsens",
- .data = &data_8996,
-+ }, {
-+ .compatible = "qcom,ipq8064-tsens",
-+ .data = &data_ipq8064,
- },
- {}
- };
---- a/drivers/thermal/qcom/tsens.h
-+++ b/drivers/thermal/qcom/tsens.h
-@@ -89,6 +89,6 @@ void compute_intercept_slope(struct tsen
- int init_common(struct tsens_device *);
- int get_temp_common(struct tsens_device *, int, int *);
-
--extern const struct tsens_data data_8916, data_8974, data_8960, data_8996;
-+extern const struct tsens_data data_8916, data_8974, data_8960, data_8996, data_ipq8064;
-
- #endif /* __QCOM_TSENS_H__ */