^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) * nct7802 - Driver for Nuvoton NCT7802Y
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2014 Guenter Roeck <linux@roeck-us.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/hwmon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/hwmon-sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define DRVNAME "nct7802"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static const u8 REG_VOLTAGE[5] = { 0x09, 0x0a, 0x0c, 0x0d, 0x0e };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static const u8 REG_VOLTAGE_LIMIT_LSB[2][5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) { 0x46, 0x00, 0x40, 0x42, 0x44 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) { 0x45, 0x00, 0x3f, 0x41, 0x43 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static const u8 REG_VOLTAGE_LIMIT_MSB[5] = { 0x48, 0x00, 0x47, 0x47, 0x48 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static const u8 REG_VOLTAGE_LIMIT_MSB_SHIFT[2][5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) { 0, 0, 4, 0, 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) { 2, 0, 6, 2, 6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define REG_BANK 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define REG_TEMP_LSB 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define REG_TEMP_PECI_LSB 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define REG_VOLTAGE_LOW 0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define REG_FANCOUNT_LOW 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define REG_START 0x21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define REG_MODE 0x22 /* 7.2.32 Mode Selection Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define REG_PECI_ENABLE 0x23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define REG_FAN_ENABLE 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define REG_VMON_ENABLE 0x25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define REG_PWM(x) (0x60 + (x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define REG_SMARTFAN_EN(x) (0x64 + (x) / 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define SMARTFAN_EN_SHIFT(x) ((x) % 2 * 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define REG_VENDOR_ID 0xfd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define REG_CHIP_ID 0xfe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define REG_VERSION_ID 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * Data structures and manipulation thereof
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct nct7802_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct mutex access_lock; /* for multi-byte read and write operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) u8 in_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct mutex in_alarm_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static ssize_t temp_type_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) unsigned int mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ret = regmap_read(data->regmap, REG_MODE, &mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return sprintf(buf, "%u\n", (mode >> (2 * sattr->index) & 3) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static ssize_t temp_type_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) unsigned int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) err = kstrtouint(buf, 0, &type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (sattr->index == 2 && type != 4) /* RD3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (type < 3 || type > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) err = regmap_update_bits(data->regmap, REG_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) 3 << 2 * sattr->index, (type - 2) << 2 * sattr->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return err ? : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static ssize_t pwm_mode_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) unsigned int regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (sattr->index > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return sprintf(buf, "1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ret = regmap_read(data->regmap, 0x5E, ®val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return sprintf(buf, "%u\n", !(regval & (1 << sattr->index)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static ssize_t pwm_show(struct device *dev, struct device_attribute *devattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (!attr->index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return sprintf(buf, "255\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) ret = regmap_read(data->regmap, attr->index, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return sprintf(buf, "%d\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static ssize_t pwm_store(struct device *dev, struct device_attribute *devattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) err = kstrtou8(buf, 0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) err = regmap_write(data->regmap, attr->index, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return err ? : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static ssize_t pwm_enable_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) unsigned int reg, enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ret = regmap_read(data->regmap, REG_SMARTFAN_EN(sattr->index), ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) enabled = reg >> SMARTFAN_EN_SHIFT(sattr->index) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return sprintf(buf, "%u\n", enabled + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static ssize_t pwm_enable_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ret = kstrtou8(buf, 0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (val < 1 || val > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) ret = regmap_update_bits(data->regmap, REG_SMARTFAN_EN(sattr->index),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 1 << SMARTFAN_EN_SHIFT(sattr->index),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) (val - 1) << SMARTFAN_EN_SHIFT(sattr->index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return ret ? : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static int nct7802_read_temp(struct nct7802_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) u8 reg_temp, u8 reg_temp_low, int *temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) unsigned int t1, t2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) *temp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) mutex_lock(&data->access_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) err = regmap_read(data->regmap, reg_temp, &t1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) t1 <<= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (reg_temp_low) { /* 11 bit data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) err = regmap_read(data->regmap, reg_temp_low, &t2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) t1 |= t2 & 0xe0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) *temp = (s16)t1 / 32 * 125;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) abort:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) mutex_unlock(&data->access_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static int nct7802_read_fan(struct nct7802_data *data, u8 reg_fan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) unsigned int f1, f2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) mutex_lock(&data->access_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ret = regmap_read(data->regmap, reg_fan, &f1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) ret = regmap_read(data->regmap, REG_FANCOUNT_LOW, &f2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ret = (f1 << 5) | (f2 >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /* convert fan count to rpm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (ret == 0x1fff) /* maximum value, assume fan is stopped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) else if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) ret = DIV_ROUND_CLOSEST(1350000U, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) abort:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) mutex_unlock(&data->access_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static int nct7802_read_fan_min(struct nct7802_data *data, u8 reg_fan_low,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) u8 reg_fan_high)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) unsigned int f1, f2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) mutex_lock(&data->access_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) ret = regmap_read(data->regmap, reg_fan_low, &f1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) ret = regmap_read(data->regmap, reg_fan_high, &f2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) ret = f1 | ((f2 & 0xf8) << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* convert fan count to rpm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (ret == 0x1fff) /* maximum value, assume no limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) else if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ret = DIV_ROUND_CLOSEST(1350000U, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) ret = 1350000U;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) abort:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) mutex_unlock(&data->access_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static int nct7802_write_fan_min(struct nct7802_data *data, u8 reg_fan_low,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) u8 reg_fan_high, unsigned long limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) limit = DIV_ROUND_CLOSEST(1350000U, limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) limit = 0x1fff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) limit = clamp_val(limit, 0, 0x1fff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) mutex_lock(&data->access_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) err = regmap_write(data->regmap, reg_fan_low, limit & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) err = regmap_write(data->regmap, reg_fan_high, (limit & 0x1f00) >> 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) abort:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) mutex_unlock(&data->access_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static u8 nct7802_vmul[] = { 4, 2, 2, 2, 2 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static int nct7802_read_voltage(struct nct7802_data *data, int nr, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) unsigned int v1, v2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) mutex_lock(&data->access_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (index == 0) { /* voltage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ret = regmap_read(data->regmap, REG_VOLTAGE[nr], &v1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) ret = regmap_read(data->regmap, REG_VOLTAGE_LOW, &v2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) ret = ((v1 << 2) | (v2 >> 6)) * nct7802_vmul[nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) } else { /* limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) int shift = 8 - REG_VOLTAGE_LIMIT_MSB_SHIFT[index - 1][nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) ret = regmap_read(data->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) REG_VOLTAGE_LIMIT_LSB[index - 1][nr], &v1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) ret = regmap_read(data->regmap, REG_VOLTAGE_LIMIT_MSB[nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) &v2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) ret = (v1 | ((v2 << shift) & 0x300)) * nct7802_vmul[nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) abort:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) mutex_unlock(&data->access_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static int nct7802_write_voltage(struct nct7802_data *data, int nr, int index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) unsigned long voltage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) int shift = 8 - REG_VOLTAGE_LIMIT_MSB_SHIFT[index - 1][nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) voltage = clamp_val(voltage, 0, 0x3ff * nct7802_vmul[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) voltage = DIV_ROUND_CLOSEST(voltage, nct7802_vmul[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) mutex_lock(&data->access_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) err = regmap_write(data->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) REG_VOLTAGE_LIMIT_LSB[index - 1][nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) voltage & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) err = regmap_update_bits(data->regmap, REG_VOLTAGE_LIMIT_MSB[nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 0x0300 >> shift, (voltage & 0x0300) >> shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) abort:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) mutex_unlock(&data->access_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static ssize_t in_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) int voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) voltage = nct7802_read_voltage(data, sattr->nr, sattr->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (voltage < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return sprintf(buf, "%d\n", voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static ssize_t in_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) int index = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) int nr = sattr->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) err = nct7802_write_voltage(data, nr, index, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return err ? : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static ssize_t in_alarm_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) int volt, min, max, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) mutex_lock(&data->in_alarm_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * The SMI Voltage status register is the only register giving a status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * for voltages. A bit is set for each input crossing a threshold, in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * both direction, but the "inside" or "outside" limits info is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * available. Also this register is cleared on read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * Note: this is not explicitly spelled out in the datasheet, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * from experiment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * To deal with this we use a status cache with one validity bit and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * one status bit for each input. Validity is cleared at startup and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * each time the register reports a change, and the status is processed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * by software based on current input value and limits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) ret = regmap_read(data->regmap, 0x1e, &val); /* SMI Voltage status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) /* invalidate cached status for all inputs crossing a threshold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) data->in_status &= ~((val & 0x0f) << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /* if cached status for requested input is invalid, update it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (!(data->in_status & (0x10 << sattr->index))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) ret = nct7802_read_voltage(data, sattr->nr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) volt = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) ret = nct7802_read_voltage(data, sattr->nr, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) min = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ret = nct7802_read_voltage(data, sattr->nr, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) max = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (volt < min || volt > max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) data->in_status |= (1 << sattr->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) data->in_status &= ~(1 << sattr->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) data->in_status |= 0x10 << sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) ret = sprintf(buf, "%u\n", !!(data->in_status & (1 << sattr->index)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) abort:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) mutex_unlock(&data->in_alarm_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static ssize_t temp_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) int err, temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) err = nct7802_read_temp(data, sattr->nr, sattr->index, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return sprintf(buf, "%d\n", temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) static ssize_t temp_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) int nr = sattr->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) err = kstrtol(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) val = DIV_ROUND_CLOSEST(clamp_val(val, -128000, 127000), 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) err = regmap_write(data->regmap, nr, val & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return err ? : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) static ssize_t fan_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) int speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) speed = nct7802_read_fan(data, sattr->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (speed < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return sprintf(buf, "%d\n", speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) static ssize_t fan_min_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) int speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) speed = nct7802_read_fan_min(data, sattr->nr, sattr->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (speed < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return sprintf(buf, "%d\n", speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) static ssize_t fan_min_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) err = nct7802_write_fan_min(data, sattr->nr, sattr->index, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return err ? : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) static ssize_t alarm_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) int bit = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) ret = regmap_read(data->regmap, sattr->nr, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return sprintf(buf, "%u\n", !!(val & (1 << bit)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) beep_show(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) unsigned int regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) err = regmap_read(data->regmap, sattr->nr, ®val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return sprintf(buf, "%u\n", !!(regval & (1 << sattr->index)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) beep_store(struct device *dev, struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (val > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) err = regmap_update_bits(data->regmap, sattr->nr, 1 << sattr->index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) val ? 1 << sattr->index : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return err ? : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) static SENSOR_DEVICE_ATTR_RW(temp1_type, temp_type, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) static SENSOR_DEVICE_ATTR_2_RO(temp1_input, temp, 0x01, REG_TEMP_LSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) static SENSOR_DEVICE_ATTR_2_RW(temp1_min, temp, 0x31, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) static SENSOR_DEVICE_ATTR_2_RW(temp1_max, temp, 0x30, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) static SENSOR_DEVICE_ATTR_2_RW(temp1_crit, temp, 0x3a, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) static SENSOR_DEVICE_ATTR_RW(temp2_type, temp_type, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) static SENSOR_DEVICE_ATTR_2_RO(temp2_input, temp, 0x02, REG_TEMP_LSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static SENSOR_DEVICE_ATTR_2_RW(temp2_min, temp, 0x33, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static SENSOR_DEVICE_ATTR_2_RW(temp2_max, temp, 0x32, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static SENSOR_DEVICE_ATTR_2_RW(temp2_crit, temp, 0x3b, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) static SENSOR_DEVICE_ATTR_RW(temp3_type, temp_type, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static SENSOR_DEVICE_ATTR_2_RO(temp3_input, temp, 0x03, REG_TEMP_LSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static SENSOR_DEVICE_ATTR_2_RW(temp3_min, temp, 0x35, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) static SENSOR_DEVICE_ATTR_2_RW(temp3_max, temp, 0x34, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static SENSOR_DEVICE_ATTR_2_RW(temp3_crit, temp, 0x3c, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) static SENSOR_DEVICE_ATTR_2_RO(temp4_input, temp, 0x04, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) static SENSOR_DEVICE_ATTR_2_RW(temp4_min, temp, 0x37, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static SENSOR_DEVICE_ATTR_2_RW(temp4_max, temp, 0x36, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) static SENSOR_DEVICE_ATTR_2_RW(temp4_crit, temp, 0x3d, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static SENSOR_DEVICE_ATTR_2_RO(temp5_input, temp, 0x06, REG_TEMP_PECI_LSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static SENSOR_DEVICE_ATTR_2_RW(temp5_min, temp, 0x39, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) static SENSOR_DEVICE_ATTR_2_RW(temp5_max, temp, 0x38, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static SENSOR_DEVICE_ATTR_2_RW(temp5_crit, temp, 0x3e, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) static SENSOR_DEVICE_ATTR_2_RO(temp6_input, temp, 0x07, REG_TEMP_PECI_LSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static SENSOR_DEVICE_ATTR_2_RO(temp1_min_alarm, alarm, 0x18, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) static SENSOR_DEVICE_ATTR_2_RO(temp2_min_alarm, alarm, 0x18, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) static SENSOR_DEVICE_ATTR_2_RO(temp3_min_alarm, alarm, 0x18, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) static SENSOR_DEVICE_ATTR_2_RO(temp4_min_alarm, alarm, 0x18, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) static SENSOR_DEVICE_ATTR_2_RO(temp5_min_alarm, alarm, 0x18, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) static SENSOR_DEVICE_ATTR_2_RO(temp1_max_alarm, alarm, 0x19, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) static SENSOR_DEVICE_ATTR_2_RO(temp2_max_alarm, alarm, 0x19, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) static SENSOR_DEVICE_ATTR_2_RO(temp3_max_alarm, alarm, 0x19, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static SENSOR_DEVICE_ATTR_2_RO(temp4_max_alarm, alarm, 0x19, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) static SENSOR_DEVICE_ATTR_2_RO(temp5_max_alarm, alarm, 0x19, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) static SENSOR_DEVICE_ATTR_2_RO(temp1_crit_alarm, alarm, 0x1b, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) static SENSOR_DEVICE_ATTR_2_RO(temp2_crit_alarm, alarm, 0x1b, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) static SENSOR_DEVICE_ATTR_2_RO(temp3_crit_alarm, alarm, 0x1b, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) static SENSOR_DEVICE_ATTR_2_RO(temp4_crit_alarm, alarm, 0x1b, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static SENSOR_DEVICE_ATTR_2_RO(temp5_crit_alarm, alarm, 0x1b, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) static SENSOR_DEVICE_ATTR_2_RO(temp1_fault, alarm, 0x17, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static SENSOR_DEVICE_ATTR_2_RO(temp2_fault, alarm, 0x17, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) static SENSOR_DEVICE_ATTR_2_RO(temp3_fault, alarm, 0x17, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) static SENSOR_DEVICE_ATTR_2_RW(temp1_beep, beep, 0x5c, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) static SENSOR_DEVICE_ATTR_2_RW(temp2_beep, beep, 0x5c, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) static SENSOR_DEVICE_ATTR_2_RW(temp3_beep, beep, 0x5c, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) static SENSOR_DEVICE_ATTR_2_RW(temp4_beep, beep, 0x5c, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) static SENSOR_DEVICE_ATTR_2_RW(temp5_beep, beep, 0x5c, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) static SENSOR_DEVICE_ATTR_2_RW(temp6_beep, beep, 0x5c, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static struct attribute *nct7802_temp_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) &sensor_dev_attr_temp1_type.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) &sensor_dev_attr_temp1_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) &sensor_dev_attr_temp1_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) &sensor_dev_attr_temp1_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) &sensor_dev_attr_temp1_crit.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) &sensor_dev_attr_temp1_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) &sensor_dev_attr_temp1_beep.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) &sensor_dev_attr_temp2_type.dev_attr.attr, /* 10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) &sensor_dev_attr_temp2_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) &sensor_dev_attr_temp2_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) &sensor_dev_attr_temp2_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) &sensor_dev_attr_temp2_crit.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) &sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) &sensor_dev_attr_temp2_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) &sensor_dev_attr_temp2_beep.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) &sensor_dev_attr_temp3_type.dev_attr.attr, /* 20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) &sensor_dev_attr_temp3_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) &sensor_dev_attr_temp3_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) &sensor_dev_attr_temp3_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) &sensor_dev_attr_temp3_crit.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) &sensor_dev_attr_temp3_min_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) &sensor_dev_attr_temp3_max_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) &sensor_dev_attr_temp3_crit_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) &sensor_dev_attr_temp3_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) &sensor_dev_attr_temp3_beep.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) &sensor_dev_attr_temp4_input.dev_attr.attr, /* 30 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) &sensor_dev_attr_temp4_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) &sensor_dev_attr_temp4_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) &sensor_dev_attr_temp4_crit.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) &sensor_dev_attr_temp4_min_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) &sensor_dev_attr_temp4_max_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) &sensor_dev_attr_temp4_crit_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) &sensor_dev_attr_temp4_beep.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) &sensor_dev_attr_temp5_input.dev_attr.attr, /* 38 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) &sensor_dev_attr_temp5_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) &sensor_dev_attr_temp5_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) &sensor_dev_attr_temp5_crit.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) &sensor_dev_attr_temp5_min_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) &sensor_dev_attr_temp5_max_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) &sensor_dev_attr_temp5_crit_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) &sensor_dev_attr_temp5_beep.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) &sensor_dev_attr_temp6_input.dev_attr.attr, /* 46 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) &sensor_dev_attr_temp6_beep.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) static umode_t nct7802_temp_is_visible(struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) struct attribute *attr, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) struct device *dev = kobj_to_dev(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) unsigned int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) err = regmap_read(data->regmap, REG_MODE, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (index < 10 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) (reg & 03) != 0x01 && (reg & 0x03) != 0x02) /* RD1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (index >= 10 && index < 20 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) (reg & 0x0c) != 0x04 && (reg & 0x0c) != 0x08) /* RD2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (index >= 20 && index < 30 && (reg & 0x30) != 0x20) /* RD3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (index >= 30 && index < 38) /* local */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) return attr->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) err = regmap_read(data->regmap, REG_PECI_ENABLE, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (index >= 38 && index < 46 && !(reg & 0x01)) /* PECI 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (index >= 0x46 && (!(reg & 0x02))) /* PECI 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) return attr->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) static const struct attribute_group nct7802_temp_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) .attrs = nct7802_temp_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) .is_visible = nct7802_temp_is_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) static SENSOR_DEVICE_ATTR_2_RO(in0_input, in, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) static SENSOR_DEVICE_ATTR_2_RW(in0_min, in, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) static SENSOR_DEVICE_ATTR_2_RW(in0_max, in, 0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) static SENSOR_DEVICE_ATTR_2_RO(in0_alarm, in_alarm, 0, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) static SENSOR_DEVICE_ATTR_2_RW(in0_beep, beep, 0x5a, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) static SENSOR_DEVICE_ATTR_2_RO(in1_input, in, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) static SENSOR_DEVICE_ATTR_2_RO(in2_input, in, 2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) static SENSOR_DEVICE_ATTR_2_RW(in2_min, in, 2, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) static SENSOR_DEVICE_ATTR_2_RW(in2_max, in, 2, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) static SENSOR_DEVICE_ATTR_2_RO(in2_alarm, in_alarm, 2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) static SENSOR_DEVICE_ATTR_2_RW(in2_beep, beep, 0x5a, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) static SENSOR_DEVICE_ATTR_2_RO(in3_input, in, 3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) static SENSOR_DEVICE_ATTR_2_RW(in3_min, in, 3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) static SENSOR_DEVICE_ATTR_2_RW(in3_max, in, 3, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) static SENSOR_DEVICE_ATTR_2_RO(in3_alarm, in_alarm, 3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) static SENSOR_DEVICE_ATTR_2_RW(in3_beep, beep, 0x5a, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) static SENSOR_DEVICE_ATTR_2_RO(in4_input, in, 4, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) static SENSOR_DEVICE_ATTR_2_RW(in4_min, in, 4, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) static SENSOR_DEVICE_ATTR_2_RW(in4_max, in, 4, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) static SENSOR_DEVICE_ATTR_2_RO(in4_alarm, in_alarm, 4, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) static SENSOR_DEVICE_ATTR_2_RW(in4_beep, beep, 0x5a, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) static struct attribute *nct7802_in_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) &sensor_dev_attr_in0_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) &sensor_dev_attr_in0_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) &sensor_dev_attr_in0_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) &sensor_dev_attr_in0_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) &sensor_dev_attr_in0_beep.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) &sensor_dev_attr_in1_input.dev_attr.attr, /* 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) &sensor_dev_attr_in2_input.dev_attr.attr, /* 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) &sensor_dev_attr_in2_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) &sensor_dev_attr_in2_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) &sensor_dev_attr_in2_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) &sensor_dev_attr_in2_beep.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) &sensor_dev_attr_in3_input.dev_attr.attr, /* 11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) &sensor_dev_attr_in3_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) &sensor_dev_attr_in3_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) &sensor_dev_attr_in3_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) &sensor_dev_attr_in3_beep.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) &sensor_dev_attr_in4_input.dev_attr.attr, /* 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) &sensor_dev_attr_in4_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) &sensor_dev_attr_in4_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) &sensor_dev_attr_in4_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) &sensor_dev_attr_in4_beep.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) static umode_t nct7802_in_is_visible(struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) struct attribute *attr, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) struct device *dev = kobj_to_dev(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) unsigned int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (index < 6) /* VCC, VCORE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return attr->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) err = regmap_read(data->regmap, REG_MODE, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (index >= 6 && index < 11 && (reg & 0x03) != 0x03) /* VSEN1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (index >= 11 && index < 16 && (reg & 0x0c) != 0x0c) /* VSEN2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) if (index >= 16 && (reg & 0x30) != 0x30) /* VSEN3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) return attr->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) static const struct attribute_group nct7802_in_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) .attrs = nct7802_in_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) .is_visible = nct7802_in_is_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) static SENSOR_DEVICE_ATTR_RO(fan1_input, fan, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) static SENSOR_DEVICE_ATTR_2_RW(fan1_min, fan_min, 0x49, 0x4c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) static SENSOR_DEVICE_ATTR_2_RO(fan1_alarm, alarm, 0x1a, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) static SENSOR_DEVICE_ATTR_2_RW(fan1_beep, beep, 0x5b, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) static SENSOR_DEVICE_ATTR_RO(fan2_input, fan, 0x11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) static SENSOR_DEVICE_ATTR_2_RW(fan2_min, fan_min, 0x4a, 0x4d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) static SENSOR_DEVICE_ATTR_2_RO(fan2_alarm, alarm, 0x1a, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) static SENSOR_DEVICE_ATTR_2_RW(fan2_beep, beep, 0x5b, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) static SENSOR_DEVICE_ATTR_RO(fan3_input, fan, 0x12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static SENSOR_DEVICE_ATTR_2_RW(fan3_min, fan_min, 0x4b, 0x4e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) static SENSOR_DEVICE_ATTR_2_RO(fan3_alarm, alarm, 0x1a, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) static SENSOR_DEVICE_ATTR_2_RW(fan3_beep, beep, 0x5b, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) /* 7.2.89 Fan Control Output Type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) static SENSOR_DEVICE_ATTR_RO(pwm1_mode, pwm_mode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) static SENSOR_DEVICE_ATTR_RO(pwm2_mode, pwm_mode, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) static SENSOR_DEVICE_ATTR_RO(pwm3_mode, pwm_mode, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) /* 7.2.91... Fan Control Output Value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) static SENSOR_DEVICE_ATTR_RW(pwm1, pwm, REG_PWM(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) static SENSOR_DEVICE_ATTR_RW(pwm2, pwm, REG_PWM(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) static SENSOR_DEVICE_ATTR_RW(pwm3, pwm, REG_PWM(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) /* 7.2.95... Temperature to Fan mapping Relationships Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) static SENSOR_DEVICE_ATTR_RW(pwm1_enable, pwm_enable, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) static SENSOR_DEVICE_ATTR_RW(pwm2_enable, pwm_enable, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) static SENSOR_DEVICE_ATTR_RW(pwm3_enable, pwm_enable, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) static struct attribute *nct7802_fan_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) &sensor_dev_attr_fan1_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) &sensor_dev_attr_fan1_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) &sensor_dev_attr_fan1_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) &sensor_dev_attr_fan1_beep.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) &sensor_dev_attr_fan2_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) &sensor_dev_attr_fan2_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) &sensor_dev_attr_fan2_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) &sensor_dev_attr_fan2_beep.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) &sensor_dev_attr_fan3_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) &sensor_dev_attr_fan3_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) &sensor_dev_attr_fan3_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) &sensor_dev_attr_fan3_beep.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) static umode_t nct7802_fan_is_visible(struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) struct attribute *attr, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) struct device *dev = kobj_to_dev(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) struct nct7802_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) int fan = index / 4; /* 4 attributes per fan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) unsigned int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) err = regmap_read(data->regmap, REG_FAN_ENABLE, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (err < 0 || !(reg & (1 << fan)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) return attr->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) static const struct attribute_group nct7802_fan_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) .attrs = nct7802_fan_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) .is_visible = nct7802_fan_is_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) static struct attribute *nct7802_pwm_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) &sensor_dev_attr_pwm1_enable.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) &sensor_dev_attr_pwm1_mode.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) &sensor_dev_attr_pwm1.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) &sensor_dev_attr_pwm2_enable.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) &sensor_dev_attr_pwm2_mode.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) &sensor_dev_attr_pwm2.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) &sensor_dev_attr_pwm3_enable.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) &sensor_dev_attr_pwm3_mode.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) &sensor_dev_attr_pwm3.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) static const struct attribute_group nct7802_pwm_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) .attrs = nct7802_pwm_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) /* 7.2.115... 0x80-0x83, 0x84 Temperature (X-axis) transition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point1_temp, temp, 0x80, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point2_temp, temp, 0x81, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point3_temp, temp, 0x82, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point4_temp, temp, 0x83, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) static SENSOR_DEVICE_ATTR_2_RW(pwm1_auto_point5_temp, temp, 0x84, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) /* 7.2.120... 0x85-0x88 PWM (Y-axis) transition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point1_pwm, pwm, 0x85);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point2_pwm, pwm, 0x86);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point3_pwm, pwm, 0x87);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point4_pwm, pwm, 0x88);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point5_pwm, pwm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) /* 7.2.124 Table 2 X-axis Transition Point 1 Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point1_temp, temp, 0x90, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point2_temp, temp, 0x91, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point3_temp, temp, 0x92, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point4_temp, temp, 0x93, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) static SENSOR_DEVICE_ATTR_2_RW(pwm2_auto_point5_temp, temp, 0x94, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) /* 7.2.129 Table 2 Y-axis Transition Point 1 Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) static SENSOR_DEVICE_ATTR_RW(pwm2_auto_point1_pwm, pwm, 0x95);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) static SENSOR_DEVICE_ATTR_RW(pwm2_auto_point2_pwm, pwm, 0x96);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) static SENSOR_DEVICE_ATTR_RW(pwm2_auto_point3_pwm, pwm, 0x97);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) static SENSOR_DEVICE_ATTR_RW(pwm2_auto_point4_pwm, pwm, 0x98);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) static SENSOR_DEVICE_ATTR_RO(pwm2_auto_point5_pwm, pwm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) /* 7.2.133 Table 3 X-axis Transition Point 1 Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point1_temp, temp, 0xA0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point2_temp, temp, 0xA1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point3_temp, temp, 0xA2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point4_temp, temp, 0xA3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) static SENSOR_DEVICE_ATTR_2_RW(pwm3_auto_point5_temp, temp, 0xA4, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) /* 7.2.138 Table 3 Y-axis Transition Point 1 Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) static SENSOR_DEVICE_ATTR_RW(pwm3_auto_point1_pwm, pwm, 0xA5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) static SENSOR_DEVICE_ATTR_RW(pwm3_auto_point2_pwm, pwm, 0xA6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) static SENSOR_DEVICE_ATTR_RW(pwm3_auto_point3_pwm, pwm, 0xA7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) static SENSOR_DEVICE_ATTR_RW(pwm3_auto_point4_pwm, pwm, 0xA8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) static SENSOR_DEVICE_ATTR_RO(pwm3_auto_point5_pwm, pwm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) static struct attribute *nct7802_auto_point_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) &sensor_dev_attr_pwm1_auto_point1_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) &sensor_dev_attr_pwm1_auto_point2_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) &sensor_dev_attr_pwm1_auto_point3_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) &sensor_dev_attr_pwm1_auto_point4_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) &sensor_dev_attr_pwm1_auto_point5_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) &sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) &sensor_dev_attr_pwm1_auto_point4_pwm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) &sensor_dev_attr_pwm1_auto_point5_pwm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) &sensor_dev_attr_pwm2_auto_point1_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) &sensor_dev_attr_pwm2_auto_point2_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) &sensor_dev_attr_pwm2_auto_point3_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) &sensor_dev_attr_pwm2_auto_point4_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) &sensor_dev_attr_pwm2_auto_point5_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) &sensor_dev_attr_pwm2_auto_point3_pwm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) &sensor_dev_attr_pwm2_auto_point4_pwm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) &sensor_dev_attr_pwm2_auto_point5_pwm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) &sensor_dev_attr_pwm3_auto_point1_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) &sensor_dev_attr_pwm3_auto_point2_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) &sensor_dev_attr_pwm3_auto_point3_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) &sensor_dev_attr_pwm3_auto_point4_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) &sensor_dev_attr_pwm3_auto_point5_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) &sensor_dev_attr_pwm3_auto_point3_pwm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) &sensor_dev_attr_pwm3_auto_point4_pwm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) &sensor_dev_attr_pwm3_auto_point5_pwm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) static const struct attribute_group nct7802_auto_point_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) .attrs = nct7802_auto_point_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) static const struct attribute_group *nct7802_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) &nct7802_temp_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) &nct7802_in_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) &nct7802_fan_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) &nct7802_pwm_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) &nct7802_auto_point_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) static int nct7802_detect(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) struct i2c_board_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) * Chip identification registers are only available in bank 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) * so only attempt chip detection if bank 0 is selected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) reg = i2c_smbus_read_byte_data(client, REG_BANK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (reg != 0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) reg = i2c_smbus_read_byte_data(client, REG_VENDOR_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (reg != 0x50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) reg = i2c_smbus_read_byte_data(client, REG_CHIP_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) if (reg != 0xc3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) reg = i2c_smbus_read_byte_data(client, REG_VERSION_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) if (reg < 0 || (reg & 0xf0) != 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) /* Also validate lower bits of voltage and temperature registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) reg = i2c_smbus_read_byte_data(client, REG_TEMP_LSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (reg < 0 || (reg & 0x1f))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) reg = i2c_smbus_read_byte_data(client, REG_TEMP_PECI_LSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) if (reg < 0 || (reg & 0x3f))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) reg = i2c_smbus_read_byte_data(client, REG_VOLTAGE_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) if (reg < 0 || (reg & 0x3f))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) strlcpy(info->type, "nct7802", I2C_NAME_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) static bool nct7802_regmap_is_volatile(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) return (reg != REG_BANK && reg <= 0x20) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) (reg >= REG_PWM(0) && reg <= REG_PWM(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) static const struct regmap_config nct7802_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) .val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) .cache_type = REGCACHE_RBTREE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) .volatile_reg = nct7802_regmap_is_volatile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) static int nct7802_init_chip(struct nct7802_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) /* Enable ADC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) err = regmap_update_bits(data->regmap, REG_START, 0x01, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) /* Enable local temperature sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) err = regmap_update_bits(data->regmap, REG_MODE, 0x40, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) /* Enable Vcore and VCC voltage monitoring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) return regmap_update_bits(data->regmap, REG_VMON_ENABLE, 0x03, 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) static int nct7802_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) struct nct7802_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) struct device *hwmon_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (data == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) data->regmap = devm_regmap_init_i2c(client, &nct7802_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) if (IS_ERR(data->regmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) return PTR_ERR(data->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) mutex_init(&data->access_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) mutex_init(&data->in_alarm_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) ret = nct7802_init_chip(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) nct7802_groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) return PTR_ERR_OR_ZERO(hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) static const unsigned short nct7802_address_list[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) static const struct i2c_device_id nct7802_idtable[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) { "nct7802", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) MODULE_DEVICE_TABLE(i2c, nct7802_idtable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) static struct i2c_driver nct7802_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) .class = I2C_CLASS_HWMON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) .name = DRVNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) .detect = nct7802_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) .probe_new = nct7802_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) .id_table = nct7802_idtable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) .address_list = nct7802_address_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) module_i2c_driver(nct7802_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) MODULE_DESCRIPTION("NCT7802Y Hardware Monitoring Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) MODULE_LICENSE("GPL v2");