^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) * vt1211.c - driver for the VIA VT1211 Super-I/O chip integrated hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * monitoring features
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2006 Juerg Haefliger <juergh@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * This driver is based on the driver for kernel 2.4 by Mark D. Studebaker
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * and its port to kernel 2.6 by Lars Ekman.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/hwmon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/hwmon-sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/hwmon-vid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static int uch_config = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) module_param(uch_config, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) MODULE_PARM_DESC(uch_config, "Initialize the universal channel configuration");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static int int_mode = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) module_param(int_mode, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) MODULE_PARM_DESC(int_mode, "Force the temperature interrupt mode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static unsigned short force_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) module_param(force_id, ushort, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) MODULE_PARM_DESC(force_id, "Override the detected device ID");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define DRVNAME "vt1211"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* ---------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * Registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * The sensors are defined as follows.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * Sensor Voltage Mode Temp Mode Notes (from the datasheet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * -------- ------------ --------- --------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * Reading 1 temp1 Intel thermal diode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * Reading 3 temp2 Internal thermal diode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * UCH1/Reading2 in0 temp3 NTC type thermistor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * UCH2 in1 temp4 +2.5V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * UCH3 in2 temp5 VccP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * UCH4 in3 temp6 +5V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * UCH5 in4 temp7 +12V
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * 3.3V in5 Internal VDD (+3.3V)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * --------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* Voltages (in) numbered 0-5 (ix) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define VT1211_REG_IN(ix) (0x21 + (ix))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define VT1211_REG_IN_MIN(ix) ((ix) == 0 ? 0x3e : 0x2a + 2 * (ix))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define VT1211_REG_IN_MAX(ix) ((ix) == 0 ? 0x3d : 0x29 + 2 * (ix))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* Temperatures (temp) numbered 0-6 (ix) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static u8 regtemp[] = {0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static u8 regtempmax[] = {0x39, 0x1d, 0x3d, 0x2b, 0x2d, 0x2f, 0x31};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static u8 regtemphyst[] = {0x3a, 0x1e, 0x3e, 0x2c, 0x2e, 0x30, 0x32};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* Fans numbered 0-1 (ix) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define VT1211_REG_FAN(ix) (0x29 + (ix))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define VT1211_REG_FAN_MIN(ix) (0x3b + (ix))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define VT1211_REG_FAN_DIV 0x47
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* PWMs numbered 0-1 (ix) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* Auto points numbered 0-3 (ap) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define VT1211_REG_PWM(ix) (0x60 + (ix))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define VT1211_REG_PWM_CLK 0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define VT1211_REG_PWM_CTL 0x51
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define VT1211_REG_PWM_AUTO_TEMP(ap) (0x55 - (ap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define VT1211_REG_PWM_AUTO_PWM(ix, ap) (0x58 + 2 * (ix) - (ap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* Miscellaneous registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define VT1211_REG_CONFIG 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define VT1211_REG_ALARM1 0x41
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define VT1211_REG_ALARM2 0x42
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define VT1211_REG_VID 0x45
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define VT1211_REG_UCH_CONFIG 0x4a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define VT1211_REG_TEMP1_CONFIG 0x4b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define VT1211_REG_TEMP2_CONFIG 0x4c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* In, temp & fan alarm bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static const u8 bitalarmin[] = {11, 0, 1, 3, 8, 2, 9};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static const u8 bitalarmtemp[] = {4, 15, 11, 0, 1, 3, 8};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static const u8 bitalarmfan[] = {6, 7};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* ---------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * Data structures and manipulation thereof
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * --------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct vt1211_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) unsigned short addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct device *hwmon_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct mutex update_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) char valid; /* !=0 if following fields are valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) unsigned long last_updated; /* In jiffies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* Register values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) u8 in[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) u8 in_max[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) u8 in_min[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) u8 temp[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) u8 temp_max[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) u8 temp_hyst[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) u8 fan[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u8 fan_min[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) u8 fan_div[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) u8 fan_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) u8 pwm[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) u8 pwm_ctl[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) u8 pwm_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) u8 pwm_auto_temp[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) u8 pwm_auto_pwm[2][4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) u8 vid; /* Read once at init time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) u8 vrm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) u8 uch_config; /* Read once at init time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) u16 alarms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* ix = [0-5] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define ISVOLT(ix, uch_config) ((ix) > 4 ? 1 : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) !(((uch_config) >> ((ix) + 2)) & 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* ix = [0-6] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define ISTEMP(ix, uch_config) ((ix) < 2 ? 1 : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ((uch_config) >> (ix)) & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * in5 (ix = 5) is special. It's the internal 3.3V so it's scaled in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * driver according to the VT1211 BIOS porting guide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define IN_FROM_REG(ix, reg) ((reg) < 3 ? 0 : (ix) == 5 ? \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) (((reg) - 3) * 15882 + 479) / 958 : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) (((reg) - 3) * 10000 + 479) / 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define IN_TO_REG(ix, val) (clamp_val((ix) == 5 ? \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) ((val) * 958 + 7941) / 15882 + 3 : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) ((val) * 958 + 5000) / 10000 + 3, 0, 255))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * temp1 (ix = 0) is an intel thermal diode which is scaled in user space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * temp2 (ix = 1) is the internal temp diode so it's scaled in the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * according to some measurements that I took on an EPIA M10000.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * temp3-7 are thermistor based so the driver returns the voltage measured at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * the pin (range 0V - 2.2V).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define TEMP_FROM_REG(ix, reg) ((ix) == 0 ? (reg) * 1000 : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) (ix) == 1 ? (reg) < 51 ? 0 : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ((reg) - 51) * 1000 : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ((253 - (reg)) * 2200 + 105) / 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define TEMP_TO_REG(ix, val) clamp_val( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) ((ix) == 0 ? ((val) + 500) / 1000 : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) (ix) == 1 ? ((val) + 500) / 1000 + 51 : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 253 - ((val) * 210 + 1100) / 2200), 0, 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define DIV_FROM_REG(reg) (1 << (reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define RPM_FROM_REG(reg, div) (((reg) == 0) || ((reg) == 255) ? 0 : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 1310720 / (reg) / DIV_FROM_REG(div))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define RPM_TO_REG(val, div) ((val) == 0 ? 255 : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) clamp_val((1310720 / (val) / \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) DIV_FROM_REG(div)), 1, 254))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /* ---------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * Super-I/O constants and functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * --------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * Configuration index port registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * The vt1211 can live at 2 different addresses so we need to probe both
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define SIO_REG_CIP1 0x2e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define SIO_REG_CIP2 0x4e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* Configuration registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #define SIO_VT1211_LDN 0x07 /* logical device number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #define SIO_VT1211_DEVID 0x20 /* device ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define SIO_VT1211_DEVREV 0x21 /* device revision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define SIO_VT1211_ACTIVE 0x30 /* HW monitor active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #define SIO_VT1211_BADDR 0x60 /* base I/O address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #define SIO_VT1211_ID 0x3c /* VT1211 device ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /* VT1211 logical device numbers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #define SIO_VT1211_LDN_HWMON 0x0b /* HW monitor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static inline void superio_outb(int sio_cip, int reg, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) outb(reg, sio_cip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) outb(val, sio_cip + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static inline int superio_inb(int sio_cip, int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) outb(reg, sio_cip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return inb(sio_cip + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static inline void superio_select(int sio_cip, int ldn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) outb(SIO_VT1211_LDN, sio_cip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) outb(ldn, sio_cip + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static inline int superio_enter(int sio_cip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (!request_muxed_region(sio_cip, 2, DRVNAME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) outb(0x87, sio_cip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) outb(0x87, sio_cip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static inline void superio_exit(int sio_cip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) outb(0xaa, sio_cip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) release_region(sio_cip, 2);
^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) /* ---------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * Device I/O access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * --------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static inline u8 vt1211_read8(struct vt1211_data *data, u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return inb(data->addr + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static inline void vt1211_write8(struct vt1211_data *data, u8 reg, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) outb(val, data->addr + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static struct vt1211_data *vt1211_update_device(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct vt1211_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int ix, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /* registers cache is refreshed after 1 second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* read VID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) data->vid = vt1211_read8(data, VT1211_REG_VID) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /* voltage (in) registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) for (ix = 0; ix < ARRAY_SIZE(data->in); ix++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (ISVOLT(ix, data->uch_config)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) data->in[ix] = vt1211_read8(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) VT1211_REG_IN(ix));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) data->in_min[ix] = vt1211_read8(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) VT1211_REG_IN_MIN(ix));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) data->in_max[ix] = vt1211_read8(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) VT1211_REG_IN_MAX(ix));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* temp registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) for (ix = 0; ix < ARRAY_SIZE(data->temp); ix++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (ISTEMP(ix, data->uch_config)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) data->temp[ix] = vt1211_read8(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) regtemp[ix]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) data->temp_max[ix] = vt1211_read8(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) regtempmax[ix]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) data->temp_hyst[ix] = vt1211_read8(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) regtemphyst[ix]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /* fan & pwm registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) for (ix = 0; ix < ARRAY_SIZE(data->fan); ix++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) data->fan[ix] = vt1211_read8(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) VT1211_REG_FAN(ix));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) data->fan_min[ix] = vt1211_read8(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) VT1211_REG_FAN_MIN(ix));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) data->pwm[ix] = vt1211_read8(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) VT1211_REG_PWM(ix));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) val = vt1211_read8(data, VT1211_REG_FAN_DIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) data->fan_div[0] = (val >> 4) & 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) data->fan_div[1] = (val >> 6) & 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) data->fan_ctl = val & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) val = vt1211_read8(data, VT1211_REG_PWM_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) data->pwm_ctl[0] = val & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) data->pwm_ctl[1] = (val >> 4) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) data->pwm_clk = vt1211_read8(data, VT1211_REG_PWM_CLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /* pwm & temp auto point registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) data->pwm_auto_pwm[0][1] = vt1211_read8(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) VT1211_REG_PWM_AUTO_PWM(0, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) data->pwm_auto_pwm[0][2] = vt1211_read8(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) VT1211_REG_PWM_AUTO_PWM(0, 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) data->pwm_auto_pwm[1][1] = vt1211_read8(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) VT1211_REG_PWM_AUTO_PWM(1, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) data->pwm_auto_pwm[1][2] = vt1211_read8(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) VT1211_REG_PWM_AUTO_PWM(1, 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) for (ix = 0; ix < ARRAY_SIZE(data->pwm_auto_temp); ix++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) data->pwm_auto_temp[ix] = vt1211_read8(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) VT1211_REG_PWM_AUTO_TEMP(ix));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* alarm registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) data->alarms = (vt1211_read8(data, VT1211_REG_ALARM2) << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) vt1211_read8(data, VT1211_REG_ALARM1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) data->last_updated = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) data->valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) /* ---------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * Voltage sysfs interfaces
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) * ix = [0-5]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * --------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) #define SHOW_IN_INPUT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) #define SHOW_SET_IN_MIN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) #define SHOW_SET_IN_MAX 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) #define SHOW_IN_ALARM 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static ssize_t show_in(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) struct vt1211_data *data = vt1211_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) struct sensor_device_attribute_2 *sensor_attr_2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) int ix = sensor_attr_2->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) int fn = sensor_attr_2->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) switch (fn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) case SHOW_IN_INPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) res = IN_FROM_REG(ix, data->in[ix]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) case SHOW_SET_IN_MIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) res = IN_FROM_REG(ix, data->in_min[ix]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) case SHOW_SET_IN_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) res = IN_FROM_REG(ix, data->in_max[ix]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) case SHOW_IN_ALARM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) res = (data->alarms >> bitalarmin[ix]) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) dev_dbg(dev, "Unknown attr fetch (%d)\n", fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return sprintf(buf, "%d\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static ssize_t set_in(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) struct vt1211_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) struct sensor_device_attribute_2 *sensor_attr_2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) int ix = sensor_attr_2->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) int fn = sensor_attr_2->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) err = kstrtol(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) switch (fn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) case SHOW_SET_IN_MIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) data->in_min[ix] = IN_TO_REG(ix, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) vt1211_write8(data, VT1211_REG_IN_MIN(ix), data->in_min[ix]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) case SHOW_SET_IN_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) data->in_max[ix] = IN_TO_REG(ix, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) vt1211_write8(data, VT1211_REG_IN_MAX(ix), data->in_max[ix]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) dev_dbg(dev, "Unknown attr fetch (%d)\n", fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) /* ---------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * Temperature sysfs interfaces
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * ix = [0-6]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * --------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) #define SHOW_TEMP_INPUT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) #define SHOW_SET_TEMP_MAX 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) #define SHOW_SET_TEMP_MAX_HYST 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) #define SHOW_TEMP_ALARM 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) struct vt1211_data *data = vt1211_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) struct sensor_device_attribute_2 *sensor_attr_2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) int ix = sensor_attr_2->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) int fn = sensor_attr_2->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) switch (fn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) case SHOW_TEMP_INPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) res = TEMP_FROM_REG(ix, data->temp[ix]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) case SHOW_SET_TEMP_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) res = TEMP_FROM_REG(ix, data->temp_max[ix]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) case SHOW_SET_TEMP_MAX_HYST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) res = TEMP_FROM_REG(ix, data->temp_hyst[ix]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) case SHOW_TEMP_ALARM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) res = (data->alarms >> bitalarmtemp[ix]) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) dev_dbg(dev, "Unknown attr fetch (%d)\n", fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return sprintf(buf, "%d\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct vt1211_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) struct sensor_device_attribute_2 *sensor_attr_2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) int ix = sensor_attr_2->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) int fn = sensor_attr_2->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) err = kstrtol(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) switch (fn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) case SHOW_SET_TEMP_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) data->temp_max[ix] = TEMP_TO_REG(ix, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) vt1211_write8(data, regtempmax[ix],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) data->temp_max[ix]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) case SHOW_SET_TEMP_MAX_HYST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) data->temp_hyst[ix] = TEMP_TO_REG(ix, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) vt1211_write8(data, regtemphyst[ix],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) data->temp_hyst[ix]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) dev_dbg(dev, "Unknown attr fetch (%d)\n", fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) /* ---------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * Fan sysfs interfaces
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * ix = [0-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) #define SHOW_FAN_INPUT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) #define SHOW_SET_FAN_MIN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) #define SHOW_SET_FAN_DIV 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) #define SHOW_FAN_ALARM 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct vt1211_data *data = vt1211_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) struct sensor_device_attribute_2 *sensor_attr_2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) int ix = sensor_attr_2->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) int fn = sensor_attr_2->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) switch (fn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) case SHOW_FAN_INPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) res = RPM_FROM_REG(data->fan[ix], data->fan_div[ix]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) case SHOW_SET_FAN_MIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) res = RPM_FROM_REG(data->fan_min[ix], data->fan_div[ix]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) case SHOW_SET_FAN_DIV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) res = DIV_FROM_REG(data->fan_div[ix]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) case SHOW_FAN_ALARM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) res = (data->alarms >> bitalarmfan[ix]) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) dev_dbg(dev, "Unknown attr fetch (%d)\n", fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return sprintf(buf, "%d\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) static ssize_t set_fan(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct vt1211_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) struct sensor_device_attribute_2 *sensor_attr_2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) int ix = sensor_attr_2->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) int fn = sensor_attr_2->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) /* sync the data cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) reg = vt1211_read8(data, VT1211_REG_FAN_DIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) data->fan_div[0] = (reg >> 4) & 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) data->fan_div[1] = (reg >> 6) & 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) data->fan_ctl = reg & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) switch (fn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) case SHOW_SET_FAN_MIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) data->fan_min[ix] = RPM_TO_REG(val, data->fan_div[ix]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) vt1211_write8(data, VT1211_REG_FAN_MIN(ix),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) data->fan_min[ix]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) case SHOW_SET_FAN_DIV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) data->fan_div[ix] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) data->fan_div[ix] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) data->fan_div[ix] = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) data->fan_div[ix] = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) count = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) dev_warn(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) "fan div value %ld not supported. Choose one of 1, 2, 4, or 8.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) vt1211_write8(data, VT1211_REG_FAN_DIV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) ((data->fan_div[1] << 6) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) (data->fan_div[0] << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) data->fan_ctl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) dev_dbg(dev, "Unknown attr fetch (%d)\n", fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) EXIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) /* ---------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) * PWM sysfs interfaces
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) * ix = [0-1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) * --------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) #define SHOW_PWM 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) #define SHOW_SET_PWM_ENABLE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) #define SHOW_SET_PWM_FREQ 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) #define SHOW_SET_PWM_AUTO_CHANNELS_TEMP 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) struct vt1211_data *data = vt1211_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) struct sensor_device_attribute_2 *sensor_attr_2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) int ix = sensor_attr_2->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) int fn = sensor_attr_2->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) switch (fn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) case SHOW_PWM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) res = data->pwm[ix];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) case SHOW_SET_PWM_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) res = ((data->pwm_ctl[ix] >> 3) & 1) ? 2 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) case SHOW_SET_PWM_FREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) res = 90000 >> (data->pwm_clk & 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) case SHOW_SET_PWM_AUTO_CHANNELS_TEMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) res = (data->pwm_ctl[ix] & 7) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) dev_dbg(dev, "Unknown attr fetch (%d)\n", fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return sprintf(buf, "%d\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) struct vt1211_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) struct sensor_device_attribute_2 *sensor_attr_2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) int ix = sensor_attr_2->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) int fn = sensor_attr_2->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) int tmp, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) switch (fn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) case SHOW_SET_PWM_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) /* sync the data cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) reg = vt1211_read8(data, VT1211_REG_FAN_DIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) data->fan_div[0] = (reg >> 4) & 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) data->fan_div[1] = (reg >> 6) & 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) data->fan_ctl = reg & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) reg = vt1211_read8(data, VT1211_REG_PWM_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) data->pwm_ctl[0] = reg & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) data->pwm_ctl[1] = (reg >> 4) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) data->pwm_ctl[ix] &= 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) * disable SmartGuardian if both PWM outputs are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if ((data->pwm_ctl[ix ^ 1] & 1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) data->fan_ctl &= 0xe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) data->pwm_ctl[ix] |= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) data->fan_ctl |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) count = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) dev_warn(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) "pwm mode %ld not supported. Choose one of 0 or 2.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) vt1211_write8(data, VT1211_REG_PWM_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) ((data->pwm_ctl[1] << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) data->pwm_ctl[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) vt1211_write8(data, VT1211_REG_FAN_DIV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) ((data->fan_div[1] << 6) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) (data->fan_div[0] << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) data->fan_ctl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) case SHOW_SET_PWM_FREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) val = 135000 / clamp_val(val, 135000 >> 7, 135000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) /* calculate tmp = log2(val) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) for (val >>= 1; val > 0; val >>= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) tmp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) /* sync the data cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) reg = vt1211_read8(data, VT1211_REG_PWM_CLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) data->pwm_clk = (reg & 0xf8) | tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) vt1211_write8(data, VT1211_REG_PWM_CLK, data->pwm_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) case SHOW_SET_PWM_AUTO_CHANNELS_TEMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (val < 1 || val > 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) count = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) dev_warn(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) "temp channel %ld not supported. Choose a value between 1 and 7.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (!ISTEMP(val - 1, data->uch_config)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) count = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) dev_warn(dev, "temp channel %ld is not available.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) /* sync the data cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) reg = vt1211_read8(data, VT1211_REG_PWM_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) data->pwm_ctl[0] = reg & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) data->pwm_ctl[1] = (reg >> 4) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) data->pwm_ctl[ix] = (data->pwm_ctl[ix] & 8) | (val - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) vt1211_write8(data, VT1211_REG_PWM_CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) ((data->pwm_ctl[1] << 4) | data->pwm_ctl[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) dev_dbg(dev, "Unknown attr fetch (%d)\n", fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) EXIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) /* ---------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * PWM auto point definitions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) * ix = [0-1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) * ap = [0-3]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) * --------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) * pwm[ix+1]_auto_point[ap+1]_temp mapping table:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) * Note that there is only a single set of temp auto points that controls both
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * PWM controllers. We still create 2 sets of sysfs files to make it look
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) * more consistent even though they map to the same registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) * ix ap : description
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * -------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) * 0 0 : pwm1/2 off temperature (pwm_auto_temp[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) * 0 1 : pwm1/2 low speed temperature (pwm_auto_temp[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) * 0 2 : pwm1/2 high speed temperature (pwm_auto_temp[2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) * 0 3 : pwm1/2 full speed temperature (pwm_auto_temp[3])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * 1 0 : pwm1/2 off temperature (pwm_auto_temp[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * 1 1 : pwm1/2 low speed temperature (pwm_auto_temp[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * 1 2 : pwm1/2 high speed temperature (pwm_auto_temp[2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * 1 3 : pwm1/2 full speed temperature (pwm_auto_temp[3])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) static ssize_t show_pwm_auto_point_temp(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct vt1211_data *data = vt1211_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct sensor_device_attribute_2 *sensor_attr_2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) int ix = sensor_attr_2->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) int ap = sensor_attr_2->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) return sprintf(buf, "%d\n", TEMP_FROM_REG(data->pwm_ctl[ix] & 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) data->pwm_auto_temp[ap]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) static ssize_t set_pwm_auto_point_temp(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) struct vt1211_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) struct sensor_device_attribute_2 *sensor_attr_2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) int ix = sensor_attr_2->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) int ap = sensor_attr_2->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) err = kstrtol(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) /* sync the data cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) reg = vt1211_read8(data, VT1211_REG_PWM_CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) data->pwm_ctl[0] = reg & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) data->pwm_ctl[1] = (reg >> 4) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) data->pwm_auto_temp[ap] = TEMP_TO_REG(data->pwm_ctl[ix] & 7, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) vt1211_write8(data, VT1211_REG_PWM_AUTO_TEMP(ap),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) data->pwm_auto_temp[ap]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * pwm[ix+1]_auto_point[ap+1]_pwm mapping table:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) * Note that the PWM auto points 0 & 3 are hard-wired in the VT1211 and can't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) * be changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) * ix ap : description
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) * -------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) * 0 0 : pwm1 off (pwm_auto_pwm[0][0], hard-wired to 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * 0 1 : pwm1 low speed duty cycle (pwm_auto_pwm[0][1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) * 0 2 : pwm1 high speed duty cycle (pwm_auto_pwm[0][2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) * 0 3 : pwm1 full speed (pwm_auto_pwm[0][3], hard-wired to 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * 1 0 : pwm2 off (pwm_auto_pwm[1][0], hard-wired to 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) * 1 1 : pwm2 low speed duty cycle (pwm_auto_pwm[1][1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * 1 2 : pwm2 high speed duty cycle (pwm_auto_pwm[1][2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) * 1 3 : pwm2 full speed (pwm_auto_pwm[1][3], hard-wired to 255)
^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) static ssize_t show_pwm_auto_point_pwm(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) struct vt1211_data *data = vt1211_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) struct sensor_device_attribute_2 *sensor_attr_2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) int ix = sensor_attr_2->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) int ap = sensor_attr_2->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) return sprintf(buf, "%d\n", data->pwm_auto_pwm[ix][ap]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) static ssize_t set_pwm_auto_point_pwm(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) struct vt1211_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) struct sensor_device_attribute_2 *sensor_attr_2 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) int ix = sensor_attr_2->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) int ap = sensor_attr_2->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) data->pwm_auto_pwm[ix][ap] = clamp_val(val, 0, 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) vt1211_write8(data, VT1211_REG_PWM_AUTO_PWM(ix, ap),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) data->pwm_auto_pwm[ix][ap]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) /* ---------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) * Miscellaneous sysfs interfaces (VRM, VID, name, and (legacy) alarms)
^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_vrm(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) struct vt1211_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) return sprintf(buf, "%d\n", data->vrm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) static ssize_t set_vrm(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) struct vt1211_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (val > 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) data->vrm = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) static ssize_t show_vid(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) struct vt1211_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) static ssize_t show_name(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) struct vt1211_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) return sprintf(buf, "%s\n", data->name);
^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) static ssize_t show_alarms(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) struct vt1211_data *data = vt1211_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) return sprintf(buf, "%d\n", data->alarms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) /* ---------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) * Device attribute structs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) * --------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) #define SENSOR_ATTR_IN(ix) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) { SENSOR_ATTR_2(in##ix##_input, S_IRUGO, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) show_in, NULL, SHOW_IN_INPUT, ix), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) SENSOR_ATTR_2(in##ix##_min, S_IRUGO | S_IWUSR, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) show_in, set_in, SHOW_SET_IN_MIN, ix), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) SENSOR_ATTR_2(in##ix##_max, S_IRUGO | S_IWUSR, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) show_in, set_in, SHOW_SET_IN_MAX, ix), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) SENSOR_ATTR_2(in##ix##_alarm, S_IRUGO, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) show_in, NULL, SHOW_IN_ALARM, ix) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) static struct sensor_device_attribute_2 vt1211_sysfs_in[][4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) SENSOR_ATTR_IN(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) SENSOR_ATTR_IN(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) SENSOR_ATTR_IN(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) SENSOR_ATTR_IN(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) SENSOR_ATTR_IN(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) SENSOR_ATTR_IN(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) #define IN_UNIT_ATTRS(X) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) { &vt1211_sysfs_in[X][0].dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) &vt1211_sysfs_in[X][1].dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) &vt1211_sysfs_in[X][2].dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) &vt1211_sysfs_in[X][3].dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) NULL \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) static struct attribute *vt1211_in_attr[][5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) IN_UNIT_ATTRS(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) IN_UNIT_ATTRS(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) IN_UNIT_ATTRS(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) IN_UNIT_ATTRS(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) IN_UNIT_ATTRS(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) IN_UNIT_ATTRS(5)
^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) static const struct attribute_group vt1211_in_attr_group[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) { .attrs = vt1211_in_attr[0] },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) { .attrs = vt1211_in_attr[1] },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) { .attrs = vt1211_in_attr[2] },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) { .attrs = vt1211_in_attr[3] },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) { .attrs = vt1211_in_attr[4] },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) { .attrs = vt1211_in_attr[5] }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) #define SENSOR_ATTR_TEMP(ix) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) { SENSOR_ATTR_2(temp##ix##_input, S_IRUGO, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) show_temp, NULL, SHOW_TEMP_INPUT, ix-1), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) SENSOR_ATTR_2(temp##ix##_max, S_IRUGO | S_IWUSR, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) show_temp, set_temp, SHOW_SET_TEMP_MAX, ix-1), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) SENSOR_ATTR_2(temp##ix##_max_hyst, S_IRUGO | S_IWUSR, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) show_temp, set_temp, SHOW_SET_TEMP_MAX_HYST, ix-1), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) SENSOR_ATTR_2(temp##ix##_alarm, S_IRUGO, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) show_temp, NULL, SHOW_TEMP_ALARM, ix-1) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) static struct sensor_device_attribute_2 vt1211_sysfs_temp[][4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) SENSOR_ATTR_TEMP(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) SENSOR_ATTR_TEMP(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) SENSOR_ATTR_TEMP(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) SENSOR_ATTR_TEMP(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) SENSOR_ATTR_TEMP(5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) SENSOR_ATTR_TEMP(6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) SENSOR_ATTR_TEMP(7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) #define TEMP_UNIT_ATTRS(X) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) { &vt1211_sysfs_temp[X][0].dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) &vt1211_sysfs_temp[X][1].dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) &vt1211_sysfs_temp[X][2].dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) &vt1211_sysfs_temp[X][3].dev_attr.attr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) NULL \
^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 attribute *vt1211_temp_attr[][5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) TEMP_UNIT_ATTRS(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) TEMP_UNIT_ATTRS(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) TEMP_UNIT_ATTRS(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) TEMP_UNIT_ATTRS(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) TEMP_UNIT_ATTRS(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) TEMP_UNIT_ATTRS(5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) TEMP_UNIT_ATTRS(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) static const struct attribute_group vt1211_temp_attr_group[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) { .attrs = vt1211_temp_attr[0] },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) { .attrs = vt1211_temp_attr[1] },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) { .attrs = vt1211_temp_attr[2] },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) { .attrs = vt1211_temp_attr[3] },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) { .attrs = vt1211_temp_attr[4] },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) { .attrs = vt1211_temp_attr[5] },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) { .attrs = vt1211_temp_attr[6] }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) #define SENSOR_ATTR_FAN(ix) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) SENSOR_ATTR_2(fan##ix##_input, S_IRUGO, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) show_fan, NULL, SHOW_FAN_INPUT, ix-1), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) SENSOR_ATTR_2(fan##ix##_min, S_IRUGO | S_IWUSR, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) show_fan, set_fan, SHOW_SET_FAN_MIN, ix-1), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) SENSOR_ATTR_2(fan##ix##_div, S_IRUGO | S_IWUSR, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) show_fan, set_fan, SHOW_SET_FAN_DIV, ix-1), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) SENSOR_ATTR_2(fan##ix##_alarm, S_IRUGO, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) show_fan, NULL, SHOW_FAN_ALARM, ix-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) #define SENSOR_ATTR_PWM(ix) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) SENSOR_ATTR_2(pwm##ix, S_IRUGO, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) show_pwm, NULL, SHOW_PWM, ix-1), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) SENSOR_ATTR_2(pwm##ix##_enable, S_IRUGO | S_IWUSR, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) show_pwm, set_pwm, SHOW_SET_PWM_ENABLE, ix-1), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) SENSOR_ATTR_2(pwm##ix##_auto_channels_temp, S_IRUGO | S_IWUSR, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) show_pwm, set_pwm, SHOW_SET_PWM_AUTO_CHANNELS_TEMP, ix-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) #define SENSOR_ATTR_PWM_FREQ(ix) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) SENSOR_ATTR_2(pwm##ix##_freq, S_IRUGO | S_IWUSR, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) show_pwm, set_pwm, SHOW_SET_PWM_FREQ, ix-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) #define SENSOR_ATTR_PWM_FREQ_RO(ix) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) SENSOR_ATTR_2(pwm##ix##_freq, S_IRUGO, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) show_pwm, NULL, SHOW_SET_PWM_FREQ, ix-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) #define SENSOR_ATTR_PWM_AUTO_POINT_TEMP(ix, ap) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) SENSOR_ATTR_2(pwm##ix##_auto_point##ap##_temp, S_IRUGO | S_IWUSR, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) show_pwm_auto_point_temp, set_pwm_auto_point_temp, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) ap-1, ix-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) #define SENSOR_ATTR_PWM_AUTO_POINT_TEMP_RO(ix, ap) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) SENSOR_ATTR_2(pwm##ix##_auto_point##ap##_temp, S_IRUGO, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) show_pwm_auto_point_temp, NULL, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) ap-1, ix-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) #define SENSOR_ATTR_PWM_AUTO_POINT_PWM(ix, ap) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) SENSOR_ATTR_2(pwm##ix##_auto_point##ap##_pwm, S_IRUGO | S_IWUSR, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) show_pwm_auto_point_pwm, set_pwm_auto_point_pwm, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) ap-1, ix-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) #define SENSOR_ATTR_PWM_AUTO_POINT_PWM_RO(ix, ap) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) SENSOR_ATTR_2(pwm##ix##_auto_point##ap##_pwm, S_IRUGO, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) show_pwm_auto_point_pwm, NULL, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) ap-1, ix-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) static struct sensor_device_attribute_2 vt1211_sysfs_fan_pwm[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) SENSOR_ATTR_FAN(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) SENSOR_ATTR_FAN(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) SENSOR_ATTR_PWM(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) SENSOR_ATTR_PWM(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) SENSOR_ATTR_PWM_FREQ(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) SENSOR_ATTR_PWM_FREQ_RO(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) SENSOR_ATTR_PWM_AUTO_POINT_TEMP(1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) SENSOR_ATTR_PWM_AUTO_POINT_TEMP(1, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) SENSOR_ATTR_PWM_AUTO_POINT_TEMP(1, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) SENSOR_ATTR_PWM_AUTO_POINT_TEMP(1, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) SENSOR_ATTR_PWM_AUTO_POINT_TEMP_RO(2, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) SENSOR_ATTR_PWM_AUTO_POINT_TEMP_RO(2, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) SENSOR_ATTR_PWM_AUTO_POINT_TEMP_RO(2, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) SENSOR_ATTR_PWM_AUTO_POINT_TEMP_RO(2, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) SENSOR_ATTR_PWM_AUTO_POINT_PWM_RO(1, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) SENSOR_ATTR_PWM_AUTO_POINT_PWM(1, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) SENSOR_ATTR_PWM_AUTO_POINT_PWM(1, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) SENSOR_ATTR_PWM_AUTO_POINT_PWM_RO(1, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) SENSOR_ATTR_PWM_AUTO_POINT_PWM_RO(2, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) SENSOR_ATTR_PWM_AUTO_POINT_PWM(2, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) SENSOR_ATTR_PWM_AUTO_POINT_PWM(2, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) SENSOR_ATTR_PWM_AUTO_POINT_PWM_RO(2, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) static struct device_attribute vt1211_sysfs_misc[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) __ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm, set_vrm),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) __ATTR(cpu0_vid, S_IRUGO, show_vid, NULL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) __ATTR(name, S_IRUGO, show_name, NULL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) __ATTR(alarms, S_IRUGO, show_alarms, NULL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) /* ---------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) * Device registration and initialization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) * --------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) static void vt1211_init_device(struct vt1211_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) /* set VRM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) data->vrm = vid_which_vrm();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) /* Read (and initialize) UCH config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) data->uch_config = vt1211_read8(data, VT1211_REG_UCH_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (uch_config > -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) data->uch_config = (data->uch_config & 0x83) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) (uch_config << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) vt1211_write8(data, VT1211_REG_UCH_CONFIG, data->uch_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) * Initialize the interrupt mode (if request at module load time).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) * The VT1211 implements 3 different modes for clearing interrupts:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) * 0: Clear INT when status register is read. Regenerate INT as long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) * as temp stays above hysteresis limit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) * 1: Clear INT when status register is read. DON'T regenerate INT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) * until temp falls below hysteresis limit and exceeds hot limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) * again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) * 2: Clear INT when temp falls below max limit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) * The driver only allows to force mode 0 since that's the only one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) * that makes sense for 'sensors'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (int_mode == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) vt1211_write8(data, VT1211_REG_TEMP1_CONFIG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) vt1211_write8(data, VT1211_REG_TEMP2_CONFIG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) /* Fill in some hard wired values into our data struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) data->pwm_auto_pwm[0][3] = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) data->pwm_auto_pwm[1][3] = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) static void vt1211_remove_sysfs(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) for (i = 0; i < ARRAY_SIZE(vt1211_in_attr_group); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) sysfs_remove_group(&dev->kobj, &vt1211_in_attr_group[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) for (i = 0; i < ARRAY_SIZE(vt1211_temp_attr_group); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) sysfs_remove_group(&dev->kobj, &vt1211_temp_attr_group[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_fan_pwm); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) device_remove_file(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) &vt1211_sysfs_fan_pwm[i].dev_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_misc); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) device_remove_file(dev, &vt1211_sysfs_misc[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) static int vt1211_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) struct vt1211_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) data = devm_kzalloc(dev, sizeof(struct vt1211_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) res = platform_get_resource(pdev, IORESOURCE_IO, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) if (!devm_request_region(dev, res->start, resource_size(res),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) DRVNAME)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) dev_err(dev, "Failed to request region 0x%lx-0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) (unsigned long)res->start, (unsigned long)res->end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) data->addr = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) data->name = DRVNAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) mutex_init(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) platform_set_drvdata(pdev, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) /* Initialize the VT1211 chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) vt1211_init_device(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) /* Create sysfs interface files */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) for (i = 0; i < ARRAY_SIZE(vt1211_in_attr_group); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) if (ISVOLT(i, data->uch_config)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) err = sysfs_create_group(&dev->kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) &vt1211_in_attr_group[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) goto EXIT_DEV_REMOVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) for (i = 0; i < ARRAY_SIZE(vt1211_temp_attr_group); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) if (ISTEMP(i, data->uch_config)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) err = sysfs_create_group(&dev->kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) &vt1211_temp_attr_group[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) goto EXIT_DEV_REMOVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_fan_pwm); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) err = device_create_file(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) &vt1211_sysfs_fan_pwm[i].dev_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) goto EXIT_DEV_REMOVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) for (i = 0; i < ARRAY_SIZE(vt1211_sysfs_misc); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) err = device_create_file(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) &vt1211_sysfs_misc[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) goto EXIT_DEV_REMOVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) /* Register device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) data->hwmon_dev = hwmon_device_register(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (IS_ERR(data->hwmon_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) err = PTR_ERR(data->hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) dev_err(dev, "Class registration failed (%d)\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) goto EXIT_DEV_REMOVE_SILENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) EXIT_DEV_REMOVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) dev_err(dev, "Sysfs interface creation failed (%d)\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) EXIT_DEV_REMOVE_SILENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) vt1211_remove_sysfs(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) static int vt1211_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) struct vt1211_data *data = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) hwmon_device_unregister(data->hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) vt1211_remove_sysfs(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) static struct platform_driver vt1211_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) .name = DRVNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) .probe = vt1211_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) .remove = vt1211_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) static int __init vt1211_device_add(unsigned short address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) struct resource res = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) .start = address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) .end = address + 0x7f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) .flags = IORESOURCE_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) pdev = platform_device_alloc(DRVNAME, address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) if (!pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) pr_err("Device allocation failed (%d)\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) res.name = pdev->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) err = acpi_check_resource_conflict(&res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) goto EXIT_DEV_PUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) err = platform_device_add_resources(pdev, &res, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) pr_err("Device resource addition failed (%d)\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) goto EXIT_DEV_PUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) err = platform_device_add(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) pr_err("Device addition failed (%d)\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) goto EXIT_DEV_PUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) EXIT_DEV_PUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) platform_device_put(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) EXIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) static int __init vt1211_find(int sio_cip, unsigned short *address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) int devid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) err = superio_enter(sio_cip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) devid = force_id ? force_id : superio_inb(sio_cip, SIO_VT1211_DEVID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (devid != SIO_VT1211_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) superio_select(sio_cip, SIO_VT1211_LDN_HWMON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) if ((superio_inb(sio_cip, SIO_VT1211_ACTIVE) & 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) pr_warn("HW monitor is disabled, skipping\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) *address = ((superio_inb(sio_cip, SIO_VT1211_BADDR) << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) (superio_inb(sio_cip, SIO_VT1211_BADDR + 1))) & 0xff00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) if (*address == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) pr_warn("Base address is not set, skipping\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) pr_info("Found VT1211 chip at 0x%04x, revision %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) *address, superio_inb(sio_cip, SIO_VT1211_DEVREV));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) EXIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) superio_exit(sio_cip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) static int __init vt1211_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) unsigned short address = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) err = vt1211_find(SIO_REG_CIP1, &address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) err = vt1211_find(SIO_REG_CIP2, &address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) if ((uch_config < -1) || (uch_config > 31)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) pr_warn("Invalid UCH configuration %d. Choose a value between 0 and 31.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) uch_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) if ((int_mode < -1) || (int_mode > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) pr_warn("Invalid interrupt mode %d. Only mode 0 is supported.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) int_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) err = platform_driver_register(&vt1211_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) goto EXIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) /* Sets global pdev as a side effect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) err = vt1211_device_add(address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) goto EXIT_DRV_UNREGISTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) EXIT_DRV_UNREGISTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) platform_driver_unregister(&vt1211_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) EXIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) static void __exit vt1211_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) platform_device_unregister(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) platform_driver_unregister(&vt1211_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) MODULE_AUTHOR("Juerg Haefliger <juergh@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) MODULE_DESCRIPTION("VT1211 sensors");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) module_init(vt1211_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) module_exit(vt1211_exit);