^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2015, The Linux Foundation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/thermal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "tsens.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #define CAL_MDEGC 30000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define CONFIG_ADDR 0x3640
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define CONFIG_ADDR_8660 0x3620
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* CONFIG_ADDR bitmasks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define CONFIG 0x9b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define CONFIG_MASK 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define CONFIG_8660 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define CONFIG_SHIFT_8660 28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define CONFIG_MASK_8660 (3 << CONFIG_SHIFT_8660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define STATUS_CNTL_ADDR_8064 0x3660
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define CNTL_ADDR 0x3620
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* CNTL_ADDR bitmasks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define EN BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define SW_RST BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define SENSOR0_EN BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define SLP_CLK_ENA BIT(26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define SLP_CLK_ENA_8660 BIT(24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define MEASURE_PERIOD 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define SENSOR0_SHIFT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* INT_STATUS_ADDR bitmasks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define MIN_STATUS_MASK BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define LOWER_STATUS_CLR BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define UPPER_STATUS_CLR BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define MAX_STATUS_MASK BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define THRESHOLD_ADDR 0x3624
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* THRESHOLD_ADDR bitmasks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define THRESHOLD_MAX_LIMIT_SHIFT 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define THRESHOLD_MIN_LIMIT_SHIFT 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define THRESHOLD_UPPER_LIMIT_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define THRESHOLD_LOWER_LIMIT_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* Initial temperature threshold values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define LOWER_LIMIT_TH 0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define UPPER_LIMIT_TH 0xdf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define MIN_LIMIT_TH 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define MAX_LIMIT_TH 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define S0_STATUS_ADDR 0x3628
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define INT_STATUS_ADDR 0x363c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define TRDY_MASK BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define TIMEOUT_US 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static int suspend_8960(struct tsens_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) unsigned int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct regmap *map = priv->tm_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) ret = regmap_read(map, THRESHOLD_ADDR, &priv->ctx.threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ret = regmap_read(map, CNTL_ADDR, &priv->ctx.control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (priv->num_sensors > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) mask = SLP_CLK_ENA | EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) mask = SLP_CLK_ENA_8660 | EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) ret = regmap_update_bits(map, CNTL_ADDR, mask, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static int resume_8960(struct tsens_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct regmap *map = priv->tm_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) ret = regmap_update_bits(map, CNTL_ADDR, SW_RST, SW_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * Separate CONFIG restore is not needed only for 8660 as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * config is part of CTRL Addr and its restored as such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (priv->num_sensors > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ret = regmap_update_bits(map, CONFIG_ADDR, CONFIG_MASK, CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ret = regmap_write(map, THRESHOLD_ADDR, priv->ctx.threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) ret = regmap_write(map, CNTL_ADDR, priv->ctx.control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static int enable_8960(struct tsens_priv *priv, int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) u32 reg, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) ret = regmap_read(priv->tm_map, CNTL_ADDR, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) mask = BIT(id + SENSOR0_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) ret = regmap_write(priv->tm_map, CNTL_ADDR, reg | SW_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (priv->num_sensors > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) reg |= mask | SLP_CLK_ENA | EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) reg |= mask | SLP_CLK_ENA_8660 | EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) ret = regmap_write(priv->tm_map, CNTL_ADDR, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static void disable_8960(struct tsens_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) u32 reg_cntl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) mask = GENMASK(priv->num_sensors - 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) mask <<= SENSOR0_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) mask |= EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) ret = regmap_read(priv->tm_map, CNTL_ADDR, ®_cntl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) reg_cntl &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (priv->num_sensors > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) reg_cntl &= ~SLP_CLK_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) reg_cntl &= ~SLP_CLK_ENA_8660;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static int init_8960(struct tsens_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) u32 reg_cntl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) priv->tm_map = dev_get_regmap(priv->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (!priv->tm_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * The status registers for each sensor are discontiguous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * because some SoCs have 5 sensors while others have more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * but the control registers stay in the same place, i.e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * directly after the first 5 status registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) for (i = 0; i < priv->num_sensors; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (i >= 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) priv->sensor[i].status = S0_STATUS_ADDR + 40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) priv->sensor[i].status += i * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) reg_cntl = SW_RST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) ret = regmap_update_bits(priv->tm_map, CNTL_ADDR, SW_RST, reg_cntl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (priv->num_sensors > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) reg_cntl |= SLP_CLK_ENA | (MEASURE_PERIOD << 18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) reg_cntl &= ~SW_RST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) ret = regmap_update_bits(priv->tm_map, CONFIG_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) CONFIG_MASK, CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) reg_cntl |= SLP_CLK_ENA_8660 | (MEASURE_PERIOD << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) reg_cntl &= ~CONFIG_MASK_8660;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) reg_cntl |= CONFIG_8660 << CONFIG_SHIFT_8660;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) reg_cntl |= GENMASK(priv->num_sensors - 1, 0) << SENSOR0_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) reg_cntl |= EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ret = regmap_write(priv->tm_map, CNTL_ADDR, reg_cntl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static int calibrate_8960(struct tsens_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) char *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) ssize_t num_read = priv->num_sensors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct tsens_sensor *s = priv->sensor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) data = qfprom_read(priv->dev, "calib");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) data = qfprom_read(priv->dev, "calib_backup");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) for (i = 0; i < num_read; i++, s++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) s->offset = data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* Temperature on y axis and ADC-code on x-axis */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static inline int code_to_mdegC(u32 adc_code, const struct tsens_sensor *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int slope, offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) slope = thermal_zone_get_slope(s->tzd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) offset = CAL_MDEGC - slope * s->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return adc_code * slope + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int get_temp_8960(const struct tsens_sensor *s, int *temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) u32 code, trdy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct tsens_priv *priv = s->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ret = regmap_read(priv->tm_map, INT_STATUS_ADDR, &trdy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (!(trdy & TRDY_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) ret = regmap_read(priv->tm_map, s->status, &code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) *temp = code_to_mdegC(code, s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) } while (time_before(jiffies, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static const struct tsens_ops ops_8960 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) .init = init_8960,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) .calibrate = calibrate_8960,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) .get_temp = get_temp_8960,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) .enable = enable_8960,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) .disable = disable_8960,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) .suspend = suspend_8960,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) .resume = resume_8960,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct tsens_plat_data data_8960 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) .num_sensors = 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) .ops = &ops_8960,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) };