^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) * w83791d.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) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2006-2007 Charles Spirakis <bezaur@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Supports following chips:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * w83791d 10 5 5 3 0x71 0x5ca3 yes no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * The w83791d chip appears to be part way between the 83781d and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * 83792d. Thus, this file is derived from both the w83792d.c and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * w83781d.c files.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * The w83791g chip is the same as the w83791d but lead-free.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/hwmon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/hwmon-vid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/hwmon-sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define NUMBER_OF_VIN 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define NUMBER_OF_FANIN 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define NUMBER_OF_TEMPIN 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define NUMBER_OF_PWM 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* Addresses to scan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) I2C_CLIENT_END };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* Insmod parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static unsigned short force_subclients[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) module_param_array(force_subclients, short, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) MODULE_PARM_DESC(force_subclients,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) "List of subclient addresses: {bus, clientaddr, subclientaddr1, subclientaddr2}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static bool reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) module_param(reset, bool, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) MODULE_PARM_DESC(reset, "Set to one to force a hardware chip reset");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static bool init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) module_param(init, bool, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) MODULE_PARM_DESC(init, "Set to one to force extra software initialization");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* The W83791D registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static const u8 W83791D_REG_IN[NUMBER_OF_VIN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 0x20, /* VCOREA in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) 0x21, /* VINR0 in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) 0x22, /* +3.3VIN in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 0x23, /* VDD5V in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 0x24, /* +12VIN in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 0x25, /* -12VIN in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 0x26, /* -5VIN in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 0xB0, /* 5VSB in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 0xB1, /* VBAT in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 0xB2 /* VINR1 in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static const u8 W83791D_REG_IN_MAX[NUMBER_OF_VIN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) 0x2B, /* VCOREA High Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) 0x2D, /* VINR0 High Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 0x2F, /* +3.3VIN High Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) 0x31, /* VDD5V High Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) 0x33, /* +12VIN High Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) 0x35, /* -12VIN High Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) 0x37, /* -5VIN High Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) 0xB4, /* 5VSB High Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) 0xB6, /* VBAT High Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) 0xB8 /* VINR1 High Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static const u8 W83791D_REG_IN_MIN[NUMBER_OF_VIN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) 0x2C, /* VCOREA Low Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) 0x2E, /* VINR0 Low Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) 0x30, /* +3.3VIN Low Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) 0x32, /* VDD5V Low Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) 0x34, /* +12VIN Low Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) 0x36, /* -12VIN Low Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) 0x38, /* -5VIN Low Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) 0xB5, /* 5VSB Low Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) 0xB7, /* VBAT Low Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) 0xB9 /* VINR1 Low Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static const u8 W83791D_REG_FAN[NUMBER_OF_FANIN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) 0x28, /* FAN 1 Count in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) 0x29, /* FAN 2 Count in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) 0x2A, /* FAN 3 Count in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) 0xBA, /* FAN 4 Count in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 0xBB, /* FAN 5 Count in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static const u8 W83791D_REG_FAN_MIN[NUMBER_OF_FANIN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 0x3B, /* FAN 1 Count Low Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 0x3C, /* FAN 2 Count Low Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 0x3D, /* FAN 3 Count Low Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 0xBC, /* FAN 4 Count Low Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 0xBD, /* FAN 5 Count Low Limit in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static const u8 W83791D_REG_PWM[NUMBER_OF_PWM] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 0x81, /* PWM 1 duty cycle register in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 0x83, /* PWM 2 duty cycle register in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 0x94, /* PWM 3 duty cycle register in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 0xA0, /* PWM 4 duty cycle register in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 0xA1, /* PWM 5 duty cycle register in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static const u8 W83791D_REG_TEMP_TARGET[3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 0x85, /* PWM 1 target temperature for temp 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 0x86, /* PWM 2 target temperature for temp 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 0x96, /* PWM 3 target temperature for temp 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static const u8 W83791D_REG_TEMP_TOL[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 0x87, /* PWM 1/2 temperature tolerance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 0x97, /* PWM 3 temperature tolerance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static const u8 W83791D_REG_FAN_CFG[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 0x84, /* FAN 1/2 configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 0x95, /* FAN 3 configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static const u8 W83791D_REG_FAN_DIV[3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 0x47, /* contains FAN1 and FAN2 Divisor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 0x4b, /* contains FAN3 Divisor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 0x5C, /* contains FAN4 and FAN5 Divisor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define W83791D_REG_BANK 0x4E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define W83791D_REG_TEMP2_CONFIG 0xC2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define W83791D_REG_TEMP3_CONFIG 0xCA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static const u8 W83791D_REG_TEMP1[3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 0x27, /* TEMP 1 in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 0x39, /* TEMP 1 Over in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 0x3A, /* TEMP 1 Hyst in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static const u8 W83791D_REG_TEMP_ADD[2][6] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {0xC0, /* TEMP 2 in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 0xC1, /* TEMP 2(0.5 deg) in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 0xC5, /* TEMP 2 Over High part in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 0xC6, /* TEMP 2 Over Low part in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 0xC3, /* TEMP 2 Thyst High part in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 0xC4}, /* TEMP 2 Thyst Low part in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {0xC8, /* TEMP 3 in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 0xC9, /* TEMP 3(0.5 deg) in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 0xCD, /* TEMP 3 Over High part in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 0xCE, /* TEMP 3 Over Low part in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 0xCB, /* TEMP 3 Thyst High part in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 0xCC} /* TEMP 3 Thyst Low part in DataSheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define W83791D_REG_BEEP_CONFIG 0x4D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static const u8 W83791D_REG_BEEP_CTRL[3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 0x56, /* BEEP Control Register 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 0x57, /* BEEP Control Register 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 0xA3, /* BEEP Control Register 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define W83791D_REG_GPIO 0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define W83791D_REG_CONFIG 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define W83791D_REG_VID_FANDIV 0x47
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define W83791D_REG_DID_VID4 0x49
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define W83791D_REG_WCHIPID 0x58
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #define W83791D_REG_CHIPMAN 0x4F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define W83791D_REG_PIN 0x4B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define W83791D_REG_I2C_SUBADDR 0x4A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define W83791D_REG_ALARM1 0xA9 /* realtime status register1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define W83791D_REG_ALARM2 0xAA /* realtime status register2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define W83791D_REG_ALARM3 0xAB /* realtime status register3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #define W83791D_REG_VBAT 0x5D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) #define W83791D_REG_I2C_ADDR 0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * The SMBus locks itself. The Winbond W83791D has a bank select register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * (index 0x4e), but the driver only accesses registers in bank 0. Since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * we don't switch banks, we don't need any special code to handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * locking access between bank switches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static inline int w83791d_read(struct i2c_client *client, u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return i2c_smbus_read_byte_data(client, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static inline int w83791d_write(struct i2c_client *client, u8 reg, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return i2c_smbus_write_byte_data(client, reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * The analog voltage inputs have 16mV LSB. Since the sysfs output is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * in mV as would be measured on the chip input pin, need to just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * multiply/divide by 16 to translate from/to register values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) #define IN_TO_REG(val) (clamp_val((((val) + 8) / 16), 0, 255))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #define IN_FROM_REG(val) ((val) * 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static u8 fan_to_reg(long rpm, int div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (rpm == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) rpm = clamp_val(rpm, 1, 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) return clamp_val((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #define FAN_FROM_REG(val, div) ((val) == 0 ? -1 : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) ((val) == 255 ? 0 : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 1350000 / ((val) * (div))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* for temp1 which is 8-bit resolution, LSB = 1 degree Celsius */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #define TEMP1_FROM_REG(val) ((val) * 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) #define TEMP1_TO_REG(val) ((val) <= -128000 ? -128 : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) (val) >= 127000 ? 127 : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) (val) < 0 ? ((val) - 500) / 1000 : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) ((val) + 500) / 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * for temp2 and temp3 which are 9-bit resolution, LSB = 0.5 degree Celsius
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * Assumes the top 8 bits are the integral amount and the bottom 8 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * are the fractional amount. Since we only have 0.5 degree resolution,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * the bottom 7 bits will always be zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) #define TEMP23_FROM_REG(val) ((val) / 128 * 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) #define TEMP23_TO_REG(val) (DIV_ROUND_CLOSEST(clamp_val((val), -128000, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 127500), 500) * 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* for thermal cruise target temp, 7-bits, LSB = 1 degree Celsius */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) #define TARGET_TEMP_TO_REG(val) DIV_ROUND_CLOSEST(clamp_val((val), 0, 127000), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /* for thermal cruise temp tolerance, 4-bits, LSB = 1 degree Celsius */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) #define TOL_TEMP_TO_REG(val) DIV_ROUND_CLOSEST(clamp_val((val), 0, 15000), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) #define BEEP_MASK_TO_REG(val) ((val) & 0xffffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) #define BEEP_MASK_FROM_REG(val) ((val) & 0xffffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) #define DIV_FROM_REG(val) (1 << (val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static u8 div_to_reg(int nr, long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /* fan divisors max out at 128 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) val = clamp_val(val, 1, 128) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) for (i = 0; i < 7; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (val == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) val >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return (u8) i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct w83791d_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct device *hwmon_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct mutex update_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) char valid; /* !=0 if following fields are valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) unsigned long last_updated; /* In jiffies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /* volts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) u8 in[NUMBER_OF_VIN]; /* Register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) u8 in_max[NUMBER_OF_VIN]; /* Register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) u8 in_min[NUMBER_OF_VIN]; /* Register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* fans */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) u8 fan[NUMBER_OF_FANIN]; /* Register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) u8 fan_min[NUMBER_OF_FANIN]; /* Register value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) u8 fan_div[NUMBER_OF_FANIN]; /* Register encoding, shifted right */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* Temperature sensors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) s8 temp1[3]; /* current, over, thyst */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) s16 temp_add[2][3]; /* fixed point value. Top 8 bits are the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * integral part, bottom 8 bits are the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * fractional part. We only use the top
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * 9 bits as the resolution is only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * to the 0.5 degree C...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * two sensors with three values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * (cur, over, hyst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) /* PWMs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) u8 pwm[5]; /* pwm duty cycle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) u8 pwm_enable[3]; /* pwm enable status for fan 1-3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * (fan 4-5 only support manual mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) u8 temp_target[3]; /* pwm 1-3 target temperature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) u8 temp_tolerance[3]; /* pwm 1-3 temperature tolerance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* Misc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) u32 alarms; /* realtime status register encoding,combined */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) u8 beep_enable; /* Global beep enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) u32 beep_mask; /* Mask off specific beeps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) u8 vid; /* Register encoding, combined */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) u8 vrm; /* hwmon-vid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static int w83791d_probe(struct i2c_client *client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static int w83791d_detect(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct i2c_board_info *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static int w83791d_remove(struct i2c_client *client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static int w83791d_read(struct i2c_client *client, u8 reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static struct w83791d_data *w83791d_update_device(struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static void w83791d_print_debug(struct w83791d_data *data, struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static void w83791d_init_client(struct i2c_client *client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static const struct i2c_device_id w83791d_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) { "w83791d", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) MODULE_DEVICE_TABLE(i2c, w83791d_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) static struct i2c_driver w83791d_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) .class = I2C_CLASS_HWMON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) .name = "w83791d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) .probe_new = w83791d_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) .remove = w83791d_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) .id_table = w83791d_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) .detect = w83791d_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) .address_list = normal_i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /* following are the sysfs callback functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) #define show_in_reg(reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct sensor_device_attribute *sensor_attr = \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) to_sensor_dev_attr(attr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct w83791d_data *data = w83791d_update_device(dev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) int nr = sensor_attr->index; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return sprintf(buf, "%d\n", IN_FROM_REG(data->reg[nr])); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) show_in_reg(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) show_in_reg(in_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) show_in_reg(in_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) #define store_in_reg(REG, reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static ssize_t store_in_##reg(struct device *dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct device_attribute *attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) const char *buf, size_t count) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct sensor_device_attribute *sensor_attr = \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) to_sensor_dev_attr(attr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct i2c_client *client = to_i2c_client(dev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) struct w83791d_data *data = i2c_get_clientdata(client); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) int nr = sensor_attr->index; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) unsigned long val; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) int err = kstrtoul(buf, 10, &val); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (err) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return err; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) mutex_lock(&data->update_lock); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) data->in_##reg[nr] = IN_TO_REG(val); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) w83791d_write(client, W83791D_REG_IN_##REG[nr], data->in_##reg[nr]); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) mutex_unlock(&data->update_lock); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return count; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) store_in_reg(MIN, min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) store_in_reg(MAX, max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static struct sensor_device_attribute sda_in_input[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) SENSOR_ATTR(in9_input, S_IRUGO, show_in, NULL, 9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) static struct sensor_device_attribute sda_in_min[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) SENSOR_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) SENSOR_ATTR(in3_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) SENSOR_ATTR(in4_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) SENSOR_ATTR(in5_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) SENSOR_ATTR(in6_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) SENSOR_ATTR(in7_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) SENSOR_ATTR(in8_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) SENSOR_ATTR(in9_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static struct sensor_device_attribute sda_in_max[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) SENSOR_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) SENSOR_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) SENSOR_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) SENSOR_ATTR(in3_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) SENSOR_ATTR(in4_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) SENSOR_ATTR(in5_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) SENSOR_ATTR(in6_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) SENSOR_ATTR(in7_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) SENSOR_ATTR(in8_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) static ssize_t show_beep(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) struct sensor_device_attribute *sensor_attr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct w83791d_data *data = w83791d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) int bitnr = sensor_attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return sprintf(buf, "%d\n", (data->beep_mask >> bitnr) & 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) static ssize_t store_beep(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct sensor_device_attribute *sensor_attr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct w83791d_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) int bitnr = sensor_attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) int bytenr = bitnr / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) val = val ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) data->beep_mask &= ~(0xff << (bytenr * 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) data->beep_mask |= w83791d_read(client, W83791D_REG_BEEP_CTRL[bytenr])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) << (bytenr * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) data->beep_mask &= ~(1 << bitnr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) data->beep_mask |= val << bitnr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) w83791d_write(client, W83791D_REG_BEEP_CTRL[bytenr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) (data->beep_mask >> (bytenr * 8)) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct sensor_device_attribute *sensor_attr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) struct w83791d_data *data = w83791d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) int bitnr = sensor_attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * Note: The bitmask for the beep enable/disable is different than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * the bitmask for the alarm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) static struct sensor_device_attribute sda_in_beep[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) SENSOR_ATTR(in0_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) SENSOR_ATTR(in1_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 13),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) SENSOR_ATTR(in2_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) SENSOR_ATTR(in3_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) SENSOR_ATTR(in4_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) SENSOR_ATTR(in5_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) SENSOR_ATTR(in6_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) SENSOR_ATTR(in7_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) SENSOR_ATTR(in8_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 17),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) SENSOR_ATTR(in9_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) static struct sensor_device_attribute sda_in_alarm[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) SENSOR_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) SENSOR_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) SENSOR_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) SENSOR_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) SENSOR_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) SENSOR_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) SENSOR_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) SENSOR_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 19),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) SENSOR_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 20),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) SENSOR_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, 14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) #define show_fan_reg(reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) struct sensor_device_attribute *sensor_attr = \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) to_sensor_dev_attr(attr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) struct w83791d_data *data = w83791d_update_device(dev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) int nr = sensor_attr->index; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return sprintf(buf, "%d\n", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) FAN_FROM_REG(data->reg[nr], DIV_FROM_REG(data->fan_div[nr]))); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) show_fan_reg(fan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) show_fan_reg(fan_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) static ssize_t store_fan_min(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) struct w83791d_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) int nr = sensor_attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) data->fan_min[nr] = fan_to_reg(val, DIV_FROM_REG(data->fan_div[nr]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) w83791d_write(client, W83791D_REG_FAN_MIN[nr], data->fan_min[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) int nr = sensor_attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) struct w83791d_data *data = w83791d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return sprintf(buf, "%u\n", DIV_FROM_REG(data->fan_div[nr]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * Note: we save and restore the fan minimum here, because its value is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * determined in part by the fan divisor. This follows the principle of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * least surprise; the user doesn't expect the fan minimum to change just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * because the divisor changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) struct w83791d_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) int nr = sensor_attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) unsigned long min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) u8 tmp_fan_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) u8 fan_div_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) u8 vbat_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) int indx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) u8 keep_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) u8 new_shift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) /* Save fan_min */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) data->fan_div[nr] = div_to_reg(nr, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) switch (nr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) indx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) keep_mask = 0xcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) new_shift = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) indx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) keep_mask = 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) new_shift = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) indx = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) keep_mask = 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) new_shift = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) indx = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) keep_mask = 0xf8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) new_shift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) indx = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) keep_mask = 0x8f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) new_shift = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) dev_warn(dev, "store_fan_div: Unexpected nr seen: %d\n", nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) count = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) goto err_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) fan_div_reg = w83791d_read(client, W83791D_REG_FAN_DIV[indx])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) & keep_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) tmp_fan_div = (data->fan_div[nr] << new_shift) & ~keep_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) w83791d_write(client, W83791D_REG_FAN_DIV[indx],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) fan_div_reg | tmp_fan_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) /* Bit 2 of fans 0-2 is stored in the vbat register (bits 5-7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (nr < 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) keep_mask = ~(1 << (nr + 5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) vbat_reg = w83791d_read(client, W83791D_REG_VBAT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) & keep_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) tmp_fan_div = (data->fan_div[nr] << (3 + nr)) & ~keep_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) w83791d_write(client, W83791D_REG_VBAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) vbat_reg | tmp_fan_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) /* Restore fan_min */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) data->fan_min[nr] = fan_to_reg(min, DIV_FROM_REG(data->fan_div[nr]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) w83791d_write(client, W83791D_REG_FAN_MIN[nr], data->fan_min[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) err_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static struct sensor_device_attribute sda_fan_input[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) static struct sensor_device_attribute sda_fan_min[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) show_fan_min, store_fan_min, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) show_fan_min, store_fan_min, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) show_fan_min, store_fan_min, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) show_fan_min, store_fan_min, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) show_fan_min, store_fan_min, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static struct sensor_device_attribute sda_fan_div[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) SENSOR_ATTR(fan1_div, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) show_fan_div, store_fan_div, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) SENSOR_ATTR(fan2_div, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) show_fan_div, store_fan_div, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) SENSOR_ATTR(fan3_div, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) show_fan_div, store_fan_div, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) SENSOR_ATTR(fan4_div, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) show_fan_div, store_fan_div, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) SENSOR_ATTR(fan5_div, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) show_fan_div, store_fan_div, 4),
^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 struct sensor_device_attribute sda_fan_beep[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) SENSOR_ATTR(fan1_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) SENSOR_ATTR(fan2_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) SENSOR_ATTR(fan3_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 11),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) SENSOR_ATTR(fan4_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 21),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) SENSOR_ATTR(fan5_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 22),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) static struct sensor_device_attribute sda_fan_alarm[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) SENSOR_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) SENSOR_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) SENSOR_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) SENSOR_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 21),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 22),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) /* read/write PWMs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) int nr = sensor_attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct w83791d_data *data = w83791d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) return sprintf(buf, "%u\n", data->pwm[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) static ssize_t store_pwm(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) struct w83791d_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) int nr = sensor_attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (kstrtoul(buf, 10, &val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) data->pwm[nr] = clamp_val(val, 0, 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) w83791d_write(client, W83791D_REG_PWM[nr], data->pwm[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) static struct sensor_device_attribute sda_pwm[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) show_pwm, store_pwm, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) show_pwm, store_pwm, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) show_pwm, store_pwm, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) SENSOR_ATTR(pwm4, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) show_pwm, store_pwm, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) SENSOR_ATTR(pwm5, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) show_pwm, store_pwm, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) static ssize_t show_pwmenable(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) int nr = sensor_attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct w83791d_data *data = w83791d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) return sprintf(buf, "%u\n", data->pwm_enable[nr] + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) static ssize_t store_pwmenable(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) struct w83791d_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) int nr = sensor_attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) u8 reg_cfg_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) u8 reg_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) u8 val_shift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) u8 keep_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) int ret = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (ret || val < 1 || val > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) data->pwm_enable[nr] = val - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) switch (nr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) reg_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) val_shift = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) keep_mask = 0xf3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) reg_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) val_shift = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) keep_mask = 0xcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) reg_idx = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) val_shift = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) keep_mask = 0xf3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) reg_cfg_tmp = w83791d_read(client, W83791D_REG_FAN_CFG[reg_idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) reg_cfg_tmp = (reg_cfg_tmp & keep_mask) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) data->pwm_enable[nr] << val_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) w83791d_write(client, W83791D_REG_FAN_CFG[reg_idx], reg_cfg_tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) static struct sensor_device_attribute sda_pwmenable[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) SENSOR_ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) show_pwmenable, store_pwmenable, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) SENSOR_ATTR(pwm2_enable, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) show_pwmenable, store_pwmenable, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) SENSOR_ATTR(pwm3_enable, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) show_pwmenable, store_pwmenable, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) /* For Smart Fan I / Thermal Cruise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) static ssize_t show_temp_target(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) struct w83791d_data *data = w83791d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) int nr = sensor_attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp_target[nr]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) static ssize_t store_temp_target(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) struct w83791d_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) int nr = sensor_attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) u8 target_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (kstrtol(buf, 10, &val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) data->temp_target[nr] = TARGET_TEMP_TO_REG(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) target_mask = w83791d_read(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) W83791D_REG_TEMP_TARGET[nr]) & 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) w83791d_write(client, W83791D_REG_TEMP_TARGET[nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) data->temp_target[nr] | target_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) static struct sensor_device_attribute sda_temp_target[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) SENSOR_ATTR(temp1_target, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) show_temp_target, store_temp_target, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) SENSOR_ATTR(temp2_target, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) show_temp_target, store_temp_target, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) SENSOR_ATTR(temp3_target, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) show_temp_target, store_temp_target, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) static ssize_t show_temp_tolerance(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) struct w83791d_data *data = w83791d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) int nr = sensor_attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp_tolerance[nr]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) static ssize_t store_temp_tolerance(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) struct w83791d_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) int nr = sensor_attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) u8 target_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) u8 reg_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) u8 val_shift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) u8 keep_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (kstrtoul(buf, 10, &val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) switch (nr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) reg_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) val_shift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) keep_mask = 0xf0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) reg_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) val_shift = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) keep_mask = 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) reg_idx = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) val_shift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) keep_mask = 0xf0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) data->temp_tolerance[nr] = TOL_TEMP_TO_REG(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) target_mask = w83791d_read(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) W83791D_REG_TEMP_TOL[reg_idx]) & keep_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) w83791d_write(client, W83791D_REG_TEMP_TOL[reg_idx],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) (data->temp_tolerance[nr] << val_shift) | target_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) static struct sensor_device_attribute sda_temp_tolerance[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) SENSOR_ATTR(temp1_tolerance, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) show_temp_tolerance, store_temp_tolerance, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) SENSOR_ATTR(temp2_tolerance, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) show_temp_tolerance, store_temp_tolerance, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) SENSOR_ATTR(temp3_tolerance, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) show_temp_tolerance, store_temp_tolerance, 2),
^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) /* read/write the temperature1, includes measured value and limits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) static ssize_t show_temp1(struct device *dev, struct device_attribute *devattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) struct w83791d_data *data = w83791d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp1[attr->index]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) static ssize_t store_temp1(struct device *dev, struct device_attribute *devattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) struct w83791d_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) int nr = attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) err = kstrtol(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) data->temp1[nr] = TEMP1_TO_REG(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) w83791d_write(client, W83791D_REG_TEMP1[nr], data->temp1[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) return count;
^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) /* read/write temperature2-3, includes measured value and limits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) static ssize_t show_temp23(struct device *dev, struct device_attribute *devattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) struct w83791d_data *data = w83791d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) int nr = attr->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) int index = attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) return sprintf(buf, "%d\n", TEMP23_FROM_REG(data->temp_add[nr][index]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) static ssize_t store_temp23(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) struct device_attribute *devattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) struct w83791d_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) int nr = attr->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) int index = attr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) err = kstrtol(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) data->temp_add[nr][index] = TEMP23_TO_REG(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) w83791d_write(client, W83791D_REG_TEMP_ADD[nr][index * 2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) data->temp_add[nr][index] >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) w83791d_write(client, W83791D_REG_TEMP_ADD[nr][index * 2 + 1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) data->temp_add[nr][index] & 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) static struct sensor_device_attribute_2 sda_temp_input[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp1, NULL, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp23, NULL, 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp23, NULL, 1, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) static struct sensor_device_attribute_2 sda_temp_max[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) SENSOR_ATTR_2(temp1_max, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) show_temp1, store_temp1, 0, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) SENSOR_ATTR_2(temp2_max, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) show_temp23, store_temp23, 0, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) SENSOR_ATTR_2(temp3_max, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) show_temp23, store_temp23, 1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) static struct sensor_device_attribute_2 sda_temp_max_hyst[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) show_temp1, store_temp1, 0, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) show_temp23, store_temp23, 0, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) show_temp23, store_temp23, 1, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) * Note: The bitmask for the beep enable/disable is different than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) * the bitmask for the alarm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) static struct sensor_device_attribute sda_temp_beep[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) SENSOR_ATTR(temp1_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) SENSOR_ATTR(temp2_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) SENSOR_ATTR(temp3_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) static struct sensor_device_attribute sda_temp_alarm[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) /* get realtime status of all sensors items: voltage, temp, fan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) static ssize_t alarms_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) struct w83791d_data *data = w83791d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) return sprintf(buf, "%u\n", data->alarms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) static DEVICE_ATTR_RO(alarms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) /* Beep control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) #define GLOBAL_BEEP_ENABLE_SHIFT 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) #define GLOBAL_BEEP_ENABLE_MASK (1 << GLOBAL_BEEP_ENABLE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) static ssize_t show_beep_enable(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) struct w83791d_data *data = w83791d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) return sprintf(buf, "%d\n", data->beep_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) static ssize_t show_beep_mask(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) struct w83791d_data *data = w83791d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) return sprintf(buf, "%d\n", BEEP_MASK_FROM_REG(data->beep_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) static ssize_t store_beep_mask(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) struct w83791d_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) err = kstrtol(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) * The beep_enable state overrides any enabling request from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) * the masks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) data->beep_mask = BEEP_MASK_TO_REG(val) & ~GLOBAL_BEEP_ENABLE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) data->beep_mask |= (data->beep_enable << GLOBAL_BEEP_ENABLE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) val = data->beep_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) for (i = 0; i < 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) w83791d_write(client, W83791D_REG_BEEP_CTRL[i], (val & 0xff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) val >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) static ssize_t store_beep_enable(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) struct w83791d_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) err = kstrtol(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) data->beep_enable = val ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) /* Keep the full mask value in sync with the current enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) data->beep_mask &= ~GLOBAL_BEEP_ENABLE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) data->beep_mask |= (data->beep_enable << GLOBAL_BEEP_ENABLE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) * The global control is in the second beep control register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) * so only need to update that register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) val = (data->beep_mask >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) w83791d_write(client, W83791D_REG_BEEP_CTRL[1], val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) static struct sensor_device_attribute sda_beep_ctrl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) SENSOR_ATTR(beep_enable, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) show_beep_enable, store_beep_enable, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) SENSOR_ATTR(beep_mask, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) show_beep_mask, store_beep_mask, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) /* cpu voltage regulation information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) static ssize_t cpu0_vid_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) struct w83791d_data *data = w83791d_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) static DEVICE_ATTR_RO(cpu0_vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) static ssize_t vrm_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) struct w83791d_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) return sprintf(buf, "%d\n", data->vrm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) static ssize_t vrm_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) struct w83791d_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) * No lock needed as vrm is internal to the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) * (not read from a chip register) and so is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) * updated in w83791d_update_device()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) if (val > 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) data->vrm = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) static DEVICE_ATTR_RW(vrm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) #define IN_UNIT_ATTRS(X) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) &sda_in_input[X].dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) &sda_in_min[X].dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) &sda_in_max[X].dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) &sda_in_beep[X].dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) &sda_in_alarm[X].dev_attr.attr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) #define FAN_UNIT_ATTRS(X) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) &sda_fan_input[X].dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) &sda_fan_min[X].dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) &sda_fan_div[X].dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) &sda_fan_beep[X].dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) &sda_fan_alarm[X].dev_attr.attr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) #define TEMP_UNIT_ATTRS(X) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) &sda_temp_input[X].dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) &sda_temp_max[X].dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) &sda_temp_max_hyst[X].dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) &sda_temp_beep[X].dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) &sda_temp_alarm[X].dev_attr.attr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) static struct attribute *w83791d_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) IN_UNIT_ATTRS(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) IN_UNIT_ATTRS(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) IN_UNIT_ATTRS(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) IN_UNIT_ATTRS(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) IN_UNIT_ATTRS(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) IN_UNIT_ATTRS(5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) IN_UNIT_ATTRS(6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) IN_UNIT_ATTRS(7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) IN_UNIT_ATTRS(8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) IN_UNIT_ATTRS(9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) FAN_UNIT_ATTRS(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) FAN_UNIT_ATTRS(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) FAN_UNIT_ATTRS(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) TEMP_UNIT_ATTRS(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) TEMP_UNIT_ATTRS(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) TEMP_UNIT_ATTRS(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) &dev_attr_alarms.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) &sda_beep_ctrl[0].dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) &sda_beep_ctrl[1].dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) &dev_attr_cpu0_vid.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) &dev_attr_vrm.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) &sda_pwm[0].dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) &sda_pwm[1].dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) &sda_pwm[2].dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) &sda_pwmenable[0].dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) &sda_pwmenable[1].dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) &sda_pwmenable[2].dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) &sda_temp_target[0].dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) &sda_temp_target[1].dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) &sda_temp_target[2].dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) &sda_temp_tolerance[0].dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) &sda_temp_tolerance[1].dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) &sda_temp_tolerance[2].dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) static const struct attribute_group w83791d_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) .attrs = w83791d_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) * Separate group of attributes for fan/pwm 4-5. Their pins can also be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) * in use for GPIO in which case their sysfs-interface should not be made
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) * available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) static struct attribute *w83791d_attributes_fanpwm45[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) FAN_UNIT_ATTRS(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) FAN_UNIT_ATTRS(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) &sda_pwm[3].dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) &sda_pwm[4].dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) static const struct attribute_group w83791d_group_fanpwm45 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) .attrs = w83791d_attributes_fanpwm45,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) static int w83791d_detect_subclients(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) struct i2c_adapter *adapter = client->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) int address = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) int i, id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) id = i2c_adapter_id(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) if (force_subclients[0] == id && force_subclients[1] == address) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) for (i = 2; i <= 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) if (force_subclients[i] < 0x48 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) force_subclients[i] > 0x4f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) "invalid subclient "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) "address %d; must be 0x48-0x4f\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) force_subclients[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) w83791d_write(client, W83791D_REG_I2C_SUBADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) (force_subclients[2] & 0x07) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) ((force_subclients[3] & 0x07) << 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) val = w83791d_read(client, W83791D_REG_I2C_SUBADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) if (!(val & 0x88) && (val & 0x7) == ((val >> 4) & 0x7)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) "duplicate addresses 0x%x, use force_subclient\n", 0x48 + (val & 0x7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) if (!(val & 0x08))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) devm_i2c_new_dummy_device(&client->dev, adapter, 0x48 + (val & 0x7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) if (!(val & 0x80))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) devm_i2c_new_dummy_device(&client->dev, adapter, 0x48 + ((val >> 4) & 0x7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) /* Return 0 if detection is successful, -ENODEV otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) static int w83791d_detect(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) struct i2c_board_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) struct i2c_adapter *adapter = client->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) int val1, val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) unsigned short address = client->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) if (w83791d_read(client, W83791D_REG_CONFIG) & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) val1 = w83791d_read(client, W83791D_REG_BANK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) val2 = w83791d_read(client, W83791D_REG_CHIPMAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) /* Check for Winbond ID if in bank 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) if (!(val1 & 0x07)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) if ((!(val1 & 0x80) && val2 != 0xa3) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) ((val1 & 0x80) && val2 != 0x5c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) * If Winbond chip, address of chip and W83791D_REG_I2C_ADDR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) * should match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) if (w83791d_read(client, W83791D_REG_I2C_ADDR) != address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) /* We want bank 0 and Vendor ID high byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) val1 = w83791d_read(client, W83791D_REG_BANK) & 0x78;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) w83791d_write(client, W83791D_REG_BANK, val1 | 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) /* Verify it is a Winbond w83791d */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) val1 = w83791d_read(client, W83791D_REG_WCHIPID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) val2 = w83791d_read(client, W83791D_REG_CHIPMAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) if (val1 != 0x71 || val2 != 0x5c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) strlcpy(info->type, "w83791d", I2C_NAME_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) static int w83791d_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) struct w83791d_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) u8 has_fanpwm45;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) int val1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) val1 = w83791d_read(client, W83791D_REG_DID_VID4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) dev_dbg(dev, "Device ID version: %d.%d (0x%02x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) (val1 >> 5) & 0x07, (val1 >> 1) & 0x0f, val1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) data = devm_kzalloc(&client->dev, sizeof(struct w83791d_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) i2c_set_clientdata(client, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) mutex_init(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) err = w83791d_detect_subclients(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) /* Initialize the chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) w83791d_init_client(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) * If the fan_div is changed, make sure there is a rational
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) * fan_min in place
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) for (i = 0; i < NUMBER_OF_FANIN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) data->fan_min[i] = w83791d_read(client, W83791D_REG_FAN_MIN[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) /* Register sysfs hooks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) err = sysfs_create_group(&client->dev.kobj, &w83791d_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) /* Check if pins of fan/pwm 4-5 are in use as GPIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) has_fanpwm45 = w83791d_read(client, W83791D_REG_GPIO) & 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) if (has_fanpwm45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) err = sysfs_create_group(&client->dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) &w83791d_group_fanpwm45);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) goto error4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) /* Everything is ready, now register the working device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) data->hwmon_dev = hwmon_device_register(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) if (IS_ERR(data->hwmon_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) err = PTR_ERR(data->hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) goto error5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) error5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) if (has_fanpwm45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) sysfs_remove_group(&client->dev.kobj, &w83791d_group_fanpwm45);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) error4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) sysfs_remove_group(&client->dev.kobj, &w83791d_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) static int w83791d_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) struct w83791d_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) hwmon_device_unregister(data->hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) sysfs_remove_group(&client->dev.kobj, &w83791d_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) static void w83791d_init_client(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) struct w83791d_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) u8 old_beep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) * The difference between reset and init is that reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) * does a hard reset of the chip via index 0x40, bit 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) * but init simply forces certain registers to have "sane"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) * values. The hope is that the BIOS has done the right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) * thing (which is why the default is reset=0, init=0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) * but if not, reset is the hard hammer and init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) * is the soft mallet both of which are trying to whack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) * things into place...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) * NOTE: The data sheet makes a distinction between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) * "power on defaults" and "reset by MR". As far as I can tell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) * the hard reset puts everything into a power-on state so I'm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) * not sure what "reset by MR" means or how it can happen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) if (reset || init) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) /* keep some BIOS settings when we... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) old_beep = w83791d_read(client, W83791D_REG_BEEP_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) if (reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) /* ... reset the chip and ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) w83791d_write(client, W83791D_REG_CONFIG, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) /* ... disable power-on abnormal beep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) w83791d_write(client, W83791D_REG_BEEP_CONFIG, old_beep | 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) /* disable the global beep (not done by hard reset) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) tmp = w83791d_read(client, W83791D_REG_BEEP_CTRL[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) w83791d_write(client, W83791D_REG_BEEP_CTRL[1], tmp & 0xef);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) if (init) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) /* Make sure monitoring is turned on for add-ons */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) tmp = w83791d_read(client, W83791D_REG_TEMP2_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) if (tmp & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) w83791d_write(client, W83791D_REG_TEMP2_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) tmp & 0xfe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) tmp = w83791d_read(client, W83791D_REG_TEMP3_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) if (tmp & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) w83791d_write(client, W83791D_REG_TEMP3_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) tmp & 0xfe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) /* Start monitoring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) tmp = w83791d_read(client, W83791D_REG_CONFIG) & 0xf7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) w83791d_write(client, W83791D_REG_CONFIG, tmp | 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) data->vrm = vid_which_vrm();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) static struct w83791d_data *w83791d_update_device(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) struct w83791d_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) u8 reg_array_tmp[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) u8 vbat_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) if (time_after(jiffies, data->last_updated + (HZ * 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) || !data->valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) dev_dbg(dev, "Starting w83791d device update\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) /* Update the voltages measured value and limits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) for (i = 0; i < NUMBER_OF_VIN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) data->in[i] = w83791d_read(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) W83791D_REG_IN[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) data->in_max[i] = w83791d_read(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) W83791D_REG_IN_MAX[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) data->in_min[i] = w83791d_read(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) W83791D_REG_IN_MIN[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) /* Update the fan counts and limits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) for (i = 0; i < NUMBER_OF_FANIN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) /* Update the Fan measured value and limits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) data->fan[i] = w83791d_read(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) W83791D_REG_FAN[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) data->fan_min[i] = w83791d_read(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) W83791D_REG_FAN_MIN[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) /* Update the fan divisor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) for (i = 0; i < 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) reg_array_tmp[i] = w83791d_read(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) W83791D_REG_FAN_DIV[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) data->fan_div[0] = (reg_array_tmp[0] >> 4) & 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) data->fan_div[1] = (reg_array_tmp[0] >> 6) & 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) data->fan_div[2] = (reg_array_tmp[1] >> 6) & 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) data->fan_div[3] = reg_array_tmp[2] & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) data->fan_div[4] = (reg_array_tmp[2] >> 4) & 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) * The fan divisor for fans 0-2 get bit 2 from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) * bits 5-7 respectively of vbat register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) vbat_reg = w83791d_read(client, W83791D_REG_VBAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) for (i = 0; i < 3; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) data->fan_div[i] |= (vbat_reg >> (3 + i)) & 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) /* Update PWM duty cycle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) for (i = 0; i < NUMBER_OF_PWM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) data->pwm[i] = w83791d_read(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) W83791D_REG_PWM[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) /* Update PWM enable status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) reg_array_tmp[i] = w83791d_read(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) W83791D_REG_FAN_CFG[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) data->pwm_enable[0] = (reg_array_tmp[0] >> 2) & 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) data->pwm_enable[1] = (reg_array_tmp[0] >> 4) & 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) data->pwm_enable[2] = (reg_array_tmp[1] >> 2) & 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) /* Update PWM target temperature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) for (i = 0; i < 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) data->temp_target[i] = w83791d_read(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) W83791D_REG_TEMP_TARGET[i]) & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) /* Update PWM temperature tolerance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) reg_array_tmp[i] = w83791d_read(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) W83791D_REG_TEMP_TOL[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) data->temp_tolerance[0] = reg_array_tmp[0] & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) data->temp_tolerance[1] = (reg_array_tmp[0] >> 4) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) data->temp_tolerance[2] = reg_array_tmp[1] & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) /* Update the first temperature sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) for (i = 0; i < 3; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) data->temp1[i] = w83791d_read(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) W83791D_REG_TEMP1[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) /* Update the rest of the temperature sensors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) for (j = 0; j < 3; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) data->temp_add[i][j] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) (w83791d_read(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) W83791D_REG_TEMP_ADD[i][j * 2]) << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) w83791d_read(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) W83791D_REG_TEMP_ADD[i][j * 2 + 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) /* Update the realtime status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) data->alarms =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) w83791d_read(client, W83791D_REG_ALARM1) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) (w83791d_read(client, W83791D_REG_ALARM2) << 8) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) (w83791d_read(client, W83791D_REG_ALARM3) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) /* Update the beep configuration information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) data->beep_mask =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) w83791d_read(client, W83791D_REG_BEEP_CTRL[0]) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) (w83791d_read(client, W83791D_REG_BEEP_CTRL[1]) << 8) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) (w83791d_read(client, W83791D_REG_BEEP_CTRL[2]) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) /* Extract global beep enable flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) data->beep_enable =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) (data->beep_mask >> GLOBAL_BEEP_ENABLE_SHIFT) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) /* Update the cpu voltage information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) i = w83791d_read(client, W83791D_REG_VID_FANDIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) data->vid = i & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) data->vid |= (w83791d_read(client, W83791D_REG_DID_VID4) & 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) data->last_updated = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) data->valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) w83791d_print_debug(data, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) static void w83791d_print_debug(struct w83791d_data *data, struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) int i = 0, j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) dev_dbg(dev, "======Start of w83791d debug values======\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) dev_dbg(dev, "%d set of Voltages: ===>\n", NUMBER_OF_VIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) for (i = 0; i < NUMBER_OF_VIN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) dev_dbg(dev, "vin[%d] is: 0x%02x\n", i, data->in[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) dev_dbg(dev, "vin[%d] min is: 0x%02x\n", i, data->in_min[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) dev_dbg(dev, "vin[%d] max is: 0x%02x\n", i, data->in_max[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) dev_dbg(dev, "%d set of Fan Counts/Divisors: ===>\n", NUMBER_OF_FANIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) for (i = 0; i < NUMBER_OF_FANIN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) dev_dbg(dev, "fan[%d] is: 0x%02x\n", i, data->fan[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) dev_dbg(dev, "fan[%d] min is: 0x%02x\n", i, data->fan_min[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) dev_dbg(dev, "fan_div[%d] is: 0x%02x\n", i, data->fan_div[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) * temperature math is signed, but only print out the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) * bits that matter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) dev_dbg(dev, "%d set of Temperatures: ===>\n", NUMBER_OF_TEMPIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) for (i = 0; i < 3; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) dev_dbg(dev, "temp1[%d] is: 0x%02x\n", i, (u8) data->temp1[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) for (j = 0; j < 3; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) dev_dbg(dev, "temp_add[%d][%d] is: 0x%04x\n", i, j,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) (u16) data->temp_add[i][j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) dev_dbg(dev, "Misc Information: ===>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) dev_dbg(dev, "alarm is: 0x%08x\n", data->alarms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) dev_dbg(dev, "beep_mask is: 0x%08x\n", data->beep_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) dev_dbg(dev, "beep_enable is: %d\n", data->beep_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) dev_dbg(dev, "vid is: 0x%02x\n", data->vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) dev_dbg(dev, "vrm is: 0x%02x\n", data->vrm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) dev_dbg(dev, "=======End of w83791d debug values========\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) dev_dbg(dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) module_i2c_driver(w83791d_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) MODULE_AUTHOR("Charles Spirakis <bezaur@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) MODULE_DESCRIPTION("W83791D driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) MODULE_LICENSE("GPL");