^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * adm1029.c - Part of lm_sensors, Linux kernel modules for hardware monitoring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2006 Corentin LABBE <clabbe.montjoie@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Based on LM83 Driver by Jean Delvare <jdelvare@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Give only processor, motherboard temperatures and fan tachs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Very rare chip please let me know if you use it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * http://www.analog.com/UploadedFiles/Data_Sheets/ADM1029.pdf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^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/init.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/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/hwmon-sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/hwmon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Addresses to scan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) 0x2e, 0x2f, I2C_CLIENT_END
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * The ADM1029 registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * Manufacturer ID is 0x41 for Analog Devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define ADM1029_REG_MAN_ID 0x0D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define ADM1029_REG_CHIP_ID 0x0E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define ADM1029_REG_CONFIG 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define ADM1029_REG_NB_FAN_SUPPORT 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define ADM1029_REG_TEMP_DEVICES_INSTALLED 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define ADM1029_REG_LOCAL_TEMP 0xA0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define ADM1029_REG_REMOTE1_TEMP 0xA1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define ADM1029_REG_REMOTE2_TEMP 0xA2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define ADM1029_REG_LOCAL_TEMP_HIGH 0x90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define ADM1029_REG_REMOTE1_TEMP_HIGH 0x91
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define ADM1029_REG_REMOTE2_TEMP_HIGH 0x92
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define ADM1029_REG_LOCAL_TEMP_LOW 0x98
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define ADM1029_REG_REMOTE1_TEMP_LOW 0x99
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define ADM1029_REG_REMOTE2_TEMP_LOW 0x9A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define ADM1029_REG_FAN1 0x70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define ADM1029_REG_FAN2 0x71
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define ADM1029_REG_FAN1_MIN 0x78
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define ADM1029_REG_FAN2_MIN 0x79
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define ADM1029_REG_FAN1_CONFIG 0x68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define ADM1029_REG_FAN2_CONFIG 0x69
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define TEMP_FROM_REG(val) ((val) * 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define DIV_FROM_REG(val) (1 << (((val) >> 6) - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* Registers to be checked by adm1029_update_device() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static const u8 ADM1029_REG_TEMP[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) ADM1029_REG_LOCAL_TEMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ADM1029_REG_REMOTE1_TEMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ADM1029_REG_REMOTE2_TEMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) ADM1029_REG_LOCAL_TEMP_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) ADM1029_REG_REMOTE1_TEMP_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) ADM1029_REG_REMOTE2_TEMP_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) ADM1029_REG_LOCAL_TEMP_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) ADM1029_REG_REMOTE1_TEMP_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ADM1029_REG_REMOTE2_TEMP_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static const u8 ADM1029_REG_FAN[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) ADM1029_REG_FAN1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ADM1029_REG_FAN2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) ADM1029_REG_FAN1_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ADM1029_REG_FAN2_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static const u8 ADM1029_REG_FAN_DIV[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) ADM1029_REG_FAN1_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ADM1029_REG_FAN2_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * Client data (each client gets its own)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct adm1029_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct mutex update_lock; /* protect register access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) char valid; /* zero until following fields are valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) unsigned long last_updated; /* in jiffies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* registers values, signed for temperature, unsigned for other stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) s8 temp[ARRAY_SIZE(ADM1029_REG_TEMP)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) u8 fan[ARRAY_SIZE(ADM1029_REG_FAN)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) u8 fan_div[ARRAY_SIZE(ADM1029_REG_FAN_DIV)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * function that update the status of the chips (temperature for example)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static struct adm1029_data *adm1029_update_device(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct adm1029_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * Use the "cache" Luke, don't recheck values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * if there are already checked not a long time later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) dev_dbg(&client->dev, "Updating adm1029 data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_TEMP); nr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) data->temp[nr] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) i2c_smbus_read_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) ADM1029_REG_TEMP[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_FAN); nr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) data->fan[nr] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) i2c_smbus_read_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ADM1029_REG_FAN[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_FAN_DIV); nr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) data->fan_div[nr] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) i2c_smbus_read_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) ADM1029_REG_FAN_DIV[nr]);
^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->last_updated = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) data->valid = 1;
^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) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * Sysfs stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) temp_show(struct device *dev, struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct adm1029_data *data = adm1029_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[attr->index]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) fan_show(struct device *dev, struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct adm1029_data *data = adm1029_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (data->fan[attr->index] == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) (data->fan_div[attr->index] & 0xC0) == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) data->fan[attr->index] == 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return sprintf(buf, "0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) val = 1880 * 120 / DIV_FROM_REG(data->fan_div[attr->index])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) / data->fan[attr->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return sprintf(buf, "%d\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) fan_div_show(struct device *dev, struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct adm1029_data *data = adm1029_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if ((data->fan_div[attr->index] & 0xC0) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return sprintf(buf, "0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static ssize_t fan_div_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct device_attribute *devattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct adm1029_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) int ret = kstrtol(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /*Read actual config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) reg = i2c_smbus_read_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) ADM1029_REG_FAN_DIV[attr->index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) val = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) val = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) val = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) "fan_div value %ld not supported. Choose one of 1, 2 or 4!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* Update the value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) reg = (reg & 0x3F) | (val << 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /* Update the cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) data->fan_div[attr->index] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /* Write value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) i2c_smbus_write_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) ADM1029_REG_FAN_DIV[attr->index], reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* Access rights on sysfs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static SENSOR_DEVICE_ATTR_RO(temp1_input, temp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static SENSOR_DEVICE_ATTR_RO(temp2_input, temp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static SENSOR_DEVICE_ATTR_RO(temp3_input, temp, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static SENSOR_DEVICE_ATTR_RO(temp1_max, temp, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static SENSOR_DEVICE_ATTR_RO(temp2_max, temp, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static SENSOR_DEVICE_ATTR_RO(temp3_max, temp, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) static SENSOR_DEVICE_ATTR_RO(temp1_min, temp, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static SENSOR_DEVICE_ATTR_RO(temp2_min, temp, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static SENSOR_DEVICE_ATTR_RO(temp3_min, temp, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static SENSOR_DEVICE_ATTR_RO(fan1_input, fan, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static SENSOR_DEVICE_ATTR_RO(fan2_input, fan, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static SENSOR_DEVICE_ATTR_RO(fan1_min, fan, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static SENSOR_DEVICE_ATTR_RO(fan2_min, fan, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static SENSOR_DEVICE_ATTR_RW(fan1_div, fan_div, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static SENSOR_DEVICE_ATTR_RW(fan2_div, fan_div, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static struct attribute *adm1029_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) &sensor_dev_attr_temp1_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) &sensor_dev_attr_temp1_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) &sensor_dev_attr_temp1_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) &sensor_dev_attr_temp2_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) &sensor_dev_attr_temp2_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) &sensor_dev_attr_temp2_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) &sensor_dev_attr_temp3_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) &sensor_dev_attr_temp3_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) &sensor_dev_attr_temp3_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) &sensor_dev_attr_fan1_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) &sensor_dev_attr_fan2_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) &sensor_dev_attr_fan1_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) &sensor_dev_attr_fan2_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) &sensor_dev_attr_fan1_div.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) &sensor_dev_attr_fan2_div.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) ATTRIBUTE_GROUPS(adm1029);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * Real code
^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) /* Return 0 if detection is successful, -ENODEV otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static int adm1029_detect(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct i2c_board_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct i2c_adapter *adapter = client->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) u8 man_id, chip_id, temp_devices_installed, nb_fan_support;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * ADM1029 doesn't have CHIP ID, check just MAN ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * For better detection we check also ADM1029_TEMP_DEVICES_INSTALLED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * ADM1029_REG_NB_FAN_SUPPORT and compare it with possible values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * documented
^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) man_id = i2c_smbus_read_byte_data(client, ADM1029_REG_MAN_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) chip_id = i2c_smbus_read_byte_data(client, ADM1029_REG_CHIP_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) temp_devices_installed = i2c_smbus_read_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) ADM1029_REG_TEMP_DEVICES_INSTALLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) nb_fan_support = i2c_smbus_read_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) ADM1029_REG_NB_FAN_SUPPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* 0x41 is Analog Devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (man_id != 0x41 || (temp_devices_installed & 0xf9) != 0x01 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) nb_fan_support != 0x03)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if ((chip_id & 0xF0) != 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * There are no "official" CHIP ID, so actually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * we use Major/Minor revision for that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) pr_info("Unknown major revision %x, please let us know\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) chip_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) strlcpy(info->type, "adm1029", I2C_NAME_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static int adm1029_init_client(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) u8 config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) config = i2c_smbus_read_byte_data(client, ADM1029_REG_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if ((config & 0x10) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) i2c_smbus_write_byte_data(client, ADM1029_REG_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) config | 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /* recheck config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) config = i2c_smbus_read_byte_data(client, ADM1029_REG_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if ((config & 0x10) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) dev_err(&client->dev, "Initialization failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return 1;
^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 int adm1029_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct adm1029_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) struct device *hwmon_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) data = devm_kzalloc(dev, sizeof(struct adm1029_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) data->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) mutex_init(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * Initialize the ADM1029 chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * Check config register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (adm1029_init_client(client) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) adm1029_groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return PTR_ERR_OR_ZERO(hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static const struct i2c_device_id adm1029_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) { "adm1029", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) MODULE_DEVICE_TABLE(i2c, adm1029_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static struct i2c_driver adm1029_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) .class = I2C_CLASS_HWMON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) .name = "adm1029",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) .probe_new = adm1029_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .id_table = adm1029_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) .detect = adm1029_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) .address_list = normal_i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) module_i2c_driver(adm1029_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) MODULE_AUTHOR("Corentin LABBE <clabbe.montjoie@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) MODULE_DESCRIPTION("adm1029 driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) MODULE_LICENSE("GPL v2");