^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * jc42.c - driver for Jedec JC42.4 compliant temperature sensors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2010 Ericsson AB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Derived from lm77.c by Andras BALI <drewie@freemail.hu>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * JC42.4 compliant temperature sensors are typically used on memory modules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/hwmon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /* Addresses to scan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static const unsigned short normal_i2c[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, I2C_CLIENT_END };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /* JC42 registers. All registers are 16 bit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define JC42_REG_CAP 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define JC42_REG_CONFIG 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define JC42_REG_TEMP_UPPER 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define JC42_REG_TEMP_LOWER 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define JC42_REG_TEMP_CRITICAL 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define JC42_REG_TEMP 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define JC42_REG_MANID 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define JC42_REG_DEVICEID 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define JC42_REG_SMBUS 0x22 /* NXP and Atmel, possibly others? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* Status bits in temperature register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define JC42_ALARM_CRIT_BIT 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define JC42_ALARM_MAX_BIT 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define JC42_ALARM_MIN_BIT 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* Configuration register defines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define JC42_CFG_CRIT_ONLY (1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define JC42_CFG_TCRIT_LOCK (1 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define JC42_CFG_EVENT_LOCK (1 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define JC42_CFG_SHUTDOWN (1 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define JC42_CFG_HYST_SHIFT 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define JC42_CFG_HYST_MASK (0x03 << 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* Capabilities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define JC42_CAP_RANGE (1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /* Manufacturer IDs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define ADT_MANID 0x11d4 /* Analog Devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define ATMEL_MANID 0x001f /* Atmel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define ATMEL_MANID2 0x1114 /* Atmel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define MAX_MANID 0x004d /* Maxim */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define IDT_MANID 0x00b3 /* IDT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define MCP_MANID 0x0054 /* Microchip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define NXP_MANID 0x1131 /* NXP Semiconductors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define ONS_MANID 0x1b09 /* ON Semiconductor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define STM_MANID 0x104a /* ST Microelectronics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define GT_MANID 0x1c68 /* Giantec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define GT_MANID2 0x132d /* Giantec, 2nd mfg ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* SMBUS register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define SMBUS_STMOUT BIT(7) /* SMBus time-out, active low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* Supported chips */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* Analog Devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define ADT7408_DEVID 0x0801
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define ADT7408_DEVID_MASK 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* Atmel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define AT30TS00_DEVID 0x8201
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define AT30TS00_DEVID_MASK 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define AT30TSE004_DEVID 0x2200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define AT30TSE004_DEVID_MASK 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* Giantec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define GT30TS00_DEVID 0x2200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define GT30TS00_DEVID_MASK 0xff00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define GT34TS02_DEVID 0x3300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define GT34TS02_DEVID_MASK 0xff00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* IDT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define TSE2004_DEVID 0x2200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define TSE2004_DEVID_MASK 0xff00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define TS3000_DEVID 0x2900 /* Also matches TSE2002 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define TS3000_DEVID_MASK 0xff00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define TS3001_DEVID 0x3000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define TS3001_DEVID_MASK 0xff00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* Maxim */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define MAX6604_DEVID 0x3e00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define MAX6604_DEVID_MASK 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* Microchip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define MCP9804_DEVID 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define MCP9804_DEVID_MASK 0xfffc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define MCP9808_DEVID 0x0400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define MCP9808_DEVID_MASK 0xfffc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define MCP98242_DEVID 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define MCP98242_DEVID_MASK 0xfffc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define MCP98243_DEVID 0x2100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define MCP98243_DEVID_MASK 0xfffc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define MCP98244_DEVID 0x2200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define MCP98244_DEVID_MASK 0xfffc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define MCP9843_DEVID 0x0000 /* Also matches mcp9805 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define MCP9843_DEVID_MASK 0xfffe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* NXP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define SE97_DEVID 0xa200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define SE97_DEVID_MASK 0xfffc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define SE98_DEVID 0xa100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define SE98_DEVID_MASK 0xfffc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* ON Semiconductor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define CAT6095_DEVID 0x0800 /* Also matches CAT34TS02 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define CAT6095_DEVID_MASK 0xffe0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define CAT34TS02C_DEVID 0x0a00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define CAT34TS02C_DEVID_MASK 0xfff0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define CAT34TS04_DEVID 0x2200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define CAT34TS04_DEVID_MASK 0xfff0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* ST Microelectronics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define STTS424_DEVID 0x0101
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define STTS424_DEVID_MASK 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define STTS424E_DEVID 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define STTS424E_DEVID_MASK 0xfffe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define STTS2002_DEVID 0x0300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define STTS2002_DEVID_MASK 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define STTS2004_DEVID 0x2201
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define STTS2004_DEVID_MASK 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define STTS3000_DEVID 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define STTS3000_DEVID_MASK 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static u16 jc42_hysteresis[] = { 0, 1500, 3000, 6000 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct jc42_chips {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) u16 manid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) u16 devid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) u16 devid_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static struct jc42_chips jc42_chips[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) { ADT_MANID, ADT7408_DEVID, ADT7408_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) { ATMEL_MANID, AT30TS00_DEVID, AT30TS00_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) { ATMEL_MANID2, AT30TSE004_DEVID, AT30TSE004_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) { GT_MANID, GT30TS00_DEVID, GT30TS00_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) { GT_MANID2, GT34TS02_DEVID, GT34TS02_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) { IDT_MANID, TSE2004_DEVID, TSE2004_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) { IDT_MANID, TS3000_DEVID, TS3000_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) { IDT_MANID, TS3001_DEVID, TS3001_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) { MAX_MANID, MAX6604_DEVID, MAX6604_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) { MCP_MANID, MCP9804_DEVID, MCP9804_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) { MCP_MANID, MCP9808_DEVID, MCP9808_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) { MCP_MANID, MCP98242_DEVID, MCP98242_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) { MCP_MANID, MCP98243_DEVID, MCP98243_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) { MCP_MANID, MCP98244_DEVID, MCP98244_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) { MCP_MANID, MCP9843_DEVID, MCP9843_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) { NXP_MANID, SE97_DEVID, SE97_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) { ONS_MANID, CAT6095_DEVID, CAT6095_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) { ONS_MANID, CAT34TS02C_DEVID, CAT34TS02C_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) { ONS_MANID, CAT34TS04_DEVID, CAT34TS04_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) { NXP_MANID, SE98_DEVID, SE98_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) { STM_MANID, STTS424_DEVID, STTS424_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) { STM_MANID, STTS424E_DEVID, STTS424E_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) { STM_MANID, STTS2002_DEVID, STTS2002_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) { STM_MANID, STTS2004_DEVID, STTS2004_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) { STM_MANID, STTS3000_DEVID, STTS3000_DEVID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) enum temp_index {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) t_input = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) t_crit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) t_min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) t_max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) t_num_temp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static const u8 temp_regs[t_num_temp] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) [t_input] = JC42_REG_TEMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) [t_crit] = JC42_REG_TEMP_CRITICAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) [t_min] = JC42_REG_TEMP_LOWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) [t_max] = JC42_REG_TEMP_UPPER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* Each client has this additional data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct jc42_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct mutex update_lock; /* protect register access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) bool extended; /* true if extended range supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) bool valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) unsigned long last_updated; /* In jiffies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) u16 orig_config; /* original configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) u16 config; /* current configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) u16 temp[t_num_temp];/* Temperatures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) #define JC42_TEMP_MIN_EXTENDED (-40000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #define JC42_TEMP_MIN 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #define JC42_TEMP_MAX 125000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static u16 jc42_temp_to_reg(long temp, bool extended)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) int ntemp = clamp_val(temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) extended ? JC42_TEMP_MIN_EXTENDED :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) JC42_TEMP_MIN, JC42_TEMP_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /* convert from 0.001 to 0.0625 resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return (ntemp * 2 / 125) & 0x1fff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static int jc42_temp_from_reg(s16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) reg = sign_extend32(reg, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* convert from 0.0625 to 0.001 resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return reg * 125 / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static struct jc42_data *jc42_update_device(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct jc42_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct jc42_data *ret = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) int i, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) for (i = 0; i < t_num_temp; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) val = i2c_smbus_read_word_swapped(client, temp_regs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ret = ERR_PTR(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) data->temp[i] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) data->last_updated = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) data->valid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) abort:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static int jc42_read(struct device *dev, enum hwmon_sensor_types type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) u32 attr, int channel, long *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct jc42_data *data = jc42_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) int temp, hyst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) case hwmon_temp_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) *val = jc42_temp_from_reg(data->temp[t_input]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) case hwmon_temp_min:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) *val = jc42_temp_from_reg(data->temp[t_min]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) case hwmon_temp_max:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) *val = jc42_temp_from_reg(data->temp[t_max]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) case hwmon_temp_crit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) *val = jc42_temp_from_reg(data->temp[t_crit]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) case hwmon_temp_max_hyst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) temp = jc42_temp_from_reg(data->temp[t_max]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) >> JC42_CFG_HYST_SHIFT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) *val = temp - hyst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) case hwmon_temp_crit_hyst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) temp = jc42_temp_from_reg(data->temp[t_crit]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) hyst = jc42_hysteresis[(data->config & JC42_CFG_HYST_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) >> JC42_CFG_HYST_SHIFT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) *val = temp - hyst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) case hwmon_temp_min_alarm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) *val = (data->temp[t_input] >> JC42_ALARM_MIN_BIT) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) case hwmon_temp_max_alarm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) *val = (data->temp[t_input] >> JC42_ALARM_MAX_BIT) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) case hwmon_temp_crit_alarm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) *val = (data->temp[t_input] >> JC42_ALARM_CRIT_BIT) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static int jc42_write(struct device *dev, enum hwmon_sensor_types type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) u32 attr, int channel, long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct jc42_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) int diff, hyst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) case hwmon_temp_min:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) data->temp[t_min] = jc42_temp_to_reg(val, data->extended);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) ret = i2c_smbus_write_word_swapped(client, temp_regs[t_min],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) data->temp[t_min]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) case hwmon_temp_max:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) data->temp[t_max] = jc42_temp_to_reg(val, data->extended);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) ret = i2c_smbus_write_word_swapped(client, temp_regs[t_max],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) data->temp[t_max]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) case hwmon_temp_crit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) data->temp[t_crit] = jc42_temp_to_reg(val, data->extended);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) ret = i2c_smbus_write_word_swapped(client, temp_regs[t_crit],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) data->temp[t_crit]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) case hwmon_temp_crit_hyst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) * JC42.4 compliant chips only support four hysteresis values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * Pick best choice and go from there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) val = clamp_val(val, (data->extended ? JC42_TEMP_MIN_EXTENDED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) : JC42_TEMP_MIN) - 6000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) JC42_TEMP_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) diff = jc42_temp_from_reg(data->temp[t_crit]) - val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) hyst = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (diff > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (diff < 2250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) hyst = 1; /* 1.5 degrees C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) else if (diff < 4500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) hyst = 2; /* 3.0 degrees C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) hyst = 3; /* 6.0 degrees C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) data->config = (data->config & ~JC42_CFG_HYST_MASK) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) (hyst << JC42_CFG_HYST_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) ret = i2c_smbus_write_word_swapped(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) JC42_REG_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) data->config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) ret = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static umode_t jc42_is_visible(const void *_data, enum hwmon_sensor_types type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) u32 attr, int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) const struct jc42_data *data = _data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) unsigned int config = data->config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) umode_t mode = 0444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) switch (attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) case hwmon_temp_min:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) case hwmon_temp_max:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (!(config & JC42_CFG_EVENT_LOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) mode |= 0200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) case hwmon_temp_crit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (!(config & JC42_CFG_TCRIT_LOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) mode |= 0200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) case hwmon_temp_crit_hyst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (!(config & (JC42_CFG_EVENT_LOCK | JC42_CFG_TCRIT_LOCK)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) mode |= 0200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) case hwmon_temp_input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) case hwmon_temp_max_hyst:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) case hwmon_temp_min_alarm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) case hwmon_temp_max_alarm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) case hwmon_temp_crit_alarm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /* Return 0 if detection is successful, -ENODEV otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct i2c_adapter *adapter = client->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) int i, config, cap, manid, devid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) I2C_FUNC_SMBUS_WORD_DATA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) cap = i2c_smbus_read_word_swapped(client, JC42_REG_CAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) config = i2c_smbus_read_word_swapped(client, JC42_REG_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) manid = i2c_smbus_read_word_swapped(client, JC42_REG_MANID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) devid = i2c_smbus_read_word_swapped(client, JC42_REG_DEVICEID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (cap < 0 || config < 0 || manid < 0 || devid < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if ((cap & 0xff00) || (config & 0xf800))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) for (i = 0; i < ARRAY_SIZE(jc42_chips); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) struct jc42_chips *chip = &jc42_chips[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (manid == chip->manid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) (devid & chip->devid_mask) == chip->devid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) strlcpy(info->type, "jc42", I2C_NAME_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) static const struct hwmon_channel_info *jc42_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) HWMON_CHANNEL_INFO(temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) HWMON_T_CRIT | HWMON_T_MAX_HYST |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) static const struct hwmon_ops jc42_hwmon_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) .is_visible = jc42_is_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) .read = jc42_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) .write = jc42_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static const struct hwmon_chip_info jc42_chip_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) .ops = &jc42_hwmon_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) .info = jc42_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) static int jc42_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) struct device *hwmon_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct jc42_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) int config, cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) data = devm_kzalloc(dev, sizeof(struct jc42_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) data->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) i2c_set_clientdata(client, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) mutex_init(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) cap = i2c_smbus_read_word_swapped(client, JC42_REG_CAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (cap < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) data->extended = !!(cap & JC42_CAP_RANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (device_property_read_bool(dev, "smbus-timeout-disable")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) int smbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * Not all chips support this register, but from a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * quick read of various datasheets no chip appears
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * incompatible with the below attempt to disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * the timeout. And the whole thing is opt-in...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) smbus = i2c_smbus_read_word_swapped(client, JC42_REG_SMBUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (smbus < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return smbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) i2c_smbus_write_word_swapped(client, JC42_REG_SMBUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) smbus | SMBUS_STMOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) config = i2c_smbus_read_word_swapped(client, JC42_REG_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (config < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) data->orig_config = config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (config & JC42_CFG_SHUTDOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) config &= ~JC42_CFG_SHUTDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) data->config = config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) hwmon_dev = devm_hwmon_device_register_with_info(dev, "jc42",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) data, &jc42_chip_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) return PTR_ERR_OR_ZERO(hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) static int jc42_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) struct jc42_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) /* Restore original configuration except hysteresis */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if ((data->config & ~JC42_CFG_HYST_MASK) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) (data->orig_config & ~JC42_CFG_HYST_MASK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) int config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) config = (data->orig_config & ~JC42_CFG_HYST_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) | (data->config & JC42_CFG_HYST_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) static int jc42_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) struct jc42_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) data->config |= JC42_CFG_SHUTDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) data->config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) static int jc42_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) struct jc42_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) data->config &= ~JC42_CFG_SHUTDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) data->config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) static const struct dev_pm_ops jc42_dev_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) .suspend = jc42_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) .resume = jc42_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) #define JC42_DEV_PM_OPS (&jc42_dev_pm_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) #define JC42_DEV_PM_OPS NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) #endif /* CONFIG_PM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) static const struct i2c_device_id jc42_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) { "jc42", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) MODULE_DEVICE_TABLE(i2c, jc42_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static const struct of_device_id jc42_of_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) { .compatible = "jedec,jc-42.4-temp", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) MODULE_DEVICE_TABLE(of, jc42_of_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) static struct i2c_driver jc42_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) .class = I2C_CLASS_SPD | I2C_CLASS_HWMON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) .name = "jc42",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) .pm = JC42_DEV_PM_OPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) .of_match_table = of_match_ptr(jc42_of_ids),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) .probe_new = jc42_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) .remove = jc42_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) .id_table = jc42_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) .detect = jc42_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) .address_list = normal_i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) module_i2c_driver(jc42_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) MODULE_DESCRIPTION("JC42 driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) MODULE_LICENSE("GPL");