^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) * Support for the FTS Systemmonitoring Chip "Teutates"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2016 Fujitsu Technology Solutions GmbH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Thilo Cestonaro <thilo.cestonaro@ts.fujitsu.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/hwmon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/hwmon-sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/watchdog.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define FTS_DEVICE_ID_REG 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define FTS_DEVICE_REVISION_REG 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define FTS_DEVICE_STATUS_REG 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define FTS_SATELLITE_STATUS_REG 0x0005
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define FTS_EVENT_STATUS_REG 0x0006
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define FTS_GLOBAL_CONTROL_REG 0x0007
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define FTS_DEVICE_DETECT_REG_1 0x0C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define FTS_DEVICE_DETECT_REG_2 0x0D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define FTS_DEVICE_DETECT_REG_3 0x0E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define FTS_SENSOR_EVENT_REG 0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define FTS_FAN_EVENT_REG 0x0014
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define FTS_FAN_PRESENT_REG 0x0015
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define FTS_POWER_ON_TIME_COUNTER_A 0x007A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define FTS_POWER_ON_TIME_COUNTER_B 0x007B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define FTS_POWER_ON_TIME_COUNTER_C 0x007C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define FTS_PAGE_SELECT_REG 0x007F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define FTS_WATCHDOG_TIME_PRESET 0x000B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define FTS_WATCHDOG_CONTROL 0x5081
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define FTS_NO_FAN_SENSORS 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define FTS_NO_TEMP_SENSORS 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define FTS_NO_VOLT_SENSORS 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static const struct i2c_device_id fts_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) { "ftsteutates", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) MODULE_DEVICE_TABLE(i2c, fts_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) enum WATCHDOG_RESOLUTION {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) seconds = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) minutes = 60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct fts_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* update sensor data lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct mutex update_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* read/write register lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct mutex access_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) unsigned long last_updated; /* in jiffies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct watchdog_device wdd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) enum WATCHDOG_RESOLUTION resolution;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) bool valid; /* false until following fields are valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) u8 volt[FTS_NO_VOLT_SENSORS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) u8 temp_input[FTS_NO_TEMP_SENSORS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) u8 temp_alarm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) u8 fan_present;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) u8 fan_input[FTS_NO_FAN_SENSORS]; /* in rps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) u8 fan_source[FTS_NO_FAN_SENSORS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) u8 fan_alarm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define FTS_REG_FAN_INPUT(idx) ((idx) + 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define FTS_REG_FAN_SOURCE(idx) ((idx) + 0x30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define FTS_REG_FAN_CONTROL(idx) (((idx) << 16) + 0x4881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define FTS_REG_TEMP_INPUT(idx) ((idx) + 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define FTS_REG_TEMP_CONTROL(idx) (((idx) << 16) + 0x0681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define FTS_REG_VOLT(idx) ((idx) + 0x18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* I2C Helper functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static int fts_read_byte(struct i2c_client *client, unsigned short reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) unsigned char page = reg >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct fts_data *data = dev_get_drvdata(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) mutex_lock(&data->access_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) dev_dbg(&client->dev, "page select - page: 0x%.02x\n", page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) ret = i2c_smbus_write_byte_data(client, FTS_PAGE_SELECT_REG, page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) reg &= 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ret = i2c_smbus_read_byte_data(client, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) dev_dbg(&client->dev, "read - reg: 0x%.02x: val: 0x%.02x\n", reg, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) mutex_unlock(&data->access_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static int fts_write_byte(struct i2c_client *client, unsigned short reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned char value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) unsigned char page = reg >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct fts_data *data = dev_get_drvdata(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) mutex_lock(&data->access_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) dev_dbg(&client->dev, "page select - page: 0x%.02x\n", page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) ret = i2c_smbus_write_byte_data(client, FTS_PAGE_SELECT_REG, page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) reg &= 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) "write - reg: 0x%.02x: val: 0x%.02x\n", reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ret = i2c_smbus_write_byte_data(client, reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) mutex_unlock(&data->access_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return ret;
^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) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* Data Updater Helper function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static int fts_update_device(struct fts_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (!time_after(jiffies, data->last_updated + 2 * HZ) && data->valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) err = fts_read_byte(data->client, FTS_DEVICE_STATUS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) data->valid = !!(err & 0x02); /* Data not ready yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (unlikely(!data->valid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) err = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) err = fts_read_byte(data->client, FTS_FAN_PRESENT_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) data->fan_present = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) err = fts_read_byte(data->client, FTS_FAN_EVENT_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) data->fan_alarm = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) for (i = 0; i < FTS_NO_FAN_SENSORS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (data->fan_present & BIT(i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) err = fts_read_byte(data->client, FTS_REG_FAN_INPUT(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) data->fan_input[i] = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) err = fts_read_byte(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) FTS_REG_FAN_SOURCE(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) data->fan_source[i] = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) data->fan_input[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) data->fan_source[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) err = fts_read_byte(data->client, FTS_SENSOR_EVENT_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) data->temp_alarm = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) for (i = 0; i < FTS_NO_TEMP_SENSORS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) err = fts_read_byte(data->client, FTS_REG_TEMP_INPUT(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) data->temp_input[i] = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) for (i = 0; i < FTS_NO_VOLT_SENSORS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) err = fts_read_byte(data->client, FTS_REG_VOLT(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) data->volt[i] = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) data->last_updated = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /* Watchdog functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static int fts_wd_set_resolution(struct fts_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) enum WATCHDOG_RESOLUTION resolution)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (data->resolution == resolution)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) ret = fts_read_byte(data->client, FTS_WATCHDOG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if ((resolution == seconds && ret & BIT(1)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) (resolution == minutes && (ret & BIT(1)) == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) data->resolution = resolution;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (resolution == seconds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) ret |= BIT(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) ret &= ~BIT(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ret = fts_write_byte(data->client, FTS_WATCHDOG_CONTROL, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) data->resolution = resolution;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static int fts_wd_set_timeout(struct watchdog_device *wdd, unsigned int timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct fts_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) enum WATCHDOG_RESOLUTION resolution = seconds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) data = watchdog_get_drvdata(wdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* switch watchdog resolution to minutes if timeout does not fit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * into a byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (timeout > 0xFF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) timeout = DIV_ROUND_UP(timeout, 60) * 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) resolution = minutes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) ret = fts_wd_set_resolution(data, resolution);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) wdd->timeout = timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return 0;
^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) static int fts_wd_start(struct watchdog_device *wdd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct fts_data *data = watchdog_get_drvdata(wdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return fts_write_byte(data->client, FTS_WATCHDOG_TIME_PRESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) wdd->timeout / (u8)data->resolution);
^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 int fts_wd_stop(struct watchdog_device *wdd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct fts_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) data = watchdog_get_drvdata(wdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return fts_write_byte(data->client, FTS_WATCHDOG_TIME_PRESET, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static const struct watchdog_info fts_wd_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) .identity = "FTS Teutates Hardware Watchdog",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static const struct watchdog_ops fts_wd_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) .start = fts_wd_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) .stop = fts_wd_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) .set_timeout = fts_wd_set_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static int fts_watchdog_init(struct fts_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int timeout, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) watchdog_set_drvdata(&data->wdd, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) timeout = fts_read_byte(data->client, FTS_WATCHDOG_TIME_PRESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (timeout < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /* watchdog not running, set timeout to a default of 60 sec. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (timeout == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) ret = fts_wd_set_resolution(data, seconds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) data->wdd.timeout = 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) ret = fts_read_byte(data->client, FTS_WATCHDOG_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) data->resolution = ret & BIT(1) ? seconds : minutes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) data->wdd.timeout = timeout * (u8)data->resolution;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) set_bit(WDOG_HW_RUNNING, &data->wdd.status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) /* Register our watchdog part */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) data->wdd.info = &fts_wd_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) data->wdd.ops = &fts_wd_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) data->wdd.parent = &data->client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) data->wdd.min_timeout = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /* max timeout 255 minutes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) data->wdd.max_hw_heartbeat_ms = 0xFF * 60 * MSEC_PER_SEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return watchdog_register_device(&data->wdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /* SysFS handler functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static ssize_t in_value_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct fts_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) int index = to_sensor_dev_attr(devattr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) err = fts_update_device(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return sprintf(buf, "%u\n", data->volt[index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static ssize_t temp_value_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct fts_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) int index = to_sensor_dev_attr(devattr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) err = fts_update_device(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return sprintf(buf, "%u\n", data->temp_input[index]);
^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 temp_fault_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) struct fts_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) int index = to_sensor_dev_attr(devattr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) err = fts_update_device(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /* 00h Temperature = Sensor Error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return sprintf(buf, "%d\n", data->temp_input[index] == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static ssize_t temp_alarm_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) struct fts_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) int index = to_sensor_dev_attr(devattr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) err = fts_update_device(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return sprintf(buf, "%u\n", !!(data->temp_alarm & BIT(index)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) temp_alarm_store(struct device *dev, struct device_attribute *devattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct fts_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int index = to_sensor_dev_attr(devattr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) ret = fts_update_device(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (kstrtoul(buf, 10, &ret) || ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ret = fts_read_byte(data->client, FTS_REG_TEMP_CONTROL(index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) ret = fts_write_byte(data->client, FTS_REG_TEMP_CONTROL(index),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) ret | 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) data->valid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ret = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static ssize_t fan_value_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) struct fts_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) int index = to_sensor_dev_attr(devattr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) err = fts_update_device(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return sprintf(buf, "%u\n", data->fan_input[index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static ssize_t fan_source_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) struct fts_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) int index = to_sensor_dev_attr(devattr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) err = fts_update_device(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return sprintf(buf, "%u\n", data->fan_source[index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static ssize_t fan_alarm_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct fts_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) int index = to_sensor_dev_attr(devattr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) err = fts_update_device(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return sprintf(buf, "%d\n", !!(data->fan_alarm & BIT(index)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) fan_alarm_store(struct device *dev, struct device_attribute *devattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct fts_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) int index = to_sensor_dev_attr(devattr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) ret = fts_update_device(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (kstrtoul(buf, 10, &ret) || ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ret = fts_read_byte(data->client, FTS_REG_FAN_CONTROL(index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ret = fts_write_byte(data->client, FTS_REG_FAN_CONTROL(index),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ret | 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) data->valid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) ret = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /* SysFS structs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) /* Temprature sensors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) static SENSOR_DEVICE_ATTR_RO(temp1_input, temp_value, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) static SENSOR_DEVICE_ATTR_RO(temp2_input, temp_value, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) static SENSOR_DEVICE_ATTR_RO(temp3_input, temp_value, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) static SENSOR_DEVICE_ATTR_RO(temp4_input, temp_value, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static SENSOR_DEVICE_ATTR_RO(temp5_input, temp_value, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) static SENSOR_DEVICE_ATTR_RO(temp6_input, temp_value, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static SENSOR_DEVICE_ATTR_RO(temp7_input, temp_value, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) static SENSOR_DEVICE_ATTR_RO(temp8_input, temp_value, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) static SENSOR_DEVICE_ATTR_RO(temp9_input, temp_value, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static SENSOR_DEVICE_ATTR_RO(temp10_input, temp_value, 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) static SENSOR_DEVICE_ATTR_RO(temp11_input, temp_value, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) static SENSOR_DEVICE_ATTR_RO(temp12_input, temp_value, 11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) static SENSOR_DEVICE_ATTR_RO(temp13_input, temp_value, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static SENSOR_DEVICE_ATTR_RO(temp14_input, temp_value, 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) static SENSOR_DEVICE_ATTR_RO(temp15_input, temp_value, 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) static SENSOR_DEVICE_ATTR_RO(temp16_input, temp_value, 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) static SENSOR_DEVICE_ATTR_RO(temp1_fault, temp_fault, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static SENSOR_DEVICE_ATTR_RO(temp2_fault, temp_fault, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) static SENSOR_DEVICE_ATTR_RO(temp3_fault, temp_fault, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) static SENSOR_DEVICE_ATTR_RO(temp4_fault, temp_fault, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) static SENSOR_DEVICE_ATTR_RO(temp5_fault, temp_fault, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) static SENSOR_DEVICE_ATTR_RO(temp6_fault, temp_fault, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static SENSOR_DEVICE_ATTR_RO(temp7_fault, temp_fault, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) static SENSOR_DEVICE_ATTR_RO(temp8_fault, temp_fault, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static SENSOR_DEVICE_ATTR_RO(temp9_fault, temp_fault, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static SENSOR_DEVICE_ATTR_RO(temp10_fault, temp_fault, 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) static SENSOR_DEVICE_ATTR_RO(temp11_fault, temp_fault, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) static SENSOR_DEVICE_ATTR_RO(temp12_fault, temp_fault, 11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static SENSOR_DEVICE_ATTR_RO(temp13_fault, temp_fault, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) static SENSOR_DEVICE_ATTR_RO(temp14_fault, temp_fault, 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) static SENSOR_DEVICE_ATTR_RO(temp15_fault, temp_fault, 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) static SENSOR_DEVICE_ATTR_RO(temp16_fault, temp_fault, 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static SENSOR_DEVICE_ATTR_RW(temp1_alarm, temp_alarm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) static SENSOR_DEVICE_ATTR_RW(temp2_alarm, temp_alarm, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) static SENSOR_DEVICE_ATTR_RW(temp3_alarm, temp_alarm, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) static SENSOR_DEVICE_ATTR_RW(temp4_alarm, temp_alarm, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) static SENSOR_DEVICE_ATTR_RW(temp5_alarm, temp_alarm, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static SENSOR_DEVICE_ATTR_RW(temp6_alarm, temp_alarm, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) static SENSOR_DEVICE_ATTR_RW(temp7_alarm, temp_alarm, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) static SENSOR_DEVICE_ATTR_RW(temp8_alarm, temp_alarm, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) static SENSOR_DEVICE_ATTR_RW(temp9_alarm, temp_alarm, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static SENSOR_DEVICE_ATTR_RW(temp10_alarm, temp_alarm, 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) static SENSOR_DEVICE_ATTR_RW(temp11_alarm, temp_alarm, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static SENSOR_DEVICE_ATTR_RW(temp12_alarm, temp_alarm, 11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) static SENSOR_DEVICE_ATTR_RW(temp13_alarm, temp_alarm, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static SENSOR_DEVICE_ATTR_RW(temp14_alarm, temp_alarm, 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) static SENSOR_DEVICE_ATTR_RW(temp15_alarm, temp_alarm, 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) static SENSOR_DEVICE_ATTR_RW(temp16_alarm, temp_alarm, 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) static struct attribute *fts_temp_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) &sensor_dev_attr_temp1_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) &sensor_dev_attr_temp2_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) &sensor_dev_attr_temp3_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) &sensor_dev_attr_temp4_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) &sensor_dev_attr_temp5_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) &sensor_dev_attr_temp6_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) &sensor_dev_attr_temp7_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) &sensor_dev_attr_temp8_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) &sensor_dev_attr_temp9_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) &sensor_dev_attr_temp10_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) &sensor_dev_attr_temp11_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) &sensor_dev_attr_temp12_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) &sensor_dev_attr_temp13_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) &sensor_dev_attr_temp14_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) &sensor_dev_attr_temp15_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) &sensor_dev_attr_temp16_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) &sensor_dev_attr_temp1_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) &sensor_dev_attr_temp2_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) &sensor_dev_attr_temp3_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) &sensor_dev_attr_temp4_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) &sensor_dev_attr_temp5_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) &sensor_dev_attr_temp6_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) &sensor_dev_attr_temp7_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) &sensor_dev_attr_temp8_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) &sensor_dev_attr_temp9_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) &sensor_dev_attr_temp10_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) &sensor_dev_attr_temp11_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) &sensor_dev_attr_temp12_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) &sensor_dev_attr_temp13_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) &sensor_dev_attr_temp14_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) &sensor_dev_attr_temp15_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) &sensor_dev_attr_temp16_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) &sensor_dev_attr_temp1_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) &sensor_dev_attr_temp2_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) &sensor_dev_attr_temp3_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) &sensor_dev_attr_temp4_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) &sensor_dev_attr_temp5_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) &sensor_dev_attr_temp6_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) &sensor_dev_attr_temp7_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) &sensor_dev_attr_temp8_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) &sensor_dev_attr_temp9_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) &sensor_dev_attr_temp10_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) &sensor_dev_attr_temp11_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) &sensor_dev_attr_temp12_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) &sensor_dev_attr_temp13_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) &sensor_dev_attr_temp14_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) &sensor_dev_attr_temp15_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) &sensor_dev_attr_temp16_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) /* Fans */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) static SENSOR_DEVICE_ATTR_RO(fan1_input, fan_value, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) static SENSOR_DEVICE_ATTR_RO(fan2_input, fan_value, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static SENSOR_DEVICE_ATTR_RO(fan3_input, fan_value, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) static SENSOR_DEVICE_ATTR_RO(fan4_input, fan_value, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) static SENSOR_DEVICE_ATTR_RO(fan5_input, fan_value, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) static SENSOR_DEVICE_ATTR_RO(fan6_input, fan_value, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) static SENSOR_DEVICE_ATTR_RO(fan7_input, fan_value, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static SENSOR_DEVICE_ATTR_RO(fan8_input, fan_value, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) static SENSOR_DEVICE_ATTR_RO(fan1_source, fan_source, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) static SENSOR_DEVICE_ATTR_RO(fan2_source, fan_source, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) static SENSOR_DEVICE_ATTR_RO(fan3_source, fan_source, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) static SENSOR_DEVICE_ATTR_RO(fan4_source, fan_source, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) static SENSOR_DEVICE_ATTR_RO(fan5_source, fan_source, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) static SENSOR_DEVICE_ATTR_RO(fan6_source, fan_source, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) static SENSOR_DEVICE_ATTR_RO(fan7_source, fan_source, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static SENSOR_DEVICE_ATTR_RO(fan8_source, fan_source, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) static SENSOR_DEVICE_ATTR_RW(fan1_alarm, fan_alarm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) static SENSOR_DEVICE_ATTR_RW(fan2_alarm, fan_alarm, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) static SENSOR_DEVICE_ATTR_RW(fan3_alarm, fan_alarm, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) static SENSOR_DEVICE_ATTR_RW(fan4_alarm, fan_alarm, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) static SENSOR_DEVICE_ATTR_RW(fan5_alarm, fan_alarm, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static SENSOR_DEVICE_ATTR_RW(fan6_alarm, fan_alarm, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) static SENSOR_DEVICE_ATTR_RW(fan7_alarm, fan_alarm, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) static SENSOR_DEVICE_ATTR_RW(fan8_alarm, fan_alarm, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) static struct attribute *fts_fan_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) &sensor_dev_attr_fan1_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) &sensor_dev_attr_fan2_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) &sensor_dev_attr_fan3_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) &sensor_dev_attr_fan4_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) &sensor_dev_attr_fan5_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) &sensor_dev_attr_fan6_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) &sensor_dev_attr_fan7_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) &sensor_dev_attr_fan8_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) &sensor_dev_attr_fan1_source.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) &sensor_dev_attr_fan2_source.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) &sensor_dev_attr_fan3_source.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) &sensor_dev_attr_fan4_source.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) &sensor_dev_attr_fan5_source.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) &sensor_dev_attr_fan6_source.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) &sensor_dev_attr_fan7_source.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) &sensor_dev_attr_fan8_source.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) &sensor_dev_attr_fan1_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) &sensor_dev_attr_fan2_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) &sensor_dev_attr_fan3_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) &sensor_dev_attr_fan4_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) &sensor_dev_attr_fan5_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) &sensor_dev_attr_fan6_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) &sensor_dev_attr_fan7_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) &sensor_dev_attr_fan8_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /* Voltages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) static SENSOR_DEVICE_ATTR_RO(in1_input, in_value, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static SENSOR_DEVICE_ATTR_RO(in2_input, in_value, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) static SENSOR_DEVICE_ATTR_RO(in3_input, in_value, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) static SENSOR_DEVICE_ATTR_RO(in4_input, in_value, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) static struct attribute *fts_voltage_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) &sensor_dev_attr_in1_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) &sensor_dev_attr_in2_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) &sensor_dev_attr_in3_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) &sensor_dev_attr_in4_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) NULL
^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 struct attribute_group fts_voltage_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) .attrs = fts_voltage_attrs
^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 const struct attribute_group fts_temp_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) .attrs = fts_temp_attrs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) static const struct attribute_group fts_fan_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) .attrs = fts_fan_attrs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) static const struct attribute_group *fts_attr_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) &fts_voltage_attr_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) &fts_temp_attr_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) &fts_fan_attr_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) /* Module initialization / remove functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) static int fts_detect(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) struct i2c_board_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) /* detection works with revsion greater or equal to 0x2b */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) val = i2c_smbus_read_byte_data(client, FTS_DEVICE_REVISION_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (val < 0x2b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) /* Device Detect Regs must have 0x17 0x34 and 0x54 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) val = i2c_smbus_read_byte_data(client, FTS_DEVICE_DETECT_REG_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (val != 0x17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) val = i2c_smbus_read_byte_data(client, FTS_DEVICE_DETECT_REG_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (val != 0x34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) val = i2c_smbus_read_byte_data(client, FTS_DEVICE_DETECT_REG_3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (val != 0x54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * 0x10 == Baseboard Management Controller, 0x01 == Teutates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) * Device ID Reg needs to be 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) val = i2c_smbus_read_byte_data(client, FTS_DEVICE_ID_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (val != 0x11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) strlcpy(info->type, fts_id[0].name, I2C_NAME_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) info->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) static int fts_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) struct fts_data *data = dev_get_drvdata(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) watchdog_unregister_device(&data->wdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) static int fts_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) u8 revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) struct fts_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) s8 deviceid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) struct device *hwmon_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if (client->addr != 0x73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) /* Baseboard Management Controller check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) deviceid = i2c_smbus_read_byte_data(client, FTS_DEVICE_ID_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (deviceid > 0 && (deviceid & 0xF0) == 0x10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) switch (deviceid & 0x0F) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) case 0x01:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) "No Baseboard Management Controller\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) dev_dbg(&client->dev, "No fujitsu board\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) data = devm_kzalloc(&client->dev, sizeof(struct fts_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) mutex_init(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) mutex_init(&data->access_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) data->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) dev_set_drvdata(&client->dev, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) err = i2c_smbus_read_byte_data(client, FTS_DEVICE_REVISION_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) revision = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) "ftsteutates",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) fts_attr_groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (IS_ERR(hwmon_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return PTR_ERR(hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) err = fts_watchdog_init(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) dev_info(&client->dev, "Detected FTS Teutates chip, revision: %d.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) (revision & 0xF0) >> 4, revision & 0x0F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) /* Module Details */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) static struct i2c_driver fts_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) .class = I2C_CLASS_HWMON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) .name = "ftsteutates",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) .id_table = fts_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) .probe_new = fts_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) .remove = fts_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) .detect = fts_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) .address_list = normal_i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) module_i2c_driver(fts_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) MODULE_AUTHOR("Thilo Cestonaro <thilo.cestonaro@ts.fujitsu.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) MODULE_DESCRIPTION("FTS Teutates driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) MODULE_LICENSE("GPL");