^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) * asc7621.c - Part of lm_sensors, Linux kernel modules for hardware monitoring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2007, 2010 George Joseph <george.joseph@fairview5.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/jiffies.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/hwmon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/hwmon-sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* Addresses to scan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static const unsigned short normal_i2c[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) 0x2c, 0x2d, 0x2e, I2C_CLIENT_END
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) enum asc7621_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) asc7621,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) asc7621a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define INTERVAL_HIGH (HZ + HZ / 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define INTERVAL_LOW (1 * 60 * HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define PRI_NONE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define PRI_LOW 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define PRI_HIGH 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define FIRST_CHIP asc7621
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define LAST_CHIP asc7621a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct asc7621_chip {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) enum asc7621_type chip_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) u8 company_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) u8 company_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) u8 verstep_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) u8 verstep_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) const unsigned short *addresses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static struct asc7621_chip asc7621_chips[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .name = "asc7621",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .chip_type = asc7621,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .company_reg = 0x3e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .company_id = 0x61,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .verstep_reg = 0x3f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .verstep_id = 0x6c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .addresses = normal_i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .name = "asc7621a",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .chip_type = asc7621a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .company_reg = 0x3e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .company_id = 0x61,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .verstep_reg = 0x3f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .verstep_id = 0x6d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .addresses = normal_i2c,
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * Defines the highest register to be used, not the count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * The actual count will probably be smaller because of gaps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * in the implementation (unused register locations).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * This define will safely set the array size of both the parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * and data arrays.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * This comes from the data sheet register description table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define LAST_REGISTER 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct asc7621_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct i2c_client client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct device *class_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct mutex update_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) int valid; /* !=0 if following fields are valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) unsigned long last_high_reading; /* In jiffies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) unsigned long last_low_reading; /* In jiffies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * Registers we care about occupy the corresponding index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * in the array. Registers we don't care about are left
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * at 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) u8 reg[LAST_REGISTER + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * Macro to get the parent asc7621_param structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * from a sensor_device_attribute passed into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * show/store functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define to_asc7621_param(_sda) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) container_of(_sda, struct asc7621_param, sda)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * Each parameter to be retrieved needs an asc7621_param structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * allocated. It contains the sensor_device_attribute structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * and the control info needed to retrieve the value from the register map.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct asc7621_param {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct sensor_device_attribute sda;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) u8 priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) u8 msb[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) u8 lsb[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) u8 mask[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) u8 shift[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * This is the map that ultimately indicates whether we'll be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * retrieving a register value or not, and at what frequency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static u8 asc7621_register_priorities[255];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static struct asc7621_data *asc7621_update_device(struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static inline u8 read_byte(struct i2c_client *client, u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int res = i2c_smbus_read_byte_data(client, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (res < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) "Unable to read from register 0x%02x.\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return res & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static inline int write_byte(struct i2c_client *client, u8 reg, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) int res = i2c_smbus_write_byte_data(client, reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (res < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) "Unable to write value 0x%02x to register 0x%02x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) data, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * Data Handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * Each function handles the formatting, storage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * and retrieval of like parameters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define SETUP_SHOW_DATA_PARAM(d, a) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct sensor_device_attribute *sda = to_sensor_dev_attr(a); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct asc7621_data *data = asc7621_update_device(d); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct asc7621_param *param = to_asc7621_param(sda)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define SETUP_STORE_DATA_PARAM(d, a) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct sensor_device_attribute *sda = to_sensor_dev_attr(a); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct i2c_client *client = to_i2c_client(d); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct asc7621_data *data = i2c_get_clientdata(client); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct asc7621_param *param = to_asc7621_param(sda)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * u8 is just what it sounds like...an unsigned byte with no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * special formatting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static ssize_t show_u8(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) SETUP_SHOW_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return sprintf(buf, "%u\n", data->reg[param->msb[0]]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static ssize_t store_u8(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) SETUP_STORE_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) long reqval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (kstrtol(buf, 10, &reqval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) reqval = clamp_val(reqval, 0, 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) data->reg[param->msb[0]] = reqval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) write_byte(client, param->msb[0], reqval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * Many of the config values occupy only a few bits of a register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static ssize_t show_bitmask(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) SETUP_SHOW_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return sprintf(buf, "%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) (data->reg[param->msb[0]] >> param->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) shift[0]) & param->mask[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static ssize_t store_bitmask(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) SETUP_STORE_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) long reqval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) u8 currval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (kstrtol(buf, 10, &reqval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) reqval = clamp_val(reqval, 0, param->mask[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) reqval = (reqval & param->mask[0]) << param->shift[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) currval = read_byte(client, param->msb[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) reqval |= (currval & ~(param->mask[0] << param->shift[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) data->reg[param->msb[0]] = reqval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) write_byte(client, param->msb[0], reqval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * 16 bit fan rpm values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * reported by the device as the number of 11.111us periods (90khz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * between full fan rotations. Therefore...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * RPM = (90000 * 60) / register value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static ssize_t show_fan16(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) SETUP_SHOW_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) u16 regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) regval = (data->reg[param->msb[0]] << 8) | data->reg[param->lsb[0]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return sprintf(buf, "%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) (regval == 0 ? -1 : (regval) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 0xffff ? 0 : 5400000 / regval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static ssize_t store_fan16(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) SETUP_STORE_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) long reqval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (kstrtol(buf, 10, &reqval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * If a minimum RPM of zero is requested, then we set the register to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * 0xffff. This value allows the fan to be stopped completely without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * generating an alarm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) reqval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) (reqval <= 0 ? 0xffff : clamp_val(5400000 / reqval, 0, 0xfffe));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) data->reg[param->msb[0]] = (reqval >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) data->reg[param->lsb[0]] = reqval & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) write_byte(client, param->msb[0], data->reg[param->msb[0]]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) write_byte(client, param->lsb[0], data->reg[param->lsb[0]]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * Voltages are scaled in the device so that the nominal voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * is 3/4ths of the 0-255 range (i.e. 192).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * If all voltages are 'normal' then all voltage registers will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * read 0xC0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * The data sheet provides us with the 3/4 scale value for each voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * which is stored in in_scaling. The sda->index parameter value provides
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * the index into in_scaling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * NOTE: The chip expects the first 2 inputs be 2.5 and 2.25 volts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * respectively. That doesn't mean that's what the motherboard provides. :)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static const int asc7621_in_scaling[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 2500, 2250, 3300, 5000, 12000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static ssize_t show_in10(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) SETUP_SHOW_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) u16 regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) u8 nr = sda->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) regval = (data->reg[param->msb[0]] << 8) | (data->reg[param->lsb[0]]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /* The LSB value is a 2-bit scaling of the MSB's LSbit value. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) regval = (regval >> 6) * asc7621_in_scaling[nr] / (0xc0 << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return sprintf(buf, "%u\n", regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* 8 bit voltage values (the mins and maxs) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static ssize_t show_in8(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) SETUP_SHOW_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) u8 nr = sda->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return sprintf(buf, "%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) ((data->reg[param->msb[0]] *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) asc7621_in_scaling[nr]) / 0xc0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static ssize_t store_in8(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) SETUP_STORE_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) long reqval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) u8 nr = sda->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (kstrtol(buf, 10, &reqval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) reqval = clamp_val(reqval, 0, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) reqval = reqval * 0xc0 / asc7621_in_scaling[nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) reqval = clamp_val(reqval, 0, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) data->reg[param->msb[0]] = reqval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) write_byte(client, param->msb[0], reqval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static ssize_t show_temp8(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) SETUP_SHOW_DATA_PARAM(dev, attr);
^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", ((s8) data->reg[param->msb[0]]) * 1000);
^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 store_temp8(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) SETUP_STORE_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) long reqval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) s8 temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (kstrtol(buf, 10, &reqval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) reqval = clamp_val(reqval, -127000, 127000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) temp = reqval / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) data->reg[param->msb[0]] = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) write_byte(client, param->msb[0], temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * Temperatures that occupy 2 bytes always have the whole
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * number of degrees in the MSB with some part of the LSB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * indicating fractional degrees.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* mmmmmmmm.llxxxxxx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static ssize_t show_temp10(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) SETUP_SHOW_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) u8 msb, lsb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) int temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) msb = data->reg[param->msb[0]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) lsb = (data->reg[param->lsb[0]] >> 6) & 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) temp = (((s8) msb) * 1000) + (lsb * 250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return sprintf(buf, "%d\n", temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* mmmmmm.ll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) static ssize_t show_temp62(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) SETUP_SHOW_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) u8 regval = data->reg[param->msb[0]];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) int temp = ((s8) (regval & 0xfc) * 1000) + ((regval & 0x03) * 250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return sprintf(buf, "%d\n", temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) static ssize_t store_temp62(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) SETUP_STORE_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) long reqval, i, f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) s8 temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (kstrtol(buf, 10, &reqval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) reqval = clamp_val(reqval, -32000, 31750);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) i = reqval / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) f = reqval - (i * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) temp = i << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) temp |= f / 250;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) data->reg[param->msb[0]] = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) write_byte(client, param->msb[0], temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * The aSC7621 doesn't provide an "auto_point2". Instead, you
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * specify the auto_point1 and a range. To keep with the sysfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * hwmon specs, we synthesize the auto_point_2 from them.
^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 u32 asc7621_range_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 2000, 2500, 3330, 4000, 5000, 6670, 8000, 10000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 13330, 16000, 20000, 26670, 32000, 40000, 53330, 80000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static ssize_t show_ap2_temp(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) SETUP_SHOW_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) long auto_point1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) u8 regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) int temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) auto_point1 = ((s8) data->reg[param->msb[1]]) * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) regval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) ((data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) temp = auto_point1 + asc7621_range_map[clamp_val(regval, 0, 15)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return sprintf(buf, "%d\n", temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static ssize_t store_ap2_temp(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) SETUP_STORE_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) long reqval, auto_point1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) u8 currval, newval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (kstrtol(buf, 10, &reqval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) auto_point1 = data->reg[param->msb[1]] * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) reqval = clamp_val(reqval, auto_point1 + 2000, auto_point1 + 80000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) for (i = ARRAY_SIZE(asc7621_range_map) - 1; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (reqval >= auto_point1 + asc7621_range_map[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) newval = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) newval = (newval & param->mask[0]) << param->shift[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) currval = read_byte(client, param->msb[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) newval |= (currval & ~(param->mask[0] << param->shift[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) data->reg[param->msb[0]] = newval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) write_byte(client, param->msb[0], newval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) static ssize_t show_pwm_ac(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) SETUP_SHOW_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) u8 config, altbit, regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) static const u8 map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 0x01, 0x02, 0x04, 0x1f, 0x00, 0x06, 0x07, 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 0x08, 0x0f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) config = (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) altbit = (data->reg[param->msb[1]] >> param->shift[1]) & param->mask[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) regval = config | (altbit << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) return sprintf(buf, "%u\n", map[clamp_val(regval, 0, 15)]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) static ssize_t store_pwm_ac(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) SETUP_STORE_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) unsigned long reqval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) u8 currval, config, altbit, newval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) static const u16 map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 0x04, 0x00, 0x01, 0xff, 0x02, 0xff, 0x05, 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (kstrtoul(buf, 10, &reqval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (reqval > 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) reqval = map[reqval];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (reqval == 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) config = reqval & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) altbit = (reqval >> 3) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) config = (config & param->mask[0]) << param->shift[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) altbit = (altbit & param->mask[1]) << param->shift[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) currval = read_byte(client, param->msb[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) newval = config | (currval & ~(param->mask[0] << param->shift[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) newval = altbit | (newval & ~(param->mask[1] << param->shift[1]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) data->reg[param->msb[0]] = newval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) write_byte(client, param->msb[0], newval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static ssize_t show_pwm_enable(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) SETUP_SHOW_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) u8 config, altbit, minoff, val, newval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) config = (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) altbit = (data->reg[param->msb[1]] >> param->shift[1]) & param->mask[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) minoff = (data->reg[param->msb[2]] >> param->shift[2]) & param->mask[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) val = config | (altbit << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (val == 3 || val >= 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) newval = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) else if (val == 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) newval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) else if (val == 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) newval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) else if (minoff == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) newval = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) newval = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return sprintf(buf, "%u\n", newval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) static ssize_t store_pwm_enable(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) SETUP_STORE_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) long reqval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) u8 currval, config, altbit, newval, minoff = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (kstrtol(buf, 10, &reqval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) switch (reqval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) newval = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) newval = 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) newval = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) minoff = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) newval = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) minoff = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) case 255:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) newval = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) config = newval & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) altbit = (newval >> 3) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) config = (config & param->mask[0]) << param->shift[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) altbit = (altbit & param->mask[1]) << param->shift[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) currval = read_byte(client, param->msb[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) newval = config | (currval & ~(param->mask[0] << param->shift[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) newval = altbit | (newval & ~(param->mask[1] << param->shift[1]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) data->reg[param->msb[0]] = newval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) write_byte(client, param->msb[0], newval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (minoff < 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) minoff = (minoff & param->mask[2]) << param->shift[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) currval = read_byte(client, param->msb[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) newval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) minoff | (currval & ~(param->mask[2] << param->shift[2]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) data->reg[param->msb[2]] = newval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) write_byte(client, param->msb[2], newval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) static const u32 asc7621_pwm_freq_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 10, 15, 23, 30, 38, 47, 62, 94,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 23000, 24000, 25000, 26000, 27000, 28000, 29000, 30000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) static ssize_t show_pwm_freq(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) SETUP_SHOW_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) u8 regval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) regval = clamp_val(regval, 0, 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) return sprintf(buf, "%u\n", asc7621_pwm_freq_map[regval]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static ssize_t store_pwm_freq(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) SETUP_STORE_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) unsigned long reqval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) u8 currval, newval = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (kstrtoul(buf, 10, &reqval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) for (i = 0; i < ARRAY_SIZE(asc7621_pwm_freq_map); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (reqval == asc7621_pwm_freq_map[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) newval = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (newval == 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) newval = (newval & param->mask[0]) << param->shift[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) currval = read_byte(client, param->msb[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) newval |= (currval & ~(param->mask[0] << param->shift[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) data->reg[param->msb[0]] = newval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) write_byte(client, param->msb[0], newval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) static const u32 asc7621_pwm_auto_spinup_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 0, 100, 250, 400, 700, 1000, 2000, 4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) static ssize_t show_pwm_ast(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) SETUP_SHOW_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) u8 regval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) regval = clamp_val(regval, 0, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) return sprintf(buf, "%u\n", asc7621_pwm_auto_spinup_map[regval]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) static ssize_t store_pwm_ast(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) SETUP_STORE_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) long reqval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) u8 currval, newval = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (kstrtol(buf, 10, &reqval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) for (i = 0; i < ARRAY_SIZE(asc7621_pwm_auto_spinup_map); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (reqval == asc7621_pwm_auto_spinup_map[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) newval = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (newval == 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) newval = (newval & param->mask[0]) << param->shift[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) currval = read_byte(client, param->msb[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) newval |= (currval & ~(param->mask[0] << param->shift[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) data->reg[param->msb[0]] = newval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) write_byte(client, param->msb[0], newval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) static const u32 asc7621_temp_smoothing_time_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 35000, 17600, 11800, 7000, 4400, 3000, 1600, 800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) static ssize_t show_temp_st(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) SETUP_SHOW_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) u8 regval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) regval = clamp_val(regval, 0, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) return sprintf(buf, "%u\n", asc7621_temp_smoothing_time_map[regval]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) static ssize_t store_temp_st(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) SETUP_STORE_DATA_PARAM(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) long reqval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) u8 currval, newval = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (kstrtol(buf, 10, &reqval))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) for (i = 0; i < ARRAY_SIZE(asc7621_temp_smoothing_time_map); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (reqval == asc7621_temp_smoothing_time_map[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) newval = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (newval == 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) newval = (newval & param->mask[0]) << param->shift[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) currval = read_byte(client, param->msb[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) newval |= (currval & ~(param->mask[0] << param->shift[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) data->reg[param->msb[0]] = newval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) write_byte(client, param->msb[0], newval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) * End of data handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) * These defines do nothing more than make the table easier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) * to read when wrapped at column 80.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) * Creates a variable length array inititalizer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) * VAA(1,3,5,7) would produce {1,3,5,7}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) #define VAA(args...) {args}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) #define PREAD(name, n, pri, rm, rl, m, s, r) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) {.sda = SENSOR_ATTR(name, S_IRUGO, show_##r, NULL, n), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) .priority = pri, .msb[0] = rm, .lsb[0] = rl, .mask[0] = m, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) .shift[0] = s,}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) #define PWRITE(name, n, pri, rm, rl, m, s, r) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) {.sda = SENSOR_ATTR(name, S_IRUGO | S_IWUSR, show_##r, store_##r, n), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) .priority = pri, .msb[0] = rm, .lsb[0] = rl, .mask[0] = m, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) .shift[0] = s,}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * PWRITEM assumes that the initializers for the .msb, .lsb, .mask and .shift
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) * were created using the VAA macro.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) #define PWRITEM(name, n, pri, rm, rl, m, s, r) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) {.sda = SENSOR_ATTR(name, S_IRUGO | S_IWUSR, show_##r, store_##r, n), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) .priority = pri, .msb = rm, .lsb = rl, .mask = m, .shift = s,}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static struct asc7621_param asc7621_params[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) PREAD(in0_input, 0, PRI_HIGH, 0x20, 0x13, 0, 0, in10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) PREAD(in1_input, 1, PRI_HIGH, 0x21, 0x18, 0, 0, in10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) PREAD(in2_input, 2, PRI_HIGH, 0x22, 0x11, 0, 0, in10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) PREAD(in3_input, 3, PRI_HIGH, 0x23, 0x12, 0, 0, in10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) PREAD(in4_input, 4, PRI_HIGH, 0x24, 0x14, 0, 0, in10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) PWRITE(in0_min, 0, PRI_LOW, 0x44, 0, 0, 0, in8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) PWRITE(in1_min, 1, PRI_LOW, 0x46, 0, 0, 0, in8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) PWRITE(in2_min, 2, PRI_LOW, 0x48, 0, 0, 0, in8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) PWRITE(in3_min, 3, PRI_LOW, 0x4a, 0, 0, 0, in8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) PWRITE(in4_min, 4, PRI_LOW, 0x4c, 0, 0, 0, in8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) PWRITE(in0_max, 0, PRI_LOW, 0x45, 0, 0, 0, in8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) PWRITE(in1_max, 1, PRI_LOW, 0x47, 0, 0, 0, in8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) PWRITE(in2_max, 2, PRI_LOW, 0x49, 0, 0, 0, in8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) PWRITE(in3_max, 3, PRI_LOW, 0x4b, 0, 0, 0, in8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) PWRITE(in4_max, 4, PRI_LOW, 0x4d, 0, 0, 0, in8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) PREAD(in0_alarm, 0, PRI_HIGH, 0x41, 0, 0x01, 0, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) PREAD(in1_alarm, 1, PRI_HIGH, 0x41, 0, 0x01, 1, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) PREAD(in2_alarm, 2, PRI_HIGH, 0x41, 0, 0x01, 2, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) PREAD(in3_alarm, 3, PRI_HIGH, 0x41, 0, 0x01, 3, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) PREAD(in4_alarm, 4, PRI_HIGH, 0x42, 0, 0x01, 0, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) PREAD(fan1_input, 0, PRI_HIGH, 0x29, 0x28, 0, 0, fan16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) PREAD(fan2_input, 1, PRI_HIGH, 0x2b, 0x2a, 0, 0, fan16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) PREAD(fan3_input, 2, PRI_HIGH, 0x2d, 0x2c, 0, 0, fan16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) PREAD(fan4_input, 3, PRI_HIGH, 0x2f, 0x2e, 0, 0, fan16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) PWRITE(fan1_min, 0, PRI_LOW, 0x55, 0x54, 0, 0, fan16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) PWRITE(fan2_min, 1, PRI_LOW, 0x57, 0x56, 0, 0, fan16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) PWRITE(fan3_min, 2, PRI_LOW, 0x59, 0x58, 0, 0, fan16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) PWRITE(fan4_min, 3, PRI_LOW, 0x5b, 0x5a, 0, 0, fan16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) PREAD(fan1_alarm, 0, PRI_HIGH, 0x42, 0, 0x01, 2, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) PREAD(fan2_alarm, 1, PRI_HIGH, 0x42, 0, 0x01, 3, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) PREAD(fan3_alarm, 2, PRI_HIGH, 0x42, 0, 0x01, 4, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) PREAD(fan4_alarm, 3, PRI_HIGH, 0x42, 0, 0x01, 5, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) PREAD(temp1_input, 0, PRI_HIGH, 0x25, 0x10, 0, 0, temp10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) PREAD(temp2_input, 1, PRI_HIGH, 0x26, 0x15, 0, 0, temp10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) PREAD(temp3_input, 2, PRI_HIGH, 0x27, 0x16, 0, 0, temp10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) PREAD(temp4_input, 3, PRI_HIGH, 0x33, 0x17, 0, 0, temp10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) PREAD(temp5_input, 4, PRI_HIGH, 0xf7, 0xf6, 0, 0, temp10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) PREAD(temp6_input, 5, PRI_HIGH, 0xf9, 0xf8, 0, 0, temp10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) PREAD(temp7_input, 6, PRI_HIGH, 0xfb, 0xfa, 0, 0, temp10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) PREAD(temp8_input, 7, PRI_HIGH, 0xfd, 0xfc, 0, 0, temp10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) PWRITE(temp1_min, 0, PRI_LOW, 0x4e, 0, 0, 0, temp8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) PWRITE(temp2_min, 1, PRI_LOW, 0x50, 0, 0, 0, temp8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) PWRITE(temp3_min, 2, PRI_LOW, 0x52, 0, 0, 0, temp8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) PWRITE(temp4_min, 3, PRI_LOW, 0x34, 0, 0, 0, temp8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) PWRITE(temp1_max, 0, PRI_LOW, 0x4f, 0, 0, 0, temp8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) PWRITE(temp2_max, 1, PRI_LOW, 0x51, 0, 0, 0, temp8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) PWRITE(temp3_max, 2, PRI_LOW, 0x53, 0, 0, 0, temp8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) PWRITE(temp4_max, 3, PRI_LOW, 0x35, 0, 0, 0, temp8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) PREAD(temp1_alarm, 0, PRI_HIGH, 0x41, 0, 0x01, 4, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) PREAD(temp2_alarm, 1, PRI_HIGH, 0x41, 0, 0x01, 5, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) PREAD(temp3_alarm, 2, PRI_HIGH, 0x41, 0, 0x01, 6, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) PREAD(temp4_alarm, 3, PRI_HIGH, 0x43, 0, 0x01, 0, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) PWRITE(temp1_source, 0, PRI_LOW, 0x02, 0, 0x07, 4, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) PWRITE(temp2_source, 1, PRI_LOW, 0x02, 0, 0x07, 0, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) PWRITE(temp3_source, 2, PRI_LOW, 0x03, 0, 0x07, 4, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) PWRITE(temp4_source, 3, PRI_LOW, 0x03, 0, 0x07, 0, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) PWRITE(temp1_smoothing_enable, 0, PRI_LOW, 0x62, 0, 0x01, 3, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) PWRITE(temp2_smoothing_enable, 1, PRI_LOW, 0x63, 0, 0x01, 7, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) PWRITE(temp3_smoothing_enable, 2, PRI_LOW, 0x63, 0, 0x01, 3, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) PWRITE(temp4_smoothing_enable, 3, PRI_LOW, 0x3c, 0, 0x01, 3, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) PWRITE(temp1_smoothing_time, 0, PRI_LOW, 0x62, 0, 0x07, 0, temp_st),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) PWRITE(temp2_smoothing_time, 1, PRI_LOW, 0x63, 0, 0x07, 4, temp_st),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) PWRITE(temp3_smoothing_time, 2, PRI_LOW, 0x63, 0, 0x07, 0, temp_st),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) PWRITE(temp4_smoothing_time, 3, PRI_LOW, 0x3c, 0, 0x07, 0, temp_st),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) PWRITE(temp1_auto_point1_temp_hyst, 0, PRI_LOW, 0x6d, 0, 0x0f, 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) PWRITE(temp2_auto_point1_temp_hyst, 1, PRI_LOW, 0x6d, 0, 0x0f, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) PWRITE(temp3_auto_point1_temp_hyst, 2, PRI_LOW, 0x6e, 0, 0x0f, 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) PWRITE(temp4_auto_point1_temp_hyst, 3, PRI_LOW, 0x6e, 0, 0x0f, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) PREAD(temp1_auto_point2_temp_hyst, 0, PRI_LOW, 0x6d, 0, 0x0f, 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) PREAD(temp2_auto_point2_temp_hyst, 1, PRI_LOW, 0x6d, 0, 0x0f, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) PREAD(temp3_auto_point2_temp_hyst, 2, PRI_LOW, 0x6e, 0, 0x0f, 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) PREAD(temp4_auto_point2_temp_hyst, 3, PRI_LOW, 0x6e, 0, 0x0f, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) PWRITE(temp1_auto_point1_temp, 0, PRI_LOW, 0x67, 0, 0, 0, temp8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) PWRITE(temp2_auto_point1_temp, 1, PRI_LOW, 0x68, 0, 0, 0, temp8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) PWRITE(temp3_auto_point1_temp, 2, PRI_LOW, 0x69, 0, 0, 0, temp8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) PWRITE(temp4_auto_point1_temp, 3, PRI_LOW, 0x3b, 0, 0, 0, temp8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) PWRITEM(temp1_auto_point2_temp, 0, PRI_LOW, VAA(0x5f, 0x67), VAA(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) VAA(0x0f), VAA(4), ap2_temp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) PWRITEM(temp2_auto_point2_temp, 1, PRI_LOW, VAA(0x60, 0x68), VAA(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) VAA(0x0f), VAA(4), ap2_temp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) PWRITEM(temp3_auto_point2_temp, 2, PRI_LOW, VAA(0x61, 0x69), VAA(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) VAA(0x0f), VAA(4), ap2_temp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) PWRITEM(temp4_auto_point2_temp, 3, PRI_LOW, VAA(0x3c, 0x3b), VAA(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) VAA(0x0f), VAA(4), ap2_temp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) PWRITE(temp1_crit, 0, PRI_LOW, 0x6a, 0, 0, 0, temp8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) PWRITE(temp2_crit, 1, PRI_LOW, 0x6b, 0, 0, 0, temp8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) PWRITE(temp3_crit, 2, PRI_LOW, 0x6c, 0, 0, 0, temp8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) PWRITE(temp4_crit, 3, PRI_LOW, 0x3d, 0, 0, 0, temp8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) PWRITE(temp5_enable, 4, PRI_LOW, 0x0e, 0, 0x01, 0, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) PWRITE(temp6_enable, 5, PRI_LOW, 0x0e, 0, 0x01, 1, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) PWRITE(temp7_enable, 6, PRI_LOW, 0x0e, 0, 0x01, 2, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) PWRITE(temp8_enable, 7, PRI_LOW, 0x0e, 0, 0x01, 3, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) PWRITE(remote1_offset, 0, PRI_LOW, 0x1c, 0, 0, 0, temp62),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) PWRITE(remote2_offset, 1, PRI_LOW, 0x1d, 0, 0, 0, temp62),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) PWRITE(pwm1, 0, PRI_HIGH, 0x30, 0, 0, 0, u8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) PWRITE(pwm2, 1, PRI_HIGH, 0x31, 0, 0, 0, u8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) PWRITE(pwm3, 2, PRI_HIGH, 0x32, 0, 0, 0, u8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) PWRITE(pwm1_invert, 0, PRI_LOW, 0x5c, 0, 0x01, 4, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) PWRITE(pwm2_invert, 1, PRI_LOW, 0x5d, 0, 0x01, 4, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) PWRITE(pwm3_invert, 2, PRI_LOW, 0x5e, 0, 0x01, 4, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) PWRITEM(pwm1_enable, 0, PRI_LOW, VAA(0x5c, 0x5c, 0x62), VAA(0, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) VAA(0x07, 0x01, 0x01), VAA(5, 3, 5), pwm_enable),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) PWRITEM(pwm2_enable, 1, PRI_LOW, VAA(0x5d, 0x5d, 0x62), VAA(0, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) VAA(0x07, 0x01, 0x01), VAA(5, 3, 6), pwm_enable),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) PWRITEM(pwm3_enable, 2, PRI_LOW, VAA(0x5e, 0x5e, 0x62), VAA(0, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) VAA(0x07, 0x01, 0x01), VAA(5, 3, 7), pwm_enable),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) PWRITEM(pwm1_auto_channels, 0, PRI_LOW, VAA(0x5c, 0x5c), VAA(0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) VAA(0x07, 0x01), VAA(5, 3), pwm_ac),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) PWRITEM(pwm2_auto_channels, 1, PRI_LOW, VAA(0x5d, 0x5d), VAA(0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) VAA(0x07, 0x01), VAA(5, 3), pwm_ac),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) PWRITEM(pwm3_auto_channels, 2, PRI_LOW, VAA(0x5e, 0x5e), VAA(0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) VAA(0x07, 0x01), VAA(5, 3), pwm_ac),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) PWRITE(pwm1_auto_point1_pwm, 0, PRI_LOW, 0x64, 0, 0, 0, u8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) PWRITE(pwm2_auto_point1_pwm, 1, PRI_LOW, 0x65, 0, 0, 0, u8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) PWRITE(pwm3_auto_point1_pwm, 2, PRI_LOW, 0x66, 0, 0, 0, u8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) PWRITE(pwm1_auto_point2_pwm, 0, PRI_LOW, 0x38, 0, 0, 0, u8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) PWRITE(pwm2_auto_point2_pwm, 1, PRI_LOW, 0x39, 0, 0, 0, u8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) PWRITE(pwm3_auto_point2_pwm, 2, PRI_LOW, 0x3a, 0, 0, 0, u8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) PWRITE(pwm1_freq, 0, PRI_LOW, 0x5f, 0, 0x0f, 0, pwm_freq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) PWRITE(pwm2_freq, 1, PRI_LOW, 0x60, 0, 0x0f, 0, pwm_freq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) PWRITE(pwm3_freq, 2, PRI_LOW, 0x61, 0, 0x0f, 0, pwm_freq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) PREAD(pwm1_auto_zone_assigned, 0, PRI_LOW, 0, 0, 0x03, 2, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) PREAD(pwm2_auto_zone_assigned, 1, PRI_LOW, 0, 0, 0x03, 4, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) PREAD(pwm3_auto_zone_assigned, 2, PRI_LOW, 0, 0, 0x03, 6, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) PWRITE(pwm1_auto_spinup_time, 0, PRI_LOW, 0x5c, 0, 0x07, 0, pwm_ast),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) PWRITE(pwm2_auto_spinup_time, 1, PRI_LOW, 0x5d, 0, 0x07, 0, pwm_ast),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) PWRITE(pwm3_auto_spinup_time, 2, PRI_LOW, 0x5e, 0, 0x07, 0, pwm_ast),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) PWRITE(peci_enable, 0, PRI_LOW, 0x40, 0, 0x01, 4, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) PWRITE(peci_avg, 0, PRI_LOW, 0x36, 0, 0x07, 0, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) PWRITE(peci_domain, 0, PRI_LOW, 0x36, 0, 0x01, 3, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) PWRITE(peci_legacy, 0, PRI_LOW, 0x36, 0, 0x01, 4, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) PWRITE(peci_diode, 0, PRI_LOW, 0x0e, 0, 0x07, 4, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) PWRITE(peci_4domain, 0, PRI_LOW, 0x0e, 0, 0x01, 4, bitmask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^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) static struct asc7621_data *asc7621_update_device(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) struct asc7621_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) * The asc7621 chips guarantee consistent reads of multi-byte values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) * regardless of the order of the reads. No special logic is needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) * so we can just read the registers in whatever order they appear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) * in the asc7621_params array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) /* Read all the high priority registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (!data->valid ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) time_after(jiffies, data->last_high_reading + INTERVAL_HIGH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) for (i = 0; i < ARRAY_SIZE(asc7621_register_priorities); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (asc7621_register_priorities[i] == PRI_HIGH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) data->reg[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) i2c_smbus_read_byte_data(client, i) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) data->last_high_reading = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) } /* last_reading */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) /* Read all the low priority registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) if (!data->valid ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) time_after(jiffies, data->last_low_reading + INTERVAL_LOW)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) if (asc7621_register_priorities[i] == PRI_LOW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) data->reg[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) i2c_smbus_read_byte_data(client, i) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) data->last_low_reading = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) } /* last_reading */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) data->valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) * Standard detection and initialization below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) * Helper function that checks if an address is valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) * for a particular chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) static inline int valid_address_for_chip(int chip_type, int address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) for (i = 0; asc7621_chips[chip_type].addresses[i] != I2C_CLIENT_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (asc7621_chips[chip_type].addresses[i] == address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) static void asc7621_init_client(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) /* Warn if part was not "READY" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) value = read_byte(client, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (value & 0x02) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) "Client (%d,0x%02x) config is locked.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) i2c_adapter_id(client->adapter), client->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) if (!(value & 0x04)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) dev_err(&client->dev, "Client (%d,0x%02x) is not ready.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) i2c_adapter_id(client->adapter), client->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) * Start monitoring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) * Try to clear LOCK, Set START, save everything else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) value = (value & ~0x02) | 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) write_byte(client, 0x40, value & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) asc7621_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) struct asc7621_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) data = devm_kzalloc(&client->dev, sizeof(struct asc7621_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) if (data == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) i2c_set_clientdata(client, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) mutex_init(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) /* Initialize the asc7621 chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) asc7621_init_client(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) /* Create the sysfs entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) err =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) device_create_file(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) &(asc7621_params[i].sda.dev_attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) goto exit_remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) data->class_dev = hwmon_device_register(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (IS_ERR(data->class_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) err = PTR_ERR(data->class_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) goto exit_remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) exit_remove:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) device_remove_file(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) &(asc7621_params[i].sda.dev_attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) static int asc7621_detect(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) struct i2c_board_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) struct i2c_adapter *adapter = client->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) int company, verstep, chip_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) for (chip_index = FIRST_CHIP; chip_index <= LAST_CHIP; chip_index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) if (!valid_address_for_chip(chip_index, client->addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) company = read_byte(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) asc7621_chips[chip_index].company_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) verstep = read_byte(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) asc7621_chips[chip_index].verstep_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) if (company == asc7621_chips[chip_index].company_id &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) verstep == asc7621_chips[chip_index].verstep_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) strlcpy(info->type, asc7621_chips[chip_index].name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) I2C_NAME_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) dev_info(&adapter->dev, "Matched %s at 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) asc7621_chips[chip_index].name, client->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) static int asc7621_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) struct asc7621_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) hwmon_device_unregister(data->class_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) device_remove_file(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) &(asc7621_params[i].sda.dev_attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) static const struct i2c_device_id asc7621_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) {"asc7621", asc7621},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) {"asc7621a", asc7621a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) MODULE_DEVICE_TABLE(i2c, asc7621_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) static struct i2c_driver asc7621_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) .class = I2C_CLASS_HWMON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) .name = "asc7621",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) .probe_new = asc7621_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) .remove = asc7621_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) .id_table = asc7621_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) .detect = asc7621_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) .address_list = normal_i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) static int __init sm_asc7621_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) * Collect all the registers needed into a single array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) * This way, if a register isn't actually used for anything,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) * we don't retrieve it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) for (j = 0; j < ARRAY_SIZE(asc7621_params[i].msb); j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) asc7621_register_priorities[asc7621_params[i].msb[j]] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) asc7621_params[i].priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) for (j = 0; j < ARRAY_SIZE(asc7621_params[i].lsb); j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) asc7621_register_priorities[asc7621_params[i].lsb[j]] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) asc7621_params[i].priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) return i2c_add_driver(&asc7621_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) static void __exit sm_asc7621_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) i2c_del_driver(&asc7621_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) MODULE_AUTHOR("George Joseph");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) MODULE_DESCRIPTION("Andigilog aSC7621 and aSC7621a driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) module_init(sm_asc7621_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) module_exit(sm_asc7621_exit);