^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) * amc6821.c - Part of lm_sensors, Linux kernel modules for hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * monitoring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2009 T. Mertelj <tomaz.mertelj@guest.arnes.si>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Based on max6650.c:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2007 Hans J. Koch <hjk@hansjkoch.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h> /* Needed for KERN_INFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.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/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/hwmon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/hwmon-sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Addresses to scan.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static const unsigned short normal_i2c[] = {0x18, 0x19, 0x1a, 0x2c, 0x2d, 0x2e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) 0x4c, 0x4d, 0x4e, I2C_CLIENT_END};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * Insmod parameters
^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) static int pwminv; /*Inverted PWM output. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) module_param(pwminv, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static int init = 1; /*Power-on initialization.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) module_param(init, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) enum chips { amc6821 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define AMC6821_REG_DEV_ID 0x3D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define AMC6821_REG_COMP_ID 0x3E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define AMC6821_REG_CONF1 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define AMC6821_REG_CONF2 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define AMC6821_REG_CONF3 0x3F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define AMC6821_REG_CONF4 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define AMC6821_REG_STAT1 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define AMC6821_REG_STAT2 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define AMC6821_REG_TDATA_LOW 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define AMC6821_REG_TDATA_HI 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define AMC6821_REG_LTEMP_HI 0x0A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define AMC6821_REG_RTEMP_HI 0x0B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define AMC6821_REG_LTEMP_LIMIT_MIN 0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define AMC6821_REG_LTEMP_LIMIT_MAX 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define AMC6821_REG_RTEMP_LIMIT_MIN 0x19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define AMC6821_REG_RTEMP_LIMIT_MAX 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define AMC6821_REG_LTEMP_CRIT 0x1B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define AMC6821_REG_RTEMP_CRIT 0x1D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define AMC6821_REG_PSV_TEMP 0x1C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define AMC6821_REG_DCY 0x22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define AMC6821_REG_LTEMP_FAN_CTRL 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define AMC6821_REG_RTEMP_FAN_CTRL 0x25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define AMC6821_REG_DCY_LOW_TEMP 0x21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define AMC6821_REG_TACH_LLIMITL 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define AMC6821_REG_TACH_LLIMITH 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define AMC6821_REG_TACH_HLIMITL 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define AMC6821_REG_TACH_HLIMITH 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define AMC6821_CONF1_START 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define AMC6821_CONF1_FAN_INT_EN 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define AMC6821_CONF1_FANIE 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define AMC6821_CONF1_PWMINV 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define AMC6821_CONF1_FAN_FAULT_EN 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define AMC6821_CONF1_FDRC0 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define AMC6821_CONF1_FDRC1 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define AMC6821_CONF1_THERMOVIE 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define AMC6821_CONF2_PWM_EN 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define AMC6821_CONF2_TACH_MODE 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define AMC6821_CONF2_TACH_EN 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define AMC6821_CONF2_RTFIE 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define AMC6821_CONF2_LTOIE 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define AMC6821_CONF2_RTOIE 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define AMC6821_CONF2_PSVIE 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define AMC6821_CONF2_RST 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define AMC6821_CONF3_THERM_FAN_EN 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define AMC6821_CONF3_REV_MASK 0x0F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define AMC6821_CONF4_OVREN 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define AMC6821_CONF4_TACH_FAST 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define AMC6821_CONF4_PSPR 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define AMC6821_CONF4_MODE 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define AMC6821_STAT1_RPM_ALARM 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define AMC6821_STAT1_FANS 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define AMC6821_STAT1_RTH 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define AMC6821_STAT1_RTL 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define AMC6821_STAT1_R_THERM 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define AMC6821_STAT1_RTF 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define AMC6821_STAT1_LTH 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define AMC6821_STAT1_LTL 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define AMC6821_STAT2_RTC 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define AMC6821_STAT2_LTC 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define AMC6821_STAT2_LPSV 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define AMC6821_STAT2_L_THERM 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define AMC6821_STAT2_THERM_IN 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) enum {IDX_TEMP1_INPUT = 0, IDX_TEMP1_MIN, IDX_TEMP1_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) IDX_TEMP1_CRIT, IDX_TEMP2_INPUT, IDX_TEMP2_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) IDX_TEMP2_MAX, IDX_TEMP2_CRIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) TEMP_IDX_LEN, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static const u8 temp_reg[] = {AMC6821_REG_LTEMP_HI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) AMC6821_REG_LTEMP_LIMIT_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) AMC6821_REG_LTEMP_LIMIT_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) AMC6821_REG_LTEMP_CRIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) AMC6821_REG_RTEMP_HI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) AMC6821_REG_RTEMP_LIMIT_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) AMC6821_REG_RTEMP_LIMIT_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) AMC6821_REG_RTEMP_CRIT, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) enum {IDX_FAN1_INPUT = 0, IDX_FAN1_MIN, IDX_FAN1_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) FAN1_IDX_LEN, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static const u8 fan_reg_low[] = {AMC6821_REG_TDATA_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) AMC6821_REG_TACH_LLIMITL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) AMC6821_REG_TACH_HLIMITL, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static const u8 fan_reg_hi[] = {AMC6821_REG_TDATA_HI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) AMC6821_REG_TACH_LLIMITH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) AMC6821_REG_TACH_HLIMITH, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * Client data (each client gets its own)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct amc6821_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct mutex update_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) char valid; /* zero until following fields are valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) unsigned long last_updated; /* in jiffies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /* register values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int temp[TEMP_IDX_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) u16 fan[FAN1_IDX_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) u8 fan1_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) u8 pwm1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) u8 temp1_auto_point_temp[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) u8 temp2_auto_point_temp[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) u8 pwm1_auto_point_pwm[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) u8 pwm1_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) u8 pwm1_auto_channels_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) u8 stat1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) u8 stat2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static struct amc6821_data *amc6821_update_device(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct amc6821_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) int timeout = HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (time_after(jiffies, data->last_updated + timeout) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) !data->valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) for (i = 0; i < TEMP_IDX_LEN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) data->temp[i] = (int8_t)i2c_smbus_read_byte_data(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) client, temp_reg[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) data->stat1 = i2c_smbus_read_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) AMC6821_REG_STAT1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) data->stat2 = i2c_smbus_read_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) AMC6821_REG_STAT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) data->pwm1 = i2c_smbus_read_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) AMC6821_REG_DCY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) for (i = 0; i < FAN1_IDX_LEN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) data->fan[i] = i2c_smbus_read_byte_data(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) fan_reg_low[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) data->fan[i] += i2c_smbus_read_byte_data(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) fan_reg_hi[i]) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) data->fan1_div = i2c_smbus_read_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) AMC6821_REG_CONF4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) data->fan1_div = data->fan1_div & AMC6821_CONF4_PSPR ? 4 : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) data->pwm1_auto_point_pwm[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) data->pwm1_auto_point_pwm[2] = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) data->pwm1_auto_point_pwm[1] = i2c_smbus_read_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) AMC6821_REG_DCY_LOW_TEMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) data->temp1_auto_point_temp[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) i2c_smbus_read_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) AMC6821_REG_PSV_TEMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) data->temp2_auto_point_temp[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) data->temp1_auto_point_temp[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) reg = i2c_smbus_read_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) AMC6821_REG_LTEMP_FAN_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) data->temp1_auto_point_temp[1] = (reg & 0xF8) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) reg &= 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) reg = 0x20 >> reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (reg > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) data->temp1_auto_point_temp[2] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) data->temp1_auto_point_temp[1] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) (data->pwm1_auto_point_pwm[2] -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) data->pwm1_auto_point_pwm[1]) / reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) data->temp1_auto_point_temp[2] = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) reg = i2c_smbus_read_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) AMC6821_REG_RTEMP_FAN_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) data->temp2_auto_point_temp[1] = (reg & 0xF8) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) reg &= 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) reg = 0x20 >> reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (reg > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) data->temp2_auto_point_temp[2] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) data->temp2_auto_point_temp[1] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) (data->pwm1_auto_point_pwm[2] -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) data->pwm1_auto_point_pwm[1]) / reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) data->temp2_auto_point_temp[2] = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) reg = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) reg = (reg >> 5) & 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) case 0: /*open loop: software sets pwm1*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) data->pwm1_auto_channels_temp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) data->pwm1_enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) case 2: /*closed loop: remote T (temp2)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) data->pwm1_auto_channels_temp = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) data->pwm1_enable = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) case 3: /*closed loop: local and remote T (temp2)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) data->pwm1_auto_channels_temp = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) data->pwm1_enable = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) case 1: /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * semi-open loop: software sets rpm, chip controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * pwm1, currently not implemented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) data->pwm1_auto_channels_temp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) data->pwm1_enable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) data->last_updated = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) data->valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static ssize_t temp_show(struct device *dev, struct device_attribute *devattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct amc6821_data *data = amc6821_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) int ix = to_sensor_dev_attr(devattr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return sprintf(buf, "%d\n", data->temp[ix] * 1000);
^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 ssize_t temp_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct amc6821_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) int ix = to_sensor_dev_attr(attr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) int ret = kstrtol(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) val = clamp_val(val / 1000, -128, 127);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) data->temp[ix] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (i2c_smbus_write_byte_data(client, temp_reg[ix], data->temp[ix])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) dev_err(&client->dev, "Register write error, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) count = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static ssize_t temp_alarm_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct amc6821_data *data = amc6821_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) int ix = to_sensor_dev_attr(devattr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) u8 flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) switch (ix) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) case IDX_TEMP1_MIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) flag = data->stat1 & AMC6821_STAT1_LTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) case IDX_TEMP1_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) flag = data->stat1 & AMC6821_STAT1_LTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) case IDX_TEMP1_CRIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) flag = data->stat2 & AMC6821_STAT2_LTC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) case IDX_TEMP2_MIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) flag = data->stat1 & AMC6821_STAT1_RTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) case IDX_TEMP2_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) flag = data->stat1 & AMC6821_STAT1_RTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) case IDX_TEMP2_CRIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) flag = data->stat2 & AMC6821_STAT2_RTC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) dev_dbg(dev, "Unknown attr->index (%d).\n", ix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return sprintf(buf, "1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return sprintf(buf, "0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static ssize_t temp2_fault_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) struct amc6821_data *data = amc6821_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (data->stat1 & AMC6821_STAT1_RTF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return sprintf(buf, "1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return sprintf(buf, "0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static ssize_t pwm1_show(struct device *dev, struct device_attribute *devattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct amc6821_data *data = amc6821_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return sprintf(buf, "%d\n", data->pwm1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) static ssize_t pwm1_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct device_attribute *devattr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct amc6821_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) int ret = kstrtol(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) data->pwm1 = clamp_val(val , 0, 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) i2c_smbus_write_byte_data(client, AMC6821_REG_DCY, data->pwm1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static ssize_t pwm1_enable_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct amc6821_data *data = amc6821_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return sprintf(buf, "%d\n", data->pwm1_enable);
^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) static ssize_t pwm1_enable_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) struct amc6821_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) int config = kstrtol(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (config < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) "Error reading configuration register, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) count = config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) config &= ~AMC6821_CONF1_FDRC0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) config &= ~AMC6821_CONF1_FDRC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) config &= ~AMC6821_CONF1_FDRC0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) config |= AMC6821_CONF1_FDRC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) config |= AMC6821_CONF1_FDRC0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) config |= AMC6821_CONF1_FDRC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) count = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF1, config)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) "Configuration register write error, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) count = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) static ssize_t pwm1_auto_channels_temp_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct device_attribute *devattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct amc6821_data *data = amc6821_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return sprintf(buf, "%d\n", data->pwm1_auto_channels_temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static ssize_t temp_auto_point_temp_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct device_attribute *devattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) int ix = to_sensor_dev_attr_2(devattr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) int nr = to_sensor_dev_attr_2(devattr)->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) struct amc6821_data *data = amc6821_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) switch (nr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return sprintf(buf, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) data->temp1_auto_point_temp[ix] * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return sprintf(buf, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) data->temp2_auto_point_temp[ix] * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) dev_dbg(dev, "Unknown attr->nr (%d).\n", nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) static ssize_t pwm1_auto_point_pwm_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct device_attribute *devattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) int ix = to_sensor_dev_attr(devattr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct amc6821_data *data = amc6821_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return sprintf(buf, "%d\n", data->pwm1_auto_point_pwm[ix]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) static inline ssize_t set_slope_register(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) u8 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) u8 dpwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) u8 *ptemp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) int dt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) dt = ptemp[2]-ptemp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) for (tmp = 4; tmp > 0; tmp--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (dt * (0x20 >> tmp) >= dpwm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) tmp |= (ptemp[1] & 0x7C) << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (i2c_smbus_write_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) reg, tmp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) dev_err(&client->dev, "Register write error, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) static ssize_t temp_auto_point_temp_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct amc6821_data *data = amc6821_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) int ix = to_sensor_dev_attr_2(attr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) int nr = to_sensor_dev_attr_2(attr)->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) u8 *ptemp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) int dpwm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) int ret = kstrtol(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) switch (nr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) ptemp = data->temp1_auto_point_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) reg = AMC6821_REG_LTEMP_FAN_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) ptemp = data->temp2_auto_point_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) reg = AMC6821_REG_RTEMP_FAN_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) dev_dbg(dev, "Unknown attr->nr (%d).\n", nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) data->valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) switch (ix) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) ptemp[0] = clamp_val(val / 1000, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) data->temp1_auto_point_temp[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) ptemp[0] = clamp_val(ptemp[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) data->temp2_auto_point_temp[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) ptemp[0] = clamp_val(ptemp[0], 0, 63);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (i2c_smbus_write_byte_data(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) AMC6821_REG_PSV_TEMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) ptemp[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) "Register write error, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) count = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) ptemp[1] = clamp_val(val / 1000, (ptemp[0] & 0x7C) + 4, 124);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ptemp[1] &= 0x7C;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ptemp[2] = clamp_val(ptemp[2], ptemp[1] + 1, 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) ptemp[2] = clamp_val(val / 1000, ptemp[1]+1, 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) dev_dbg(dev, "Unknown attr->index (%d).\n", ix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) count = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) dpwm = data->pwm1_auto_point_pwm[2] - data->pwm1_auto_point_pwm[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (set_slope_register(client, reg, dpwm, ptemp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) count = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) EXIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) static ssize_t pwm1_auto_point_pwm_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) struct amc6821_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) int dpwm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) int ret = kstrtol(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) data->pwm1_auto_point_pwm[1] = clamp_val(val, 0, 254);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (i2c_smbus_write_byte_data(client, AMC6821_REG_DCY_LOW_TEMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) data->pwm1_auto_point_pwm[1])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) dev_err(&client->dev, "Register write error, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) count = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) dpwm = data->pwm1_auto_point_pwm[2] - data->pwm1_auto_point_pwm[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (set_slope_register(client, AMC6821_REG_LTEMP_FAN_CTRL, dpwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) data->temp1_auto_point_temp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) count = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (set_slope_register(client, AMC6821_REG_RTEMP_FAN_CTRL, dpwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) data->temp2_auto_point_temp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) count = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) EXIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) data->valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static ssize_t fan_show(struct device *dev, struct device_attribute *devattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) struct amc6821_data *data = amc6821_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) int ix = to_sensor_dev_attr(devattr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (0 == data->fan[ix])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return sprintf(buf, "0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return sprintf(buf, "%d\n", (int)(6000000 / data->fan[ix]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) static ssize_t fan1_fault_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) struct amc6821_data *data = amc6821_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (data->stat1 & AMC6821_STAT1_FANS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return sprintf(buf, "1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) return sprintf(buf, "0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) static ssize_t fan_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) struct amc6821_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) int ix = to_sensor_dev_attr(attr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) int ret = kstrtol(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) val = 1 > val ? 0xFFFF : 6000000/val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) data->fan[ix] = (u16) clamp_val(val, 1, 0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (i2c_smbus_write_byte_data(client, fan_reg_low[ix],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) data->fan[ix] & 0xFF)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) dev_err(&client->dev, "Register write error, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) count = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (i2c_smbus_write_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) fan_reg_hi[ix], data->fan[ix] >> 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) dev_err(&client->dev, "Register write error, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) count = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) EXIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static ssize_t fan1_div_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) struct device_attribute *devattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) struct amc6821_data *data = amc6821_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return sprintf(buf, "%d\n", data->fan1_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) static ssize_t fan1_div_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) struct amc6821_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) int config = kstrtol(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if (config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (config < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) "Error reading configuration register, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) count = config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) config &= ~AMC6821_CONF4_PSPR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) data->fan1_div = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) config |= AMC6821_CONF4_PSPR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) data->fan1_div = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) count = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF4, config)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) "Configuration register write error, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) count = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) EXIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) static SENSOR_DEVICE_ATTR_RO(temp1_input, temp, IDX_TEMP1_INPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) static SENSOR_DEVICE_ATTR_RW(temp1_min, temp, IDX_TEMP1_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) static SENSOR_DEVICE_ATTR_RW(temp1_max, temp, IDX_TEMP1_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) static SENSOR_DEVICE_ATTR_RW(temp1_crit, temp, IDX_TEMP1_CRIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) static SENSOR_DEVICE_ATTR_RO(temp1_min_alarm, temp_alarm, IDX_TEMP1_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) static SENSOR_DEVICE_ATTR_RO(temp1_max_alarm, temp_alarm, IDX_TEMP1_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) static SENSOR_DEVICE_ATTR_RO(temp1_crit_alarm, temp_alarm, IDX_TEMP1_CRIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) static SENSOR_DEVICE_ATTR_RO(temp2_input, temp, IDX_TEMP2_INPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) static SENSOR_DEVICE_ATTR_RW(temp2_min, temp, IDX_TEMP2_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) static SENSOR_DEVICE_ATTR_RW(temp2_max, temp, IDX_TEMP2_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) static SENSOR_DEVICE_ATTR_RW(temp2_crit, temp, IDX_TEMP2_CRIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) static SENSOR_DEVICE_ATTR_RO(temp2_fault, temp2_fault, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) static SENSOR_DEVICE_ATTR_RO(temp2_min_alarm, temp_alarm, IDX_TEMP2_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) static SENSOR_DEVICE_ATTR_RO(temp2_max_alarm, temp_alarm, IDX_TEMP2_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) static SENSOR_DEVICE_ATTR_RO(temp2_crit_alarm, temp_alarm, IDX_TEMP2_CRIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) static SENSOR_DEVICE_ATTR_RO(fan1_input, fan, IDX_FAN1_INPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) static SENSOR_DEVICE_ATTR_RW(fan1_min, fan, IDX_FAN1_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) static SENSOR_DEVICE_ATTR_RW(fan1_max, fan, IDX_FAN1_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) static SENSOR_DEVICE_ATTR_RO(fan1_fault, fan1_fault, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) static SENSOR_DEVICE_ATTR_RW(fan1_div, fan1_div, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) static SENSOR_DEVICE_ATTR_RW(pwm1, pwm1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static SENSOR_DEVICE_ATTR_RW(pwm1_enable, pwm1_enable, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point1_pwm, pwm1_auto_point_pwm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) static SENSOR_DEVICE_ATTR_RW(pwm1_auto_point2_pwm, pwm1_auto_point_pwm, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) static SENSOR_DEVICE_ATTR_RO(pwm1_auto_point3_pwm, pwm1_auto_point_pwm, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) static SENSOR_DEVICE_ATTR_RO(pwm1_auto_channels_temp, pwm1_auto_channels_temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) static SENSOR_DEVICE_ATTR_2_RO(temp1_auto_point1_temp, temp_auto_point_temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) static SENSOR_DEVICE_ATTR_2_RW(temp1_auto_point2_temp, temp_auto_point_temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) static SENSOR_DEVICE_ATTR_2_RW(temp1_auto_point3_temp, temp_auto_point_temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 1, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) static SENSOR_DEVICE_ATTR_2_RW(temp2_auto_point1_temp, temp_auto_point_temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) static SENSOR_DEVICE_ATTR_2_RW(temp2_auto_point2_temp, temp_auto_point_temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 2, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) static SENSOR_DEVICE_ATTR_2_RW(temp2_auto_point3_temp, temp_auto_point_temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 2, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) static struct attribute *amc6821_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) &sensor_dev_attr_temp1_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) &sensor_dev_attr_temp1_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) &sensor_dev_attr_temp1_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) &sensor_dev_attr_temp1_crit.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) &sensor_dev_attr_temp2_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) &sensor_dev_attr_temp2_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) &sensor_dev_attr_temp2_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) &sensor_dev_attr_temp2_crit.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) &sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) &sensor_dev_attr_temp2_crit_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) &sensor_dev_attr_temp2_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) &sensor_dev_attr_fan1_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) &sensor_dev_attr_fan1_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) &sensor_dev_attr_fan1_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) &sensor_dev_attr_fan1_fault.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) &sensor_dev_attr_fan1_div.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) &sensor_dev_attr_pwm1.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) &sensor_dev_attr_pwm1_enable.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) &sensor_dev_attr_pwm1_auto_point3_pwm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) &sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) &sensor_dev_attr_temp1_auto_point3_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) &sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) &sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) &sensor_dev_attr_temp2_auto_point3_temp.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) ATTRIBUTE_GROUPS(amc6821);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) /* Return 0 if detection is successful, -ENODEV otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) static int amc6821_detect(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) struct i2c_board_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) struct i2c_adapter *adapter = client->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) int address = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) int dev_id, comp_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) dev_dbg(&adapter->dev, "amc6821_detect called.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) dev_dbg(&adapter->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) "amc6821: I2C bus doesn't support byte mode, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) "skipping.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) dev_id = i2c_smbus_read_byte_data(client, AMC6821_REG_DEV_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) comp_id = i2c_smbus_read_byte_data(client, AMC6821_REG_COMP_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) if (dev_id != 0x21 || comp_id != 0x49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) dev_dbg(&adapter->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) "amc6821: detection failed at 0x%02x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) * Bit 7 of the address register is ignored, so we can check the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) * ID registers again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) dev_id = i2c_smbus_read_byte_data(client, 0x80 | AMC6821_REG_DEV_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) comp_id = i2c_smbus_read_byte_data(client, 0x80 | AMC6821_REG_COMP_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (dev_id != 0x21 || comp_id != 0x49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) dev_dbg(&adapter->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) "amc6821: detection failed at 0x%02x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) dev_info(&adapter->dev, "amc6821: chip found at 0x%02x.\n", address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) strlcpy(info->type, "amc6821", I2C_NAME_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static int amc6821_init_client(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) int config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) int err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (init) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (config < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) "Error reading configuration register, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) config |= AMC6821_CONF4_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) config)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) "Configuration register write error, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) if (config < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) "Error reading configuration register, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) dev_info(&client->dev, "Revision %d\n", config & 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) config &= ~AMC6821_CONF3_THERM_FAN_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) config)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) "Configuration register write error, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (config < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) "Error reading configuration register, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) config &= ~AMC6821_CONF2_RTFIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) config &= ~AMC6821_CONF2_LTOIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) config &= ~AMC6821_CONF2_RTOIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (i2c_smbus_write_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) AMC6821_REG_CONF2, config)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) "Configuration register write error, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (config < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) "Error reading configuration register, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) config &= ~AMC6821_CONF1_THERMOVIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) config &= ~AMC6821_CONF1_FANIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) config |= AMC6821_CONF1_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (pwminv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) config |= AMC6821_CONF1_PWMINV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) config &= ~AMC6821_CONF1_PWMINV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) if (i2c_smbus_write_byte_data(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) client, AMC6821_REG_CONF1, config)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) "Configuration register write error, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) static int amc6821_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) struct amc6821_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) struct device *hwmon_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) data = devm_kzalloc(dev, sizeof(struct amc6821_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) data->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) mutex_init(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * Initialize the amc6821 chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) err = amc6821_init_client(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) amc6821_groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) return PTR_ERR_OR_ZERO(hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) static const struct i2c_device_id amc6821_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) { "amc6821", amc6821 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) MODULE_DEVICE_TABLE(i2c, amc6821_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) static struct i2c_driver amc6821_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) .class = I2C_CLASS_HWMON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) .name = "amc6821",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) .probe_new = amc6821_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) .id_table = amc6821_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) .detect = amc6821_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) .address_list = normal_i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) module_i2c_driver(amc6821_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) MODULE_AUTHOR("T. Mertelj <tomaz.mertelj@guest.arnes.si>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) MODULE_DESCRIPTION("Texas Instruments amc6821 hwmon driver");