18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/*************************************************************************** 38c2ecf20Sopenharmony_ci * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> * 48c2ecf20Sopenharmony_ci * Copyright (C) 2007-2011 Hans de Goede <hdegoede@redhat.com> * 58c2ecf20Sopenharmony_ci * * 68c2ecf20Sopenharmony_ci ***************************************************************************/ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/module.h> 118c2ecf20Sopenharmony_ci#include <linux/init.h> 128c2ecf20Sopenharmony_ci#include <linux/slab.h> 138c2ecf20Sopenharmony_ci#include <linux/jiffies.h> 148c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 158c2ecf20Sopenharmony_ci#include <linux/hwmon.h> 168c2ecf20Sopenharmony_ci#include <linux/hwmon-sysfs.h> 178c2ecf20Sopenharmony_ci#include <linux/err.h> 188c2ecf20Sopenharmony_ci#include <linux/mutex.h> 198c2ecf20Sopenharmony_ci#include <linux/io.h> 208c2ecf20Sopenharmony_ci#include <linux/acpi.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#define DRVNAME "f71882fg" 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#define SIO_F71858FG_LD_HWM 0x02 /* Hardware monitor logical device */ 258c2ecf20Sopenharmony_ci#define SIO_F71882FG_LD_HWM 0x04 /* Hardware monitor logical device */ 268c2ecf20Sopenharmony_ci#define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */ 278c2ecf20Sopenharmony_ci#define SIO_LOCK_KEY 0xAA /* Key to disable Super-I/O */ 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#define SIO_REG_LDSEL 0x07 /* Logical device select */ 308c2ecf20Sopenharmony_ci#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ 318c2ecf20Sopenharmony_ci#define SIO_REG_DEVREV 0x22 /* Device revision */ 328c2ecf20Sopenharmony_ci#define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */ 338c2ecf20Sopenharmony_ci#define SIO_REG_ENABLE 0x30 /* Logical device enable */ 348c2ecf20Sopenharmony_ci#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci#define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ 378c2ecf20Sopenharmony_ci#define SIO_F71808E_ID 0x0901 /* Chipset ID */ 388c2ecf20Sopenharmony_ci#define SIO_F71808A_ID 0x1001 /* Chipset ID */ 398c2ecf20Sopenharmony_ci#define SIO_F71858_ID 0x0507 /* Chipset ID */ 408c2ecf20Sopenharmony_ci#define SIO_F71862_ID 0x0601 /* Chipset ID */ 418c2ecf20Sopenharmony_ci#define SIO_F71868_ID 0x1106 /* Chipset ID */ 428c2ecf20Sopenharmony_ci#define SIO_F71869_ID 0x0814 /* Chipset ID */ 438c2ecf20Sopenharmony_ci#define SIO_F71869A_ID 0x1007 /* Chipset ID */ 448c2ecf20Sopenharmony_ci#define SIO_F71882_ID 0x0541 /* Chipset ID */ 458c2ecf20Sopenharmony_ci#define SIO_F71889_ID 0x0723 /* Chipset ID */ 468c2ecf20Sopenharmony_ci#define SIO_F71889E_ID 0x0909 /* Chipset ID */ 478c2ecf20Sopenharmony_ci#define SIO_F71889A_ID 0x1005 /* Chipset ID */ 488c2ecf20Sopenharmony_ci#define SIO_F8000_ID 0x0581 /* Chipset ID */ 498c2ecf20Sopenharmony_ci#define SIO_F81768D_ID 0x1210 /* Chipset ID */ 508c2ecf20Sopenharmony_ci#define SIO_F81865_ID 0x0704 /* Chipset ID */ 518c2ecf20Sopenharmony_ci#define SIO_F81866_ID 0x1010 /* Chipset ID */ 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci#define REGION_LENGTH 8 548c2ecf20Sopenharmony_ci#define ADDR_REG_OFFSET 5 558c2ecf20Sopenharmony_ci#define DATA_REG_OFFSET 6 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci#define F71882FG_REG_IN_STATUS 0x12 /* f7188x only */ 588c2ecf20Sopenharmony_ci#define F71882FG_REG_IN_BEEP 0x13 /* f7188x only */ 598c2ecf20Sopenharmony_ci#define F71882FG_REG_IN(nr) (0x20 + (nr)) 608c2ecf20Sopenharmony_ci#define F71882FG_REG_IN1_HIGH 0x32 /* f7188x only */ 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci#define F81866_REG_IN_STATUS 0x16 /* F81866 only */ 638c2ecf20Sopenharmony_ci#define F81866_REG_IN_BEEP 0x17 /* F81866 only */ 648c2ecf20Sopenharmony_ci#define F81866_REG_IN1_HIGH 0x3a /* F81866 only */ 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci#define F71882FG_REG_FAN(nr) (0xA0 + (16 * (nr))) 678c2ecf20Sopenharmony_ci#define F71882FG_REG_FAN_TARGET(nr) (0xA2 + (16 * (nr))) 688c2ecf20Sopenharmony_ci#define F71882FG_REG_FAN_FULL_SPEED(nr) (0xA4 + (16 * (nr))) 698c2ecf20Sopenharmony_ci#define F71882FG_REG_FAN_STATUS 0x92 708c2ecf20Sopenharmony_ci#define F71882FG_REG_FAN_BEEP 0x93 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci#define F71882FG_REG_TEMP(nr) (0x70 + 2 * (nr)) 738c2ecf20Sopenharmony_ci#define F71882FG_REG_TEMP_OVT(nr) (0x80 + 2 * (nr)) 748c2ecf20Sopenharmony_ci#define F71882FG_REG_TEMP_HIGH(nr) (0x81 + 2 * (nr)) 758c2ecf20Sopenharmony_ci#define F71882FG_REG_TEMP_STATUS 0x62 768c2ecf20Sopenharmony_ci#define F71882FG_REG_TEMP_BEEP 0x63 778c2ecf20Sopenharmony_ci#define F71882FG_REG_TEMP_CONFIG 0x69 788c2ecf20Sopenharmony_ci#define F71882FG_REG_TEMP_HYST(nr) (0x6C + (nr)) 798c2ecf20Sopenharmony_ci#define F71882FG_REG_TEMP_TYPE 0x6B 808c2ecf20Sopenharmony_ci#define F71882FG_REG_TEMP_DIODE_OPEN 0x6F 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci#define F71882FG_REG_PWM(nr) (0xA3 + (16 * (nr))) 838c2ecf20Sopenharmony_ci#define F71882FG_REG_PWM_TYPE 0x94 848c2ecf20Sopenharmony_ci#define F71882FG_REG_PWM_ENABLE 0x96 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci#define F71882FG_REG_FAN_HYST(nr) (0x98 + (nr)) 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci#define F71882FG_REG_FAN_FAULT_T 0x9F 898c2ecf20Sopenharmony_ci#define F71882FG_FAN_NEG_TEMP_EN 0x20 908c2ecf20Sopenharmony_ci#define F71882FG_FAN_PROG_SEL 0x80 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci#define F71882FG_REG_POINT_PWM(pwm, point) (0xAA + (point) + (16 * (pwm))) 938c2ecf20Sopenharmony_ci#define F71882FG_REG_POINT_TEMP(pwm, point) (0xA6 + (point) + (16 * (pwm))) 948c2ecf20Sopenharmony_ci#define F71882FG_REG_POINT_MAPPING(nr) (0xAF + 16 * (nr)) 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci#define F71882FG_REG_START 0x01 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci#define F71882FG_MAX_INS 11 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci#define FAN_MIN_DETECT 366 /* Lowest detectable fanspeed */ 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_cistatic unsigned short force_id; 1038c2ecf20Sopenharmony_cimodule_param(force_id, ushort, 0); 1048c2ecf20Sopenharmony_ciMODULE_PARM_DESC(force_id, "Override the detected device ID"); 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_cienum chips { f71808e, f71808a, f71858fg, f71862fg, f71868a, f71869, f71869a, 1078c2ecf20Sopenharmony_ci f71882fg, f71889fg, f71889ed, f71889a, f8000, f81768d, f81865f, 1088c2ecf20Sopenharmony_ci f81866a}; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_cistatic const char *const f71882fg_names[] = { 1118c2ecf20Sopenharmony_ci "f71808e", 1128c2ecf20Sopenharmony_ci "f71808a", 1138c2ecf20Sopenharmony_ci "f71858fg", 1148c2ecf20Sopenharmony_ci "f71862fg", 1158c2ecf20Sopenharmony_ci "f71868a", 1168c2ecf20Sopenharmony_ci "f71869", /* Both f71869f and f71869e, reg. compatible and same id */ 1178c2ecf20Sopenharmony_ci "f71869a", 1188c2ecf20Sopenharmony_ci "f71882fg", 1198c2ecf20Sopenharmony_ci "f71889fg", /* f81801u too, same id */ 1208c2ecf20Sopenharmony_ci "f71889ed", 1218c2ecf20Sopenharmony_ci "f71889a", 1228c2ecf20Sopenharmony_ci "f8000", 1238c2ecf20Sopenharmony_ci "f81768d", 1248c2ecf20Sopenharmony_ci "f81865f", 1258c2ecf20Sopenharmony_ci "f81866a", 1268c2ecf20Sopenharmony_ci}; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_cistatic const char f71882fg_has_in[][F71882FG_MAX_INS] = { 1298c2ecf20Sopenharmony_ci [f71808e] = { 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0 }, 1308c2ecf20Sopenharmony_ci [f71808a] = { 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0 }, 1318c2ecf20Sopenharmony_ci [f71858fg] = { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, 1328c2ecf20Sopenharmony_ci [f71862fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, 1338c2ecf20Sopenharmony_ci [f71868a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, 1348c2ecf20Sopenharmony_ci [f71869] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, 1358c2ecf20Sopenharmony_ci [f71869a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, 1368c2ecf20Sopenharmony_ci [f71882fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, 1378c2ecf20Sopenharmony_ci [f71889fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, 1388c2ecf20Sopenharmony_ci [f71889ed] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, 1398c2ecf20Sopenharmony_ci [f71889a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, 1408c2ecf20Sopenharmony_ci [f8000] = { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, 1418c2ecf20Sopenharmony_ci [f81768d] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, 1428c2ecf20Sopenharmony_ci [f81865f] = { 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, 1438c2ecf20Sopenharmony_ci [f81866a] = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 }, 1448c2ecf20Sopenharmony_ci}; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cistatic const char f71882fg_has_in1_alarm[] = { 1478c2ecf20Sopenharmony_ci [f71808e] = 0, 1488c2ecf20Sopenharmony_ci [f71808a] = 0, 1498c2ecf20Sopenharmony_ci [f71858fg] = 0, 1508c2ecf20Sopenharmony_ci [f71862fg] = 0, 1518c2ecf20Sopenharmony_ci [f71868a] = 0, 1528c2ecf20Sopenharmony_ci [f71869] = 0, 1538c2ecf20Sopenharmony_ci [f71869a] = 0, 1548c2ecf20Sopenharmony_ci [f71882fg] = 1, 1558c2ecf20Sopenharmony_ci [f71889fg] = 1, 1568c2ecf20Sopenharmony_ci [f71889ed] = 1, 1578c2ecf20Sopenharmony_ci [f71889a] = 1, 1588c2ecf20Sopenharmony_ci [f8000] = 0, 1598c2ecf20Sopenharmony_ci [f81768d] = 1, 1608c2ecf20Sopenharmony_ci [f81865f] = 1, 1618c2ecf20Sopenharmony_ci [f81866a] = 1, 1628c2ecf20Sopenharmony_ci}; 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_cistatic const char f71882fg_fan_has_beep[] = { 1658c2ecf20Sopenharmony_ci [f71808e] = 0, 1668c2ecf20Sopenharmony_ci [f71808a] = 0, 1678c2ecf20Sopenharmony_ci [f71858fg] = 0, 1688c2ecf20Sopenharmony_ci [f71862fg] = 1, 1698c2ecf20Sopenharmony_ci [f71868a] = 1, 1708c2ecf20Sopenharmony_ci [f71869] = 1, 1718c2ecf20Sopenharmony_ci [f71869a] = 1, 1728c2ecf20Sopenharmony_ci [f71882fg] = 1, 1738c2ecf20Sopenharmony_ci [f71889fg] = 1, 1748c2ecf20Sopenharmony_ci [f71889ed] = 1, 1758c2ecf20Sopenharmony_ci [f71889a] = 1, 1768c2ecf20Sopenharmony_ci [f8000] = 0, 1778c2ecf20Sopenharmony_ci [f81768d] = 1, 1788c2ecf20Sopenharmony_ci [f81865f] = 1, 1798c2ecf20Sopenharmony_ci [f81866a] = 1, 1808c2ecf20Sopenharmony_ci}; 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_cistatic const char f71882fg_nr_fans[] = { 1838c2ecf20Sopenharmony_ci [f71808e] = 3, 1848c2ecf20Sopenharmony_ci [f71808a] = 2, /* +1 fan which is monitor + simple pwm only */ 1858c2ecf20Sopenharmony_ci [f71858fg] = 3, 1868c2ecf20Sopenharmony_ci [f71862fg] = 3, 1878c2ecf20Sopenharmony_ci [f71868a] = 3, 1888c2ecf20Sopenharmony_ci [f71869] = 3, 1898c2ecf20Sopenharmony_ci [f71869a] = 3, 1908c2ecf20Sopenharmony_ci [f71882fg] = 4, 1918c2ecf20Sopenharmony_ci [f71889fg] = 3, 1928c2ecf20Sopenharmony_ci [f71889ed] = 3, 1938c2ecf20Sopenharmony_ci [f71889a] = 3, 1948c2ecf20Sopenharmony_ci [f8000] = 3, /* +1 fan which is monitor only */ 1958c2ecf20Sopenharmony_ci [f81768d] = 3, 1968c2ecf20Sopenharmony_ci [f81865f] = 2, 1978c2ecf20Sopenharmony_ci [f81866a] = 3, 1988c2ecf20Sopenharmony_ci}; 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_cistatic const char f71882fg_temp_has_beep[] = { 2018c2ecf20Sopenharmony_ci [f71808e] = 0, 2028c2ecf20Sopenharmony_ci [f71808a] = 1, 2038c2ecf20Sopenharmony_ci [f71858fg] = 0, 2048c2ecf20Sopenharmony_ci [f71862fg] = 1, 2058c2ecf20Sopenharmony_ci [f71868a] = 1, 2068c2ecf20Sopenharmony_ci [f71869] = 1, 2078c2ecf20Sopenharmony_ci [f71869a] = 1, 2088c2ecf20Sopenharmony_ci [f71882fg] = 1, 2098c2ecf20Sopenharmony_ci [f71889fg] = 1, 2108c2ecf20Sopenharmony_ci [f71889ed] = 1, 2118c2ecf20Sopenharmony_ci [f71889a] = 1, 2128c2ecf20Sopenharmony_ci [f8000] = 0, 2138c2ecf20Sopenharmony_ci [f81768d] = 1, 2148c2ecf20Sopenharmony_ci [f81865f] = 1, 2158c2ecf20Sopenharmony_ci [f81866a] = 1, 2168c2ecf20Sopenharmony_ci}; 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_cistatic const char f71882fg_nr_temps[] = { 2198c2ecf20Sopenharmony_ci [f71808e] = 2, 2208c2ecf20Sopenharmony_ci [f71808a] = 2, 2218c2ecf20Sopenharmony_ci [f71858fg] = 3, 2228c2ecf20Sopenharmony_ci [f71862fg] = 3, 2238c2ecf20Sopenharmony_ci [f71868a] = 3, 2248c2ecf20Sopenharmony_ci [f71869] = 3, 2258c2ecf20Sopenharmony_ci [f71869a] = 3, 2268c2ecf20Sopenharmony_ci [f71882fg] = 3, 2278c2ecf20Sopenharmony_ci [f71889fg] = 3, 2288c2ecf20Sopenharmony_ci [f71889ed] = 3, 2298c2ecf20Sopenharmony_ci [f71889a] = 3, 2308c2ecf20Sopenharmony_ci [f8000] = 3, 2318c2ecf20Sopenharmony_ci [f81768d] = 3, 2328c2ecf20Sopenharmony_ci [f81865f] = 2, 2338c2ecf20Sopenharmony_ci [f81866a] = 3, 2348c2ecf20Sopenharmony_ci}; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_cistatic struct platform_device *f71882fg_pdev; 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci/* Super-I/O Function prototypes */ 2398c2ecf20Sopenharmony_cistatic inline int superio_inb(int base, int reg); 2408c2ecf20Sopenharmony_cistatic inline int superio_inw(int base, int reg); 2418c2ecf20Sopenharmony_cistatic inline int superio_enter(int base); 2428c2ecf20Sopenharmony_cistatic inline void superio_select(int base, int ld); 2438c2ecf20Sopenharmony_cistatic inline void superio_exit(int base); 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_cistruct f71882fg_sio_data { 2468c2ecf20Sopenharmony_ci enum chips type; 2478c2ecf20Sopenharmony_ci}; 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_cistruct f71882fg_data { 2508c2ecf20Sopenharmony_ci unsigned short addr; 2518c2ecf20Sopenharmony_ci enum chips type; 2528c2ecf20Sopenharmony_ci struct device *hwmon_dev; 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci struct mutex update_lock; 2558c2ecf20Sopenharmony_ci int temp_start; /* temp numbering start (0 or 1) */ 2568c2ecf20Sopenharmony_ci char valid; /* !=0 if following fields are valid */ 2578c2ecf20Sopenharmony_ci char auto_point_temp_signed; 2588c2ecf20Sopenharmony_ci unsigned long last_updated; /* In jiffies */ 2598c2ecf20Sopenharmony_ci unsigned long last_limits; /* In jiffies */ 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci /* Register Values */ 2628c2ecf20Sopenharmony_ci u8 in[F71882FG_MAX_INS]; 2638c2ecf20Sopenharmony_ci u8 in1_max; 2648c2ecf20Sopenharmony_ci u8 in_status; 2658c2ecf20Sopenharmony_ci u8 in_beep; 2668c2ecf20Sopenharmony_ci u16 fan[4]; 2678c2ecf20Sopenharmony_ci u16 fan_target[4]; 2688c2ecf20Sopenharmony_ci u16 fan_full_speed[4]; 2698c2ecf20Sopenharmony_ci u8 fan_status; 2708c2ecf20Sopenharmony_ci u8 fan_beep; 2718c2ecf20Sopenharmony_ci /* 2728c2ecf20Sopenharmony_ci * Note: all models have max 3 temperature channels, but on some 2738c2ecf20Sopenharmony_ci * they are addressed as 0-2 and on others as 1-3, so for coding 2748c2ecf20Sopenharmony_ci * convenience we reserve space for 4 channels 2758c2ecf20Sopenharmony_ci */ 2768c2ecf20Sopenharmony_ci u16 temp[4]; 2778c2ecf20Sopenharmony_ci u8 temp_ovt[4]; 2788c2ecf20Sopenharmony_ci u8 temp_high[4]; 2798c2ecf20Sopenharmony_ci u8 temp_hyst[2]; /* 2 hysts stored per reg */ 2808c2ecf20Sopenharmony_ci u8 temp_type[4]; 2818c2ecf20Sopenharmony_ci u8 temp_status; 2828c2ecf20Sopenharmony_ci u8 temp_beep; 2838c2ecf20Sopenharmony_ci u8 temp_diode_open; 2848c2ecf20Sopenharmony_ci u8 temp_config; 2858c2ecf20Sopenharmony_ci u8 pwm[4]; 2868c2ecf20Sopenharmony_ci u8 pwm_enable; 2878c2ecf20Sopenharmony_ci u8 pwm_auto_point_hyst[2]; 2888c2ecf20Sopenharmony_ci u8 pwm_auto_point_mapping[4]; 2898c2ecf20Sopenharmony_ci u8 pwm_auto_point_pwm[4][5]; 2908c2ecf20Sopenharmony_ci s8 pwm_auto_point_temp[4][4]; 2918c2ecf20Sopenharmony_ci}; 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci/* Sysfs in */ 2948c2ecf20Sopenharmony_cistatic ssize_t show_in(struct device *dev, struct device_attribute *devattr, 2958c2ecf20Sopenharmony_ci char *buf); 2968c2ecf20Sopenharmony_cistatic ssize_t show_in_max(struct device *dev, struct device_attribute 2978c2ecf20Sopenharmony_ci *devattr, char *buf); 2988c2ecf20Sopenharmony_cistatic ssize_t store_in_max(struct device *dev, struct device_attribute 2998c2ecf20Sopenharmony_ci *devattr, const char *buf, size_t count); 3008c2ecf20Sopenharmony_cistatic ssize_t show_in_beep(struct device *dev, struct device_attribute 3018c2ecf20Sopenharmony_ci *devattr, char *buf); 3028c2ecf20Sopenharmony_cistatic ssize_t store_in_beep(struct device *dev, struct device_attribute 3038c2ecf20Sopenharmony_ci *devattr, const char *buf, size_t count); 3048c2ecf20Sopenharmony_cistatic ssize_t show_in_alarm(struct device *dev, struct device_attribute 3058c2ecf20Sopenharmony_ci *devattr, char *buf); 3068c2ecf20Sopenharmony_ci/* Sysfs Fan */ 3078c2ecf20Sopenharmony_cistatic ssize_t show_fan(struct device *dev, struct device_attribute *devattr, 3088c2ecf20Sopenharmony_ci char *buf); 3098c2ecf20Sopenharmony_cistatic ssize_t show_fan_full_speed(struct device *dev, 3108c2ecf20Sopenharmony_ci struct device_attribute *devattr, char *buf); 3118c2ecf20Sopenharmony_cistatic ssize_t store_fan_full_speed(struct device *dev, 3128c2ecf20Sopenharmony_ci struct device_attribute *devattr, const char *buf, size_t count); 3138c2ecf20Sopenharmony_cistatic ssize_t show_fan_beep(struct device *dev, struct device_attribute 3148c2ecf20Sopenharmony_ci *devattr, char *buf); 3158c2ecf20Sopenharmony_cistatic ssize_t store_fan_beep(struct device *dev, struct device_attribute 3168c2ecf20Sopenharmony_ci *devattr, const char *buf, size_t count); 3178c2ecf20Sopenharmony_cistatic ssize_t show_fan_alarm(struct device *dev, struct device_attribute 3188c2ecf20Sopenharmony_ci *devattr, char *buf); 3198c2ecf20Sopenharmony_ci/* Sysfs Temp */ 3208c2ecf20Sopenharmony_cistatic ssize_t show_temp(struct device *dev, struct device_attribute 3218c2ecf20Sopenharmony_ci *devattr, char *buf); 3228c2ecf20Sopenharmony_cistatic ssize_t show_temp_max(struct device *dev, struct device_attribute 3238c2ecf20Sopenharmony_ci *devattr, char *buf); 3248c2ecf20Sopenharmony_cistatic ssize_t store_temp_max(struct device *dev, struct device_attribute 3258c2ecf20Sopenharmony_ci *devattr, const char *buf, size_t count); 3268c2ecf20Sopenharmony_cistatic ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute 3278c2ecf20Sopenharmony_ci *devattr, char *buf); 3288c2ecf20Sopenharmony_cistatic ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute 3298c2ecf20Sopenharmony_ci *devattr, const char *buf, size_t count); 3308c2ecf20Sopenharmony_cistatic ssize_t show_temp_crit(struct device *dev, struct device_attribute 3318c2ecf20Sopenharmony_ci *devattr, char *buf); 3328c2ecf20Sopenharmony_cistatic ssize_t store_temp_crit(struct device *dev, struct device_attribute 3338c2ecf20Sopenharmony_ci *devattr, const char *buf, size_t count); 3348c2ecf20Sopenharmony_cistatic ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute 3358c2ecf20Sopenharmony_ci *devattr, char *buf); 3368c2ecf20Sopenharmony_cistatic ssize_t show_temp_type(struct device *dev, struct device_attribute 3378c2ecf20Sopenharmony_ci *devattr, char *buf); 3388c2ecf20Sopenharmony_cistatic ssize_t show_temp_beep(struct device *dev, struct device_attribute 3398c2ecf20Sopenharmony_ci *devattr, char *buf); 3408c2ecf20Sopenharmony_cistatic ssize_t store_temp_beep(struct device *dev, struct device_attribute 3418c2ecf20Sopenharmony_ci *devattr, const char *buf, size_t count); 3428c2ecf20Sopenharmony_cistatic ssize_t show_temp_alarm(struct device *dev, struct device_attribute 3438c2ecf20Sopenharmony_ci *devattr, char *buf); 3448c2ecf20Sopenharmony_cistatic ssize_t show_temp_fault(struct device *dev, struct device_attribute 3458c2ecf20Sopenharmony_ci *devattr, char *buf); 3468c2ecf20Sopenharmony_ci/* PWM and Auto point control */ 3478c2ecf20Sopenharmony_cistatic ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, 3488c2ecf20Sopenharmony_ci char *buf); 3498c2ecf20Sopenharmony_cistatic ssize_t store_pwm(struct device *dev, struct device_attribute *devattr, 3508c2ecf20Sopenharmony_ci const char *buf, size_t count); 3518c2ecf20Sopenharmony_cistatic ssize_t show_simple_pwm(struct device *dev, 3528c2ecf20Sopenharmony_ci struct device_attribute *devattr, char *buf); 3538c2ecf20Sopenharmony_cistatic ssize_t store_simple_pwm(struct device *dev, 3548c2ecf20Sopenharmony_ci struct device_attribute *devattr, const char *buf, size_t count); 3558c2ecf20Sopenharmony_cistatic ssize_t show_pwm_enable(struct device *dev, 3568c2ecf20Sopenharmony_ci struct device_attribute *devattr, char *buf); 3578c2ecf20Sopenharmony_cistatic ssize_t store_pwm_enable(struct device *dev, 3588c2ecf20Sopenharmony_ci struct device_attribute *devattr, const char *buf, size_t count); 3598c2ecf20Sopenharmony_cistatic ssize_t show_pwm_interpolate(struct device *dev, 3608c2ecf20Sopenharmony_ci struct device_attribute *devattr, char *buf); 3618c2ecf20Sopenharmony_cistatic ssize_t store_pwm_interpolate(struct device *dev, 3628c2ecf20Sopenharmony_ci struct device_attribute *devattr, const char *buf, size_t count); 3638c2ecf20Sopenharmony_cistatic ssize_t show_pwm_auto_point_channel(struct device *dev, 3648c2ecf20Sopenharmony_ci struct device_attribute *devattr, char *buf); 3658c2ecf20Sopenharmony_cistatic ssize_t store_pwm_auto_point_channel(struct device *dev, 3668c2ecf20Sopenharmony_ci struct device_attribute *devattr, const char *buf, size_t count); 3678c2ecf20Sopenharmony_cistatic ssize_t show_pwm_auto_point_temp_hyst(struct device *dev, 3688c2ecf20Sopenharmony_ci struct device_attribute *devattr, char *buf); 3698c2ecf20Sopenharmony_cistatic ssize_t store_pwm_auto_point_temp_hyst(struct device *dev, 3708c2ecf20Sopenharmony_ci struct device_attribute *devattr, const char *buf, size_t count); 3718c2ecf20Sopenharmony_cistatic ssize_t show_pwm_auto_point_pwm(struct device *dev, 3728c2ecf20Sopenharmony_ci struct device_attribute *devattr, char *buf); 3738c2ecf20Sopenharmony_cistatic ssize_t store_pwm_auto_point_pwm(struct device *dev, 3748c2ecf20Sopenharmony_ci struct device_attribute *devattr, const char *buf, size_t count); 3758c2ecf20Sopenharmony_cistatic ssize_t show_pwm_auto_point_temp(struct device *dev, 3768c2ecf20Sopenharmony_ci struct device_attribute *devattr, char *buf); 3778c2ecf20Sopenharmony_cistatic ssize_t store_pwm_auto_point_temp(struct device *dev, 3788c2ecf20Sopenharmony_ci struct device_attribute *devattr, const char *buf, size_t count); 3798c2ecf20Sopenharmony_ci/* Sysfs misc */ 3808c2ecf20Sopenharmony_cistatic ssize_t name_show(struct device *dev, struct device_attribute *devattr, 3818c2ecf20Sopenharmony_ci char *buf); 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_cistatic int f71882fg_probe(struct platform_device *pdev); 3848c2ecf20Sopenharmony_cistatic int f71882fg_remove(struct platform_device *pdev); 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_cistatic struct platform_driver f71882fg_driver = { 3878c2ecf20Sopenharmony_ci .driver = { 3888c2ecf20Sopenharmony_ci .name = DRVNAME, 3898c2ecf20Sopenharmony_ci }, 3908c2ecf20Sopenharmony_ci .probe = f71882fg_probe, 3918c2ecf20Sopenharmony_ci .remove = f71882fg_remove, 3928c2ecf20Sopenharmony_ci}; 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(name); 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ci/* 3978c2ecf20Sopenharmony_ci * Temp attr for the f71858fg, the f71858fg is special as it has its 3988c2ecf20Sopenharmony_ci * temperature indexes start at 0 (the others start at 1) 3998c2ecf20Sopenharmony_ci */ 4008c2ecf20Sopenharmony_cistatic struct sensor_device_attribute_2 f71858fg_temp_attr[] = { 4018c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0), 4028c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, 4038c2ecf20Sopenharmony_ci store_temp_max, 0, 0), 4048c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, 4058c2ecf20Sopenharmony_ci store_temp_max_hyst, 0, 0), 4068c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 0), 4078c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit, 4088c2ecf20Sopenharmony_ci store_temp_crit, 0, 0), 4098c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 4108c2ecf20Sopenharmony_ci 0, 0), 4118c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4), 4128c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0), 4138c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1), 4148c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max, 4158c2ecf20Sopenharmony_ci store_temp_max, 0, 1), 4168c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, 4178c2ecf20Sopenharmony_ci store_temp_max_hyst, 0, 1), 4188c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1), 4198c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit, 4208c2ecf20Sopenharmony_ci store_temp_crit, 0, 1), 4218c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 4228c2ecf20Sopenharmony_ci 0, 1), 4238c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5), 4248c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1), 4258c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2), 4268c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max, 4278c2ecf20Sopenharmony_ci store_temp_max, 0, 2), 4288c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, 4298c2ecf20Sopenharmony_ci store_temp_max_hyst, 0, 2), 4308c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2), 4318c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit, 4328c2ecf20Sopenharmony_ci store_temp_crit, 0, 2), 4338c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 4348c2ecf20Sopenharmony_ci 0, 2), 4358c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6), 4368c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), 4378c2ecf20Sopenharmony_ci}; 4388c2ecf20Sopenharmony_ci 4398c2ecf20Sopenharmony_ci/* Temp attr for the standard models */ 4408c2ecf20Sopenharmony_cistatic struct sensor_device_attribute_2 fxxxx_temp_attr[3][9] = { { 4418c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1), 4428c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, 4438c2ecf20Sopenharmony_ci store_temp_max, 0, 1), 4448c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, 4458c2ecf20Sopenharmony_ci store_temp_max_hyst, 0, 1), 4468c2ecf20Sopenharmony_ci /* 4478c2ecf20Sopenharmony_ci * Should really be temp1_max_alarm, but older versions did not handle 4488c2ecf20Sopenharmony_ci * the max and crit alarms separately and lm_sensors v2 depends on the 4498c2ecf20Sopenharmony_ci * presence of temp#_alarm files. The same goes for temp2/3 _alarm. 4508c2ecf20Sopenharmony_ci */ 4518c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1), 4528c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit, 4538c2ecf20Sopenharmony_ci store_temp_crit, 0, 1), 4548c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 4558c2ecf20Sopenharmony_ci 0, 1), 4568c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5), 4578c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_type, S_IRUGO, show_temp_type, NULL, 0, 1), 4588c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 1), 4598c2ecf20Sopenharmony_ci}, { 4608c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 2), 4618c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max, 4628c2ecf20Sopenharmony_ci store_temp_max, 0, 2), 4638c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, 4648c2ecf20Sopenharmony_ci store_temp_max_hyst, 0, 2), 4658c2ecf20Sopenharmony_ci /* Should be temp2_max_alarm, see temp1_alarm note */ 4668c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2), 4678c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit, 4688c2ecf20Sopenharmony_ci store_temp_crit, 0, 2), 4698c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 4708c2ecf20Sopenharmony_ci 0, 2), 4718c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6), 4728c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2), 4738c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), 4748c2ecf20Sopenharmony_ci}, { 4758c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3), 4768c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max, 4778c2ecf20Sopenharmony_ci store_temp_max, 0, 3), 4788c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst, 4798c2ecf20Sopenharmony_ci store_temp_max_hyst, 0, 3), 4808c2ecf20Sopenharmony_ci /* Should be temp3_max_alarm, see temp1_alarm note */ 4818c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 3), 4828c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit, 4838c2ecf20Sopenharmony_ci store_temp_crit, 0, 3), 4848c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL, 4858c2ecf20Sopenharmony_ci 0, 3), 4868c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 7), 4878c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_type, S_IRUGO, show_temp_type, NULL, 0, 3), 4888c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 3), 4898c2ecf20Sopenharmony_ci} }; 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_ci/* Temp attr for models which can beep on temp alarm */ 4928c2ecf20Sopenharmony_cistatic struct sensor_device_attribute_2 fxxxx_temp_beep_attr[3][2] = { { 4938c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep, 4948c2ecf20Sopenharmony_ci store_temp_beep, 0, 1), 4958c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep, 4968c2ecf20Sopenharmony_ci store_temp_beep, 0, 5), 4978c2ecf20Sopenharmony_ci}, { 4988c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep, 4998c2ecf20Sopenharmony_ci store_temp_beep, 0, 2), 5008c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep, 5018c2ecf20Sopenharmony_ci store_temp_beep, 0, 6), 5028c2ecf20Sopenharmony_ci}, { 5038c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep, 5048c2ecf20Sopenharmony_ci store_temp_beep, 0, 3), 5058c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep, 5068c2ecf20Sopenharmony_ci store_temp_beep, 0, 7), 5078c2ecf20Sopenharmony_ci} }; 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_cistatic struct sensor_device_attribute_2 f81866_temp_beep_attr[3][2] = { { 5108c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_max_beep, S_IRUGO|S_IWUSR, show_temp_beep, 5118c2ecf20Sopenharmony_ci store_temp_beep, 0, 0), 5128c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep, 5138c2ecf20Sopenharmony_ci store_temp_beep, 0, 4), 5148c2ecf20Sopenharmony_ci}, { 5158c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_max_beep, S_IRUGO|S_IWUSR, show_temp_beep, 5168c2ecf20Sopenharmony_ci store_temp_beep, 0, 1), 5178c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep, 5188c2ecf20Sopenharmony_ci store_temp_beep, 0, 5), 5198c2ecf20Sopenharmony_ci}, { 5208c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_max_beep, S_IRUGO|S_IWUSR, show_temp_beep, 5218c2ecf20Sopenharmony_ci store_temp_beep, 0, 2), 5228c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_crit_beep, S_IRUGO|S_IWUSR, show_temp_beep, 5238c2ecf20Sopenharmony_ci store_temp_beep, 0, 6), 5248c2ecf20Sopenharmony_ci} }; 5258c2ecf20Sopenharmony_ci 5268c2ecf20Sopenharmony_ci/* 5278c2ecf20Sopenharmony_ci * Temp attr for the f8000 5288c2ecf20Sopenharmony_ci * Note on the f8000 temp_ovt (crit) is used as max, and temp_high (max) 5298c2ecf20Sopenharmony_ci * is used as hysteresis value to clear alarms 5308c2ecf20Sopenharmony_ci * Also like the f71858fg its temperature indexes start at 0 5318c2ecf20Sopenharmony_ci */ 5328c2ecf20Sopenharmony_cistatic struct sensor_device_attribute_2 f8000_temp_attr[] = { 5338c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0), 5348c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_crit, 5358c2ecf20Sopenharmony_ci store_temp_crit, 0, 0), 5368c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max, 5378c2ecf20Sopenharmony_ci store_temp_max, 0, 0), 5388c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4), 5398c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0), 5408c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1), 5418c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_crit, 5428c2ecf20Sopenharmony_ci store_temp_crit, 0, 1), 5438c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max, 5448c2ecf20Sopenharmony_ci store_temp_max, 0, 1), 5458c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5), 5468c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1), 5478c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2), 5488c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_crit, 5498c2ecf20Sopenharmony_ci store_temp_crit, 0, 2), 5508c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max, 5518c2ecf20Sopenharmony_ci store_temp_max, 0, 2), 5528c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6), 5538c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), 5548c2ecf20Sopenharmony_ci}; 5558c2ecf20Sopenharmony_ci 5568c2ecf20Sopenharmony_ci/* in attr for all models */ 5578c2ecf20Sopenharmony_cistatic struct sensor_device_attribute_2 fxxxx_in_attr[] = { 5588c2ecf20Sopenharmony_ci SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), 5598c2ecf20Sopenharmony_ci SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), 5608c2ecf20Sopenharmony_ci SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2), 5618c2ecf20Sopenharmony_ci SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3), 5628c2ecf20Sopenharmony_ci SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4), 5638c2ecf20Sopenharmony_ci SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5), 5648c2ecf20Sopenharmony_ci SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6), 5658c2ecf20Sopenharmony_ci SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7), 5668c2ecf20Sopenharmony_ci SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8), 5678c2ecf20Sopenharmony_ci SENSOR_ATTR_2(in9_input, S_IRUGO, show_in, NULL, 0, 9), 5688c2ecf20Sopenharmony_ci SENSOR_ATTR_2(in10_input, S_IRUGO, show_in, NULL, 0, 10), 5698c2ecf20Sopenharmony_ci}; 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_ci/* For models with in1 alarm capability */ 5728c2ecf20Sopenharmony_cistatic struct sensor_device_attribute_2 fxxxx_in1_alarm_attr[] = { 5738c2ecf20Sopenharmony_ci SENSOR_ATTR_2(in1_max, S_IRUGO|S_IWUSR, show_in_max, store_in_max, 5748c2ecf20Sopenharmony_ci 0, 1), 5758c2ecf20Sopenharmony_ci SENSOR_ATTR_2(in1_beep, S_IRUGO|S_IWUSR, show_in_beep, store_in_beep, 5768c2ecf20Sopenharmony_ci 0, 1), 5778c2ecf20Sopenharmony_ci SENSOR_ATTR_2(in1_alarm, S_IRUGO, show_in_alarm, NULL, 0, 1), 5788c2ecf20Sopenharmony_ci}; 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_ci/* Fan / PWM attr common to all models */ 5818c2ecf20Sopenharmony_cistatic struct sensor_device_attribute_2 fxxxx_fan_attr[4][6] = { { 5828c2ecf20Sopenharmony_ci SENSOR_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0), 5838c2ecf20Sopenharmony_ci SENSOR_ATTR_2(fan1_full_speed, S_IRUGO|S_IWUSR, 5848c2ecf20Sopenharmony_ci show_fan_full_speed, 5858c2ecf20Sopenharmony_ci store_fan_full_speed, 0, 0), 5868c2ecf20Sopenharmony_ci SENSOR_ATTR_2(fan1_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 0), 5878c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 0), 5888c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_enable, S_IRUGO|S_IWUSR, show_pwm_enable, 5898c2ecf20Sopenharmony_ci store_pwm_enable, 0, 0), 5908c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_interpolate, S_IRUGO|S_IWUSR, 5918c2ecf20Sopenharmony_ci show_pwm_interpolate, store_pwm_interpolate, 0, 0), 5928c2ecf20Sopenharmony_ci}, { 5938c2ecf20Sopenharmony_ci SENSOR_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 0, 1), 5948c2ecf20Sopenharmony_ci SENSOR_ATTR_2(fan2_full_speed, S_IRUGO|S_IWUSR, 5958c2ecf20Sopenharmony_ci show_fan_full_speed, 5968c2ecf20Sopenharmony_ci store_fan_full_speed, 0, 1), 5978c2ecf20Sopenharmony_ci SENSOR_ATTR_2(fan2_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 1), 5988c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 1), 5998c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_enable, S_IRUGO|S_IWUSR, show_pwm_enable, 6008c2ecf20Sopenharmony_ci store_pwm_enable, 0, 1), 6018c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_interpolate, S_IRUGO|S_IWUSR, 6028c2ecf20Sopenharmony_ci show_pwm_interpolate, store_pwm_interpolate, 0, 1), 6038c2ecf20Sopenharmony_ci}, { 6048c2ecf20Sopenharmony_ci SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2), 6058c2ecf20Sopenharmony_ci SENSOR_ATTR_2(fan3_full_speed, S_IRUGO|S_IWUSR, 6068c2ecf20Sopenharmony_ci show_fan_full_speed, 6078c2ecf20Sopenharmony_ci store_fan_full_speed, 0, 2), 6088c2ecf20Sopenharmony_ci SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2), 6098c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2), 6108c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable, 6118c2ecf20Sopenharmony_ci store_pwm_enable, 0, 2), 6128c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR, 6138c2ecf20Sopenharmony_ci show_pwm_interpolate, store_pwm_interpolate, 0, 2), 6148c2ecf20Sopenharmony_ci}, { 6158c2ecf20Sopenharmony_ci SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3), 6168c2ecf20Sopenharmony_ci SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR, 6178c2ecf20Sopenharmony_ci show_fan_full_speed, 6188c2ecf20Sopenharmony_ci store_fan_full_speed, 0, 3), 6198c2ecf20Sopenharmony_ci SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3), 6208c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3), 6218c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable, 6228c2ecf20Sopenharmony_ci store_pwm_enable, 0, 3), 6238c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm4_interpolate, S_IRUGO|S_IWUSR, 6248c2ecf20Sopenharmony_ci show_pwm_interpolate, store_pwm_interpolate, 0, 3), 6258c2ecf20Sopenharmony_ci} }; 6268c2ecf20Sopenharmony_ci 6278c2ecf20Sopenharmony_ci/* Attr for the third fan of the f71808a, which only has manual pwm */ 6288c2ecf20Sopenharmony_cistatic struct sensor_device_attribute_2 f71808a_fan3_attr[] = { 6298c2ecf20Sopenharmony_ci SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2), 6308c2ecf20Sopenharmony_ci SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2), 6318c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, 6328c2ecf20Sopenharmony_ci show_simple_pwm, store_simple_pwm, 0, 2), 6338c2ecf20Sopenharmony_ci}; 6348c2ecf20Sopenharmony_ci 6358c2ecf20Sopenharmony_ci/* Attr for models which can beep on Fan alarm */ 6368c2ecf20Sopenharmony_cistatic struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = { 6378c2ecf20Sopenharmony_ci SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep, 6388c2ecf20Sopenharmony_ci store_fan_beep, 0, 0), 6398c2ecf20Sopenharmony_ci SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep, 6408c2ecf20Sopenharmony_ci store_fan_beep, 0, 1), 6418c2ecf20Sopenharmony_ci SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep, 6428c2ecf20Sopenharmony_ci store_fan_beep, 0, 2), 6438c2ecf20Sopenharmony_ci SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep, 6448c2ecf20Sopenharmony_ci store_fan_beep, 0, 3), 6458c2ecf20Sopenharmony_ci}; 6468c2ecf20Sopenharmony_ci 6478c2ecf20Sopenharmony_ci/* 6488c2ecf20Sopenharmony_ci * PWM attr for the f71862fg, fewer pwms and fewer zones per pwm than the 6498c2ecf20Sopenharmony_ci * standard models 6508c2ecf20Sopenharmony_ci */ 6518c2ecf20Sopenharmony_cistatic struct sensor_device_attribute_2 f71862fg_auto_pwm_attr[3][7] = { { 6528c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, 6538c2ecf20Sopenharmony_ci show_pwm_auto_point_channel, 6548c2ecf20Sopenharmony_ci store_pwm_auto_point_channel, 0, 0), 6558c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR, 6568c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 6578c2ecf20Sopenharmony_ci 1, 0), 6588c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR, 6598c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 6608c2ecf20Sopenharmony_ci 4, 0), 6618c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR, 6628c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 6638c2ecf20Sopenharmony_ci 0, 0), 6648c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR, 6658c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 6668c2ecf20Sopenharmony_ci 3, 0), 6678c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 6688c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, 6698c2ecf20Sopenharmony_ci store_pwm_auto_point_temp_hyst, 6708c2ecf20Sopenharmony_ci 0, 0), 6718c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO, 6728c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 3, 0), 6738c2ecf20Sopenharmony_ci}, { 6748c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR, 6758c2ecf20Sopenharmony_ci show_pwm_auto_point_channel, 6768c2ecf20Sopenharmony_ci store_pwm_auto_point_channel, 0, 1), 6778c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR, 6788c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 6798c2ecf20Sopenharmony_ci 1, 1), 6808c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR, 6818c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 6828c2ecf20Sopenharmony_ci 4, 1), 6838c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR, 6848c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 6858c2ecf20Sopenharmony_ci 0, 1), 6868c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR, 6878c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 6888c2ecf20Sopenharmony_ci 3, 1), 6898c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 6908c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, 6918c2ecf20Sopenharmony_ci store_pwm_auto_point_temp_hyst, 6928c2ecf20Sopenharmony_ci 0, 1), 6938c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO, 6948c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 3, 1), 6958c2ecf20Sopenharmony_ci}, { 6968c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR, 6978c2ecf20Sopenharmony_ci show_pwm_auto_point_channel, 6988c2ecf20Sopenharmony_ci store_pwm_auto_point_channel, 0, 2), 6998c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR, 7008c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 7018c2ecf20Sopenharmony_ci 1, 2), 7028c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR, 7038c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 7048c2ecf20Sopenharmony_ci 4, 2), 7058c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR, 7068c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 7078c2ecf20Sopenharmony_ci 0, 2), 7088c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR, 7098c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 7108c2ecf20Sopenharmony_ci 3, 2), 7118c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 7128c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, 7138c2ecf20Sopenharmony_ci store_pwm_auto_point_temp_hyst, 7148c2ecf20Sopenharmony_ci 0, 2), 7158c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO, 7168c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 3, 2), 7178c2ecf20Sopenharmony_ci} }; 7188c2ecf20Sopenharmony_ci 7198c2ecf20Sopenharmony_ci/* 7208c2ecf20Sopenharmony_ci * PWM attr for the f71808e/f71869, almost identical to the f71862fg, but the 7218c2ecf20Sopenharmony_ci * pwm setting when the temperature is above the pwmX_auto_point1_temp can be 7228c2ecf20Sopenharmony_ci * programmed instead of being hardcoded to 0xff 7238c2ecf20Sopenharmony_ci */ 7248c2ecf20Sopenharmony_cistatic struct sensor_device_attribute_2 f71869_auto_pwm_attr[3][8] = { { 7258c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, 7268c2ecf20Sopenharmony_ci show_pwm_auto_point_channel, 7278c2ecf20Sopenharmony_ci store_pwm_auto_point_channel, 0, 0), 7288c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR, 7298c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 7308c2ecf20Sopenharmony_ci 0, 0), 7318c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR, 7328c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 7338c2ecf20Sopenharmony_ci 1, 0), 7348c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR, 7358c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 7368c2ecf20Sopenharmony_ci 4, 0), 7378c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR, 7388c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 7398c2ecf20Sopenharmony_ci 0, 0), 7408c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR, 7418c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 7428c2ecf20Sopenharmony_ci 3, 0), 7438c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 7448c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, 7458c2ecf20Sopenharmony_ci store_pwm_auto_point_temp_hyst, 7468c2ecf20Sopenharmony_ci 0, 0), 7478c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO, 7488c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 3, 0), 7498c2ecf20Sopenharmony_ci}, { 7508c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR, 7518c2ecf20Sopenharmony_ci show_pwm_auto_point_channel, 7528c2ecf20Sopenharmony_ci store_pwm_auto_point_channel, 0, 1), 7538c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR, 7548c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 7558c2ecf20Sopenharmony_ci 0, 1), 7568c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR, 7578c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 7588c2ecf20Sopenharmony_ci 1, 1), 7598c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR, 7608c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 7618c2ecf20Sopenharmony_ci 4, 1), 7628c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR, 7638c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 7648c2ecf20Sopenharmony_ci 0, 1), 7658c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR, 7668c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 7678c2ecf20Sopenharmony_ci 3, 1), 7688c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 7698c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, 7708c2ecf20Sopenharmony_ci store_pwm_auto_point_temp_hyst, 7718c2ecf20Sopenharmony_ci 0, 1), 7728c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO, 7738c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 3, 1), 7748c2ecf20Sopenharmony_ci}, { 7758c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR, 7768c2ecf20Sopenharmony_ci show_pwm_auto_point_channel, 7778c2ecf20Sopenharmony_ci store_pwm_auto_point_channel, 0, 2), 7788c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR, 7798c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 7808c2ecf20Sopenharmony_ci 0, 2), 7818c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR, 7828c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 7838c2ecf20Sopenharmony_ci 1, 2), 7848c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR, 7858c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 7868c2ecf20Sopenharmony_ci 4, 2), 7878c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR, 7888c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 7898c2ecf20Sopenharmony_ci 0, 2), 7908c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR, 7918c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 7928c2ecf20Sopenharmony_ci 3, 2), 7938c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 7948c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, 7958c2ecf20Sopenharmony_ci store_pwm_auto_point_temp_hyst, 7968c2ecf20Sopenharmony_ci 0, 2), 7978c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO, 7988c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 3, 2), 7998c2ecf20Sopenharmony_ci} }; 8008c2ecf20Sopenharmony_ci 8018c2ecf20Sopenharmony_ci/* PWM attr for the standard models */ 8028c2ecf20Sopenharmony_cistatic struct sensor_device_attribute_2 fxxxx_auto_pwm_attr[4][14] = { { 8038c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, 8048c2ecf20Sopenharmony_ci show_pwm_auto_point_channel, 8058c2ecf20Sopenharmony_ci store_pwm_auto_point_channel, 0, 0), 8068c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR, 8078c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 8088c2ecf20Sopenharmony_ci 0, 0), 8098c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO|S_IWUSR, 8108c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 8118c2ecf20Sopenharmony_ci 1, 0), 8128c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO|S_IWUSR, 8138c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 8148c2ecf20Sopenharmony_ci 2, 0), 8158c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point4_pwm, S_IRUGO|S_IWUSR, 8168c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 8178c2ecf20Sopenharmony_ci 3, 0), 8188c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point5_pwm, S_IRUGO|S_IWUSR, 8198c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 8208c2ecf20Sopenharmony_ci 4, 0), 8218c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point1_temp, S_IRUGO|S_IWUSR, 8228c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 8238c2ecf20Sopenharmony_ci 0, 0), 8248c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point2_temp, S_IRUGO|S_IWUSR, 8258c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 8268c2ecf20Sopenharmony_ci 1, 0), 8278c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point3_temp, S_IRUGO|S_IWUSR, 8288c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 8298c2ecf20Sopenharmony_ci 2, 0), 8308c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point4_temp, S_IRUGO|S_IWUSR, 8318c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 8328c2ecf20Sopenharmony_ci 3, 0), 8338c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 8348c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, 8358c2ecf20Sopenharmony_ci store_pwm_auto_point_temp_hyst, 8368c2ecf20Sopenharmony_ci 0, 0), 8378c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point2_temp_hyst, S_IRUGO, 8388c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 1, 0), 8398c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point3_temp_hyst, S_IRUGO, 8408c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 2, 0), 8418c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_point4_temp_hyst, S_IRUGO, 8428c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 3, 0), 8438c2ecf20Sopenharmony_ci}, { 8448c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR, 8458c2ecf20Sopenharmony_ci show_pwm_auto_point_channel, 8468c2ecf20Sopenharmony_ci store_pwm_auto_point_channel, 0, 1), 8478c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO|S_IWUSR, 8488c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 8498c2ecf20Sopenharmony_ci 0, 1), 8508c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO|S_IWUSR, 8518c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 8528c2ecf20Sopenharmony_ci 1, 1), 8538c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO|S_IWUSR, 8548c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 8558c2ecf20Sopenharmony_ci 2, 1), 8568c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point4_pwm, S_IRUGO|S_IWUSR, 8578c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 8588c2ecf20Sopenharmony_ci 3, 1), 8598c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point5_pwm, S_IRUGO|S_IWUSR, 8608c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 8618c2ecf20Sopenharmony_ci 4, 1), 8628c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point1_temp, S_IRUGO|S_IWUSR, 8638c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 8648c2ecf20Sopenharmony_ci 0, 1), 8658c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point2_temp, S_IRUGO|S_IWUSR, 8668c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 8678c2ecf20Sopenharmony_ci 1, 1), 8688c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point3_temp, S_IRUGO|S_IWUSR, 8698c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 8708c2ecf20Sopenharmony_ci 2, 1), 8718c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point4_temp, S_IRUGO|S_IWUSR, 8728c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 8738c2ecf20Sopenharmony_ci 3, 1), 8748c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 8758c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, 8768c2ecf20Sopenharmony_ci store_pwm_auto_point_temp_hyst, 8778c2ecf20Sopenharmony_ci 0, 1), 8788c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO, 8798c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 1, 1), 8808c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point3_temp_hyst, S_IRUGO, 8818c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 2, 1), 8828c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO, 8838c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 3, 1), 8848c2ecf20Sopenharmony_ci}, { 8858c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR, 8868c2ecf20Sopenharmony_ci show_pwm_auto_point_channel, 8878c2ecf20Sopenharmony_ci store_pwm_auto_point_channel, 0, 2), 8888c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR, 8898c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 8908c2ecf20Sopenharmony_ci 0, 2), 8918c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO|S_IWUSR, 8928c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 8938c2ecf20Sopenharmony_ci 1, 2), 8948c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO|S_IWUSR, 8958c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 8968c2ecf20Sopenharmony_ci 2, 2), 8978c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point4_pwm, S_IRUGO|S_IWUSR, 8988c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 8998c2ecf20Sopenharmony_ci 3, 2), 9008c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point5_pwm, S_IRUGO|S_IWUSR, 9018c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 9028c2ecf20Sopenharmony_ci 4, 2), 9038c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point1_temp, S_IRUGO|S_IWUSR, 9048c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 9058c2ecf20Sopenharmony_ci 0, 2), 9068c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point2_temp, S_IRUGO|S_IWUSR, 9078c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 9088c2ecf20Sopenharmony_ci 1, 2), 9098c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point3_temp, S_IRUGO|S_IWUSR, 9108c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 9118c2ecf20Sopenharmony_ci 2, 2), 9128c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point4_temp, S_IRUGO|S_IWUSR, 9138c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 9148c2ecf20Sopenharmony_ci 3, 2), 9158c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 9168c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, 9178c2ecf20Sopenharmony_ci store_pwm_auto_point_temp_hyst, 9188c2ecf20Sopenharmony_ci 0, 2), 9198c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point2_temp_hyst, S_IRUGO, 9208c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 1, 2), 9218c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point3_temp_hyst, S_IRUGO, 9228c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 2, 2), 9238c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO, 9248c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 3, 2), 9258c2ecf20Sopenharmony_ci}, { 9268c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm4_auto_channels_temp, S_IRUGO|S_IWUSR, 9278c2ecf20Sopenharmony_ci show_pwm_auto_point_channel, 9288c2ecf20Sopenharmony_ci store_pwm_auto_point_channel, 0, 3), 9298c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm4_auto_point1_pwm, S_IRUGO|S_IWUSR, 9308c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 9318c2ecf20Sopenharmony_ci 0, 3), 9328c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm4_auto_point2_pwm, S_IRUGO|S_IWUSR, 9338c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 9348c2ecf20Sopenharmony_ci 1, 3), 9358c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm4_auto_point3_pwm, S_IRUGO|S_IWUSR, 9368c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 9378c2ecf20Sopenharmony_ci 2, 3), 9388c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm4_auto_point4_pwm, S_IRUGO|S_IWUSR, 9398c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 9408c2ecf20Sopenharmony_ci 3, 3), 9418c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm4_auto_point5_pwm, S_IRUGO|S_IWUSR, 9428c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 9438c2ecf20Sopenharmony_ci 4, 3), 9448c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm4_auto_point1_temp, S_IRUGO|S_IWUSR, 9458c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 9468c2ecf20Sopenharmony_ci 0, 3), 9478c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm4_auto_point2_temp, S_IRUGO|S_IWUSR, 9488c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 9498c2ecf20Sopenharmony_ci 1, 3), 9508c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm4_auto_point3_temp, S_IRUGO|S_IWUSR, 9518c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 9528c2ecf20Sopenharmony_ci 2, 3), 9538c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm4_auto_point4_temp, S_IRUGO|S_IWUSR, 9548c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 9558c2ecf20Sopenharmony_ci 3, 3), 9568c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm4_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 9578c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, 9588c2ecf20Sopenharmony_ci store_pwm_auto_point_temp_hyst, 9598c2ecf20Sopenharmony_ci 0, 3), 9608c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm4_auto_point2_temp_hyst, S_IRUGO, 9618c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 1, 3), 9628c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm4_auto_point3_temp_hyst, S_IRUGO, 9638c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 2, 3), 9648c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm4_auto_point4_temp_hyst, S_IRUGO, 9658c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 3, 3), 9668c2ecf20Sopenharmony_ci} }; 9678c2ecf20Sopenharmony_ci 9688c2ecf20Sopenharmony_ci/* Fan attr specific to the f8000 (4th fan input can only measure speed) */ 9698c2ecf20Sopenharmony_cistatic struct sensor_device_attribute_2 f8000_fan_attr[] = { 9708c2ecf20Sopenharmony_ci SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3), 9718c2ecf20Sopenharmony_ci}; 9728c2ecf20Sopenharmony_ci 9738c2ecf20Sopenharmony_ci/* 9748c2ecf20Sopenharmony_ci * PWM attr for the f8000, zones mapped to temp instead of to pwm! 9758c2ecf20Sopenharmony_ci * Also the register block at offset A0 maps to TEMP1 (so our temp2, as the 9768c2ecf20Sopenharmony_ci * F8000 starts counting temps at 0), B0 maps the TEMP2 and C0 maps to TEMP0 9778c2ecf20Sopenharmony_ci */ 9788c2ecf20Sopenharmony_cistatic struct sensor_device_attribute_2 f8000_auto_pwm_attr[3][14] = { { 9798c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm1_auto_channels_temp, S_IRUGO|S_IWUSR, 9808c2ecf20Sopenharmony_ci show_pwm_auto_point_channel, 9818c2ecf20Sopenharmony_ci store_pwm_auto_point_channel, 0, 0), 9828c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR, 9838c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 9848c2ecf20Sopenharmony_ci 0, 2), 9858c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_auto_point2_pwm, S_IRUGO|S_IWUSR, 9868c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 9878c2ecf20Sopenharmony_ci 1, 2), 9888c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_auto_point3_pwm, S_IRUGO|S_IWUSR, 9898c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 9908c2ecf20Sopenharmony_ci 2, 2), 9918c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_auto_point4_pwm, S_IRUGO|S_IWUSR, 9928c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 9938c2ecf20Sopenharmony_ci 3, 2), 9948c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_auto_point5_pwm, S_IRUGO|S_IWUSR, 9958c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 9968c2ecf20Sopenharmony_ci 4, 2), 9978c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_auto_point1_temp, S_IRUGO|S_IWUSR, 9988c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 9998c2ecf20Sopenharmony_ci 0, 2), 10008c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_auto_point2_temp, S_IRUGO|S_IWUSR, 10018c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 10028c2ecf20Sopenharmony_ci 1, 2), 10038c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_auto_point3_temp, S_IRUGO|S_IWUSR, 10048c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 10058c2ecf20Sopenharmony_ci 2, 2), 10068c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_auto_point4_temp, S_IRUGO|S_IWUSR, 10078c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 10088c2ecf20Sopenharmony_ci 3, 2), 10098c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 10108c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, 10118c2ecf20Sopenharmony_ci store_pwm_auto_point_temp_hyst, 10128c2ecf20Sopenharmony_ci 0, 2), 10138c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_auto_point2_temp_hyst, S_IRUGO, 10148c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 1, 2), 10158c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_auto_point3_temp_hyst, S_IRUGO, 10168c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 2, 2), 10178c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp1_auto_point4_temp_hyst, S_IRUGO, 10188c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 3, 2), 10198c2ecf20Sopenharmony_ci}, { 10208c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm2_auto_channels_temp, S_IRUGO|S_IWUSR, 10218c2ecf20Sopenharmony_ci show_pwm_auto_point_channel, 10228c2ecf20Sopenharmony_ci store_pwm_auto_point_channel, 0, 1), 10238c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_auto_point1_pwm, S_IRUGO|S_IWUSR, 10248c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 10258c2ecf20Sopenharmony_ci 0, 0), 10268c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_auto_point2_pwm, S_IRUGO|S_IWUSR, 10278c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 10288c2ecf20Sopenharmony_ci 1, 0), 10298c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_auto_point3_pwm, S_IRUGO|S_IWUSR, 10308c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 10318c2ecf20Sopenharmony_ci 2, 0), 10328c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_auto_point4_pwm, S_IRUGO|S_IWUSR, 10338c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 10348c2ecf20Sopenharmony_ci 3, 0), 10358c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_auto_point5_pwm, S_IRUGO|S_IWUSR, 10368c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 10378c2ecf20Sopenharmony_ci 4, 0), 10388c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_auto_point1_temp, S_IRUGO|S_IWUSR, 10398c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 10408c2ecf20Sopenharmony_ci 0, 0), 10418c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_auto_point2_temp, S_IRUGO|S_IWUSR, 10428c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 10438c2ecf20Sopenharmony_ci 1, 0), 10448c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_auto_point3_temp, S_IRUGO|S_IWUSR, 10458c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 10468c2ecf20Sopenharmony_ci 2, 0), 10478c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_auto_point4_temp, S_IRUGO|S_IWUSR, 10488c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 10498c2ecf20Sopenharmony_ci 3, 0), 10508c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 10518c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, 10528c2ecf20Sopenharmony_ci store_pwm_auto_point_temp_hyst, 10538c2ecf20Sopenharmony_ci 0, 0), 10548c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_auto_point2_temp_hyst, S_IRUGO, 10558c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 1, 0), 10568c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_auto_point3_temp_hyst, S_IRUGO, 10578c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 2, 0), 10588c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp2_auto_point4_temp_hyst, S_IRUGO, 10598c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 3, 0), 10608c2ecf20Sopenharmony_ci}, { 10618c2ecf20Sopenharmony_ci SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR, 10628c2ecf20Sopenharmony_ci show_pwm_auto_point_channel, 10638c2ecf20Sopenharmony_ci store_pwm_auto_point_channel, 0, 2), 10648c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_auto_point1_pwm, S_IRUGO|S_IWUSR, 10658c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 10668c2ecf20Sopenharmony_ci 0, 1), 10678c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_auto_point2_pwm, S_IRUGO|S_IWUSR, 10688c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 10698c2ecf20Sopenharmony_ci 1, 1), 10708c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_auto_point3_pwm, S_IRUGO|S_IWUSR, 10718c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 10728c2ecf20Sopenharmony_ci 2, 1), 10738c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_auto_point4_pwm, S_IRUGO|S_IWUSR, 10748c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 10758c2ecf20Sopenharmony_ci 3, 1), 10768c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_auto_point5_pwm, S_IRUGO|S_IWUSR, 10778c2ecf20Sopenharmony_ci show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 10788c2ecf20Sopenharmony_ci 4, 1), 10798c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_auto_point1_temp, S_IRUGO|S_IWUSR, 10808c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 10818c2ecf20Sopenharmony_ci 0, 1), 10828c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_auto_point2_temp, S_IRUGO|S_IWUSR, 10838c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 10848c2ecf20Sopenharmony_ci 1, 1), 10858c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_auto_point3_temp, S_IRUGO|S_IWUSR, 10868c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 10878c2ecf20Sopenharmony_ci 2, 1), 10888c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_auto_point4_temp, S_IRUGO|S_IWUSR, 10898c2ecf20Sopenharmony_ci show_pwm_auto_point_temp, store_pwm_auto_point_temp, 10908c2ecf20Sopenharmony_ci 3, 1), 10918c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_auto_point1_temp_hyst, S_IRUGO|S_IWUSR, 10928c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, 10938c2ecf20Sopenharmony_ci store_pwm_auto_point_temp_hyst, 10948c2ecf20Sopenharmony_ci 0, 1), 10958c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_auto_point2_temp_hyst, S_IRUGO, 10968c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 1, 1), 10978c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_auto_point3_temp_hyst, S_IRUGO, 10988c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 2, 1), 10998c2ecf20Sopenharmony_ci SENSOR_ATTR_2(temp3_auto_point4_temp_hyst, S_IRUGO, 11008c2ecf20Sopenharmony_ci show_pwm_auto_point_temp_hyst, NULL, 3, 1), 11018c2ecf20Sopenharmony_ci} }; 11028c2ecf20Sopenharmony_ci 11038c2ecf20Sopenharmony_ci/* Super I/O functions */ 11048c2ecf20Sopenharmony_cistatic inline int superio_inb(int base, int reg) 11058c2ecf20Sopenharmony_ci{ 11068c2ecf20Sopenharmony_ci outb(reg, base); 11078c2ecf20Sopenharmony_ci return inb(base + 1); 11088c2ecf20Sopenharmony_ci} 11098c2ecf20Sopenharmony_ci 11108c2ecf20Sopenharmony_cistatic int superio_inw(int base, int reg) 11118c2ecf20Sopenharmony_ci{ 11128c2ecf20Sopenharmony_ci int val; 11138c2ecf20Sopenharmony_ci val = superio_inb(base, reg) << 8; 11148c2ecf20Sopenharmony_ci val |= superio_inb(base, reg + 1); 11158c2ecf20Sopenharmony_ci return val; 11168c2ecf20Sopenharmony_ci} 11178c2ecf20Sopenharmony_ci 11188c2ecf20Sopenharmony_cistatic inline int superio_enter(int base) 11198c2ecf20Sopenharmony_ci{ 11208c2ecf20Sopenharmony_ci /* Don't step on other drivers' I/O space by accident */ 11218c2ecf20Sopenharmony_ci if (!request_muxed_region(base, 2, DRVNAME)) { 11228c2ecf20Sopenharmony_ci pr_err("I/O address 0x%04x already in use\n", base); 11238c2ecf20Sopenharmony_ci return -EBUSY; 11248c2ecf20Sopenharmony_ci } 11258c2ecf20Sopenharmony_ci 11268c2ecf20Sopenharmony_ci /* according to the datasheet the key must be send twice! */ 11278c2ecf20Sopenharmony_ci outb(SIO_UNLOCK_KEY, base); 11288c2ecf20Sopenharmony_ci outb(SIO_UNLOCK_KEY, base); 11298c2ecf20Sopenharmony_ci 11308c2ecf20Sopenharmony_ci return 0; 11318c2ecf20Sopenharmony_ci} 11328c2ecf20Sopenharmony_ci 11338c2ecf20Sopenharmony_cistatic inline void superio_select(int base, int ld) 11348c2ecf20Sopenharmony_ci{ 11358c2ecf20Sopenharmony_ci outb(SIO_REG_LDSEL, base); 11368c2ecf20Sopenharmony_ci outb(ld, base + 1); 11378c2ecf20Sopenharmony_ci} 11388c2ecf20Sopenharmony_ci 11398c2ecf20Sopenharmony_cistatic inline void superio_exit(int base) 11408c2ecf20Sopenharmony_ci{ 11418c2ecf20Sopenharmony_ci outb(SIO_LOCK_KEY, base); 11428c2ecf20Sopenharmony_ci release_region(base, 2); 11438c2ecf20Sopenharmony_ci} 11448c2ecf20Sopenharmony_ci 11458c2ecf20Sopenharmony_cistatic inline int fan_from_reg(u16 reg) 11468c2ecf20Sopenharmony_ci{ 11478c2ecf20Sopenharmony_ci return reg ? (1500000 / reg) : 0; 11488c2ecf20Sopenharmony_ci} 11498c2ecf20Sopenharmony_ci 11508c2ecf20Sopenharmony_cistatic inline u16 fan_to_reg(int fan) 11518c2ecf20Sopenharmony_ci{ 11528c2ecf20Sopenharmony_ci return fan ? (1500000 / fan) : 0; 11538c2ecf20Sopenharmony_ci} 11548c2ecf20Sopenharmony_ci 11558c2ecf20Sopenharmony_cistatic u8 f71882fg_read8(struct f71882fg_data *data, u8 reg) 11568c2ecf20Sopenharmony_ci{ 11578c2ecf20Sopenharmony_ci u8 val; 11588c2ecf20Sopenharmony_ci 11598c2ecf20Sopenharmony_ci outb(reg, data->addr + ADDR_REG_OFFSET); 11608c2ecf20Sopenharmony_ci val = inb(data->addr + DATA_REG_OFFSET); 11618c2ecf20Sopenharmony_ci 11628c2ecf20Sopenharmony_ci return val; 11638c2ecf20Sopenharmony_ci} 11648c2ecf20Sopenharmony_ci 11658c2ecf20Sopenharmony_cistatic u16 f71882fg_read16(struct f71882fg_data *data, u8 reg) 11668c2ecf20Sopenharmony_ci{ 11678c2ecf20Sopenharmony_ci u16 val; 11688c2ecf20Sopenharmony_ci 11698c2ecf20Sopenharmony_ci val = f71882fg_read8(data, reg) << 8; 11708c2ecf20Sopenharmony_ci val |= f71882fg_read8(data, reg + 1); 11718c2ecf20Sopenharmony_ci 11728c2ecf20Sopenharmony_ci return val; 11738c2ecf20Sopenharmony_ci} 11748c2ecf20Sopenharmony_ci 11758c2ecf20Sopenharmony_cistatic void f71882fg_write8(struct f71882fg_data *data, u8 reg, u8 val) 11768c2ecf20Sopenharmony_ci{ 11778c2ecf20Sopenharmony_ci outb(reg, data->addr + ADDR_REG_OFFSET); 11788c2ecf20Sopenharmony_ci outb(val, data->addr + DATA_REG_OFFSET); 11798c2ecf20Sopenharmony_ci} 11808c2ecf20Sopenharmony_ci 11818c2ecf20Sopenharmony_cistatic void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val) 11828c2ecf20Sopenharmony_ci{ 11838c2ecf20Sopenharmony_ci f71882fg_write8(data, reg, val >> 8); 11848c2ecf20Sopenharmony_ci f71882fg_write8(data, reg + 1, val & 0xff); 11858c2ecf20Sopenharmony_ci} 11868c2ecf20Sopenharmony_ci 11878c2ecf20Sopenharmony_cistatic u16 f71882fg_read_temp(struct f71882fg_data *data, int nr) 11888c2ecf20Sopenharmony_ci{ 11898c2ecf20Sopenharmony_ci if (data->type == f71858fg) 11908c2ecf20Sopenharmony_ci return f71882fg_read16(data, F71882FG_REG_TEMP(nr)); 11918c2ecf20Sopenharmony_ci else 11928c2ecf20Sopenharmony_ci return f71882fg_read8(data, F71882FG_REG_TEMP(nr)); 11938c2ecf20Sopenharmony_ci} 11948c2ecf20Sopenharmony_ci 11958c2ecf20Sopenharmony_cistatic struct f71882fg_data *f71882fg_update_device(struct device *dev) 11968c2ecf20Sopenharmony_ci{ 11978c2ecf20Sopenharmony_ci struct f71882fg_data *data = dev_get_drvdata(dev); 11988c2ecf20Sopenharmony_ci int nr_fans = f71882fg_nr_fans[data->type]; 11998c2ecf20Sopenharmony_ci int nr_temps = f71882fg_nr_temps[data->type]; 12008c2ecf20Sopenharmony_ci int nr, reg, point; 12018c2ecf20Sopenharmony_ci 12028c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 12038c2ecf20Sopenharmony_ci 12048c2ecf20Sopenharmony_ci /* Update once every 60 seconds */ 12058c2ecf20Sopenharmony_ci if (time_after(jiffies, data->last_limits + 60 * HZ) || 12068c2ecf20Sopenharmony_ci !data->valid) { 12078c2ecf20Sopenharmony_ci if (f71882fg_has_in1_alarm[data->type]) { 12088c2ecf20Sopenharmony_ci if (data->type == f81866a) { 12098c2ecf20Sopenharmony_ci data->in1_max = 12108c2ecf20Sopenharmony_ci f71882fg_read8(data, 12118c2ecf20Sopenharmony_ci F81866_REG_IN1_HIGH); 12128c2ecf20Sopenharmony_ci data->in_beep = 12138c2ecf20Sopenharmony_ci f71882fg_read8(data, 12148c2ecf20Sopenharmony_ci F81866_REG_IN_BEEP); 12158c2ecf20Sopenharmony_ci } else { 12168c2ecf20Sopenharmony_ci data->in1_max = 12178c2ecf20Sopenharmony_ci f71882fg_read8(data, 12188c2ecf20Sopenharmony_ci F71882FG_REG_IN1_HIGH); 12198c2ecf20Sopenharmony_ci data->in_beep = 12208c2ecf20Sopenharmony_ci f71882fg_read8(data, 12218c2ecf20Sopenharmony_ci F71882FG_REG_IN_BEEP); 12228c2ecf20Sopenharmony_ci } 12238c2ecf20Sopenharmony_ci } 12248c2ecf20Sopenharmony_ci 12258c2ecf20Sopenharmony_ci /* Get High & boundary temps*/ 12268c2ecf20Sopenharmony_ci for (nr = data->temp_start; nr < nr_temps + data->temp_start; 12278c2ecf20Sopenharmony_ci nr++) { 12288c2ecf20Sopenharmony_ci data->temp_ovt[nr] = f71882fg_read8(data, 12298c2ecf20Sopenharmony_ci F71882FG_REG_TEMP_OVT(nr)); 12308c2ecf20Sopenharmony_ci data->temp_high[nr] = f71882fg_read8(data, 12318c2ecf20Sopenharmony_ci F71882FG_REG_TEMP_HIGH(nr)); 12328c2ecf20Sopenharmony_ci } 12338c2ecf20Sopenharmony_ci 12348c2ecf20Sopenharmony_ci if (data->type != f8000) { 12358c2ecf20Sopenharmony_ci data->temp_hyst[0] = f71882fg_read8(data, 12368c2ecf20Sopenharmony_ci F71882FG_REG_TEMP_HYST(0)); 12378c2ecf20Sopenharmony_ci data->temp_hyst[1] = f71882fg_read8(data, 12388c2ecf20Sopenharmony_ci F71882FG_REG_TEMP_HYST(1)); 12398c2ecf20Sopenharmony_ci } 12408c2ecf20Sopenharmony_ci /* All but the f71858fg / f8000 have this register */ 12418c2ecf20Sopenharmony_ci if ((data->type != f71858fg) && (data->type != f8000)) { 12428c2ecf20Sopenharmony_ci reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE); 12438c2ecf20Sopenharmony_ci data->temp_type[1] = (reg & 0x02) ? 2 : 4; 12448c2ecf20Sopenharmony_ci data->temp_type[2] = (reg & 0x04) ? 2 : 4; 12458c2ecf20Sopenharmony_ci data->temp_type[3] = (reg & 0x08) ? 2 : 4; 12468c2ecf20Sopenharmony_ci } 12478c2ecf20Sopenharmony_ci 12488c2ecf20Sopenharmony_ci if (f71882fg_fan_has_beep[data->type]) 12498c2ecf20Sopenharmony_ci data->fan_beep = f71882fg_read8(data, 12508c2ecf20Sopenharmony_ci F71882FG_REG_FAN_BEEP); 12518c2ecf20Sopenharmony_ci 12528c2ecf20Sopenharmony_ci if (f71882fg_temp_has_beep[data->type]) 12538c2ecf20Sopenharmony_ci data->temp_beep = f71882fg_read8(data, 12548c2ecf20Sopenharmony_ci F71882FG_REG_TEMP_BEEP); 12558c2ecf20Sopenharmony_ci 12568c2ecf20Sopenharmony_ci data->pwm_enable = f71882fg_read8(data, 12578c2ecf20Sopenharmony_ci F71882FG_REG_PWM_ENABLE); 12588c2ecf20Sopenharmony_ci data->pwm_auto_point_hyst[0] = 12598c2ecf20Sopenharmony_ci f71882fg_read8(data, F71882FG_REG_FAN_HYST(0)); 12608c2ecf20Sopenharmony_ci data->pwm_auto_point_hyst[1] = 12618c2ecf20Sopenharmony_ci f71882fg_read8(data, F71882FG_REG_FAN_HYST(1)); 12628c2ecf20Sopenharmony_ci 12638c2ecf20Sopenharmony_ci for (nr = 0; nr < nr_fans; nr++) { 12648c2ecf20Sopenharmony_ci data->pwm_auto_point_mapping[nr] = 12658c2ecf20Sopenharmony_ci f71882fg_read8(data, 12668c2ecf20Sopenharmony_ci F71882FG_REG_POINT_MAPPING(nr)); 12678c2ecf20Sopenharmony_ci 12688c2ecf20Sopenharmony_ci switch (data->type) { 12698c2ecf20Sopenharmony_ci default: 12708c2ecf20Sopenharmony_ci for (point = 0; point < 5; point++) { 12718c2ecf20Sopenharmony_ci data->pwm_auto_point_pwm[nr][point] = 12728c2ecf20Sopenharmony_ci f71882fg_read8(data, 12738c2ecf20Sopenharmony_ci F71882FG_REG_POINT_PWM 12748c2ecf20Sopenharmony_ci (nr, point)); 12758c2ecf20Sopenharmony_ci } 12768c2ecf20Sopenharmony_ci for (point = 0; point < 4; point++) { 12778c2ecf20Sopenharmony_ci data->pwm_auto_point_temp[nr][point] = 12788c2ecf20Sopenharmony_ci f71882fg_read8(data, 12798c2ecf20Sopenharmony_ci F71882FG_REG_POINT_TEMP 12808c2ecf20Sopenharmony_ci (nr, point)); 12818c2ecf20Sopenharmony_ci } 12828c2ecf20Sopenharmony_ci break; 12838c2ecf20Sopenharmony_ci case f71808e: 12848c2ecf20Sopenharmony_ci case f71869: 12858c2ecf20Sopenharmony_ci data->pwm_auto_point_pwm[nr][0] = 12868c2ecf20Sopenharmony_ci f71882fg_read8(data, 12878c2ecf20Sopenharmony_ci F71882FG_REG_POINT_PWM(nr, 0)); 12888c2ecf20Sopenharmony_ci fallthrough; 12898c2ecf20Sopenharmony_ci case f71862fg: 12908c2ecf20Sopenharmony_ci data->pwm_auto_point_pwm[nr][1] = 12918c2ecf20Sopenharmony_ci f71882fg_read8(data, 12928c2ecf20Sopenharmony_ci F71882FG_REG_POINT_PWM 12938c2ecf20Sopenharmony_ci (nr, 1)); 12948c2ecf20Sopenharmony_ci data->pwm_auto_point_pwm[nr][4] = 12958c2ecf20Sopenharmony_ci f71882fg_read8(data, 12968c2ecf20Sopenharmony_ci F71882FG_REG_POINT_PWM 12978c2ecf20Sopenharmony_ci (nr, 4)); 12988c2ecf20Sopenharmony_ci data->pwm_auto_point_temp[nr][0] = 12998c2ecf20Sopenharmony_ci f71882fg_read8(data, 13008c2ecf20Sopenharmony_ci F71882FG_REG_POINT_TEMP 13018c2ecf20Sopenharmony_ci (nr, 0)); 13028c2ecf20Sopenharmony_ci data->pwm_auto_point_temp[nr][3] = 13038c2ecf20Sopenharmony_ci f71882fg_read8(data, 13048c2ecf20Sopenharmony_ci F71882FG_REG_POINT_TEMP 13058c2ecf20Sopenharmony_ci (nr, 3)); 13068c2ecf20Sopenharmony_ci break; 13078c2ecf20Sopenharmony_ci } 13088c2ecf20Sopenharmony_ci } 13098c2ecf20Sopenharmony_ci data->last_limits = jiffies; 13108c2ecf20Sopenharmony_ci } 13118c2ecf20Sopenharmony_ci 13128c2ecf20Sopenharmony_ci /* Update every second */ 13138c2ecf20Sopenharmony_ci if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { 13148c2ecf20Sopenharmony_ci data->temp_status = f71882fg_read8(data, 13158c2ecf20Sopenharmony_ci F71882FG_REG_TEMP_STATUS); 13168c2ecf20Sopenharmony_ci data->temp_diode_open = f71882fg_read8(data, 13178c2ecf20Sopenharmony_ci F71882FG_REG_TEMP_DIODE_OPEN); 13188c2ecf20Sopenharmony_ci for (nr = data->temp_start; nr < nr_temps + data->temp_start; 13198c2ecf20Sopenharmony_ci nr++) 13208c2ecf20Sopenharmony_ci data->temp[nr] = f71882fg_read_temp(data, nr); 13218c2ecf20Sopenharmony_ci 13228c2ecf20Sopenharmony_ci data->fan_status = f71882fg_read8(data, 13238c2ecf20Sopenharmony_ci F71882FG_REG_FAN_STATUS); 13248c2ecf20Sopenharmony_ci for (nr = 0; nr < nr_fans; nr++) { 13258c2ecf20Sopenharmony_ci data->fan[nr] = f71882fg_read16(data, 13268c2ecf20Sopenharmony_ci F71882FG_REG_FAN(nr)); 13278c2ecf20Sopenharmony_ci data->fan_target[nr] = 13288c2ecf20Sopenharmony_ci f71882fg_read16(data, F71882FG_REG_FAN_TARGET(nr)); 13298c2ecf20Sopenharmony_ci data->fan_full_speed[nr] = 13308c2ecf20Sopenharmony_ci f71882fg_read16(data, 13318c2ecf20Sopenharmony_ci F71882FG_REG_FAN_FULL_SPEED(nr)); 13328c2ecf20Sopenharmony_ci data->pwm[nr] = 13338c2ecf20Sopenharmony_ci f71882fg_read8(data, F71882FG_REG_PWM(nr)); 13348c2ecf20Sopenharmony_ci } 13358c2ecf20Sopenharmony_ci /* Some models have 1 more fan with limited capabilities */ 13368c2ecf20Sopenharmony_ci if (data->type == f71808a) { 13378c2ecf20Sopenharmony_ci data->fan[2] = f71882fg_read16(data, 13388c2ecf20Sopenharmony_ci F71882FG_REG_FAN(2)); 13398c2ecf20Sopenharmony_ci data->pwm[2] = f71882fg_read8(data, 13408c2ecf20Sopenharmony_ci F71882FG_REG_PWM(2)); 13418c2ecf20Sopenharmony_ci } 13428c2ecf20Sopenharmony_ci if (data->type == f8000) 13438c2ecf20Sopenharmony_ci data->fan[3] = f71882fg_read16(data, 13448c2ecf20Sopenharmony_ci F71882FG_REG_FAN(3)); 13458c2ecf20Sopenharmony_ci 13468c2ecf20Sopenharmony_ci if (f71882fg_has_in1_alarm[data->type]) { 13478c2ecf20Sopenharmony_ci if (data->type == f81866a) 13488c2ecf20Sopenharmony_ci data->in_status = f71882fg_read8(data, 13498c2ecf20Sopenharmony_ci F81866_REG_IN_STATUS); 13508c2ecf20Sopenharmony_ci 13518c2ecf20Sopenharmony_ci else 13528c2ecf20Sopenharmony_ci data->in_status = f71882fg_read8(data, 13538c2ecf20Sopenharmony_ci F71882FG_REG_IN_STATUS); 13548c2ecf20Sopenharmony_ci } 13558c2ecf20Sopenharmony_ci 13568c2ecf20Sopenharmony_ci for (nr = 0; nr < F71882FG_MAX_INS; nr++) 13578c2ecf20Sopenharmony_ci if (f71882fg_has_in[data->type][nr]) 13588c2ecf20Sopenharmony_ci data->in[nr] = f71882fg_read8(data, 13598c2ecf20Sopenharmony_ci F71882FG_REG_IN(nr)); 13608c2ecf20Sopenharmony_ci 13618c2ecf20Sopenharmony_ci data->last_updated = jiffies; 13628c2ecf20Sopenharmony_ci data->valid = 1; 13638c2ecf20Sopenharmony_ci } 13648c2ecf20Sopenharmony_ci 13658c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 13668c2ecf20Sopenharmony_ci 13678c2ecf20Sopenharmony_ci return data; 13688c2ecf20Sopenharmony_ci} 13698c2ecf20Sopenharmony_ci 13708c2ecf20Sopenharmony_ci/* Sysfs Interface */ 13718c2ecf20Sopenharmony_cistatic ssize_t show_fan(struct device *dev, struct device_attribute *devattr, 13728c2ecf20Sopenharmony_ci char *buf) 13738c2ecf20Sopenharmony_ci{ 13748c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 13758c2ecf20Sopenharmony_ci int nr = to_sensor_dev_attr_2(devattr)->index; 13768c2ecf20Sopenharmony_ci int speed = fan_from_reg(data->fan[nr]); 13778c2ecf20Sopenharmony_ci 13788c2ecf20Sopenharmony_ci if (speed == FAN_MIN_DETECT) 13798c2ecf20Sopenharmony_ci speed = 0; 13808c2ecf20Sopenharmony_ci 13818c2ecf20Sopenharmony_ci return sprintf(buf, "%d\n", speed); 13828c2ecf20Sopenharmony_ci} 13838c2ecf20Sopenharmony_ci 13848c2ecf20Sopenharmony_cistatic ssize_t show_fan_full_speed(struct device *dev, 13858c2ecf20Sopenharmony_ci struct device_attribute *devattr, char *buf) 13868c2ecf20Sopenharmony_ci{ 13878c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 13888c2ecf20Sopenharmony_ci int nr = to_sensor_dev_attr_2(devattr)->index; 13898c2ecf20Sopenharmony_ci int speed = fan_from_reg(data->fan_full_speed[nr]); 13908c2ecf20Sopenharmony_ci return sprintf(buf, "%d\n", speed); 13918c2ecf20Sopenharmony_ci} 13928c2ecf20Sopenharmony_ci 13938c2ecf20Sopenharmony_cistatic ssize_t store_fan_full_speed(struct device *dev, 13948c2ecf20Sopenharmony_ci struct device_attribute *devattr, 13958c2ecf20Sopenharmony_ci const char *buf, size_t count) 13968c2ecf20Sopenharmony_ci{ 13978c2ecf20Sopenharmony_ci struct f71882fg_data *data = dev_get_drvdata(dev); 13988c2ecf20Sopenharmony_ci int err, nr = to_sensor_dev_attr_2(devattr)->index; 13998c2ecf20Sopenharmony_ci long val; 14008c2ecf20Sopenharmony_ci 14018c2ecf20Sopenharmony_ci err = kstrtol(buf, 10, &val); 14028c2ecf20Sopenharmony_ci if (err) 14038c2ecf20Sopenharmony_ci return err; 14048c2ecf20Sopenharmony_ci 14058c2ecf20Sopenharmony_ci val = clamp_val(val, 23, 1500000); 14068c2ecf20Sopenharmony_ci val = fan_to_reg(val); 14078c2ecf20Sopenharmony_ci 14088c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 14098c2ecf20Sopenharmony_ci f71882fg_write16(data, F71882FG_REG_FAN_FULL_SPEED(nr), val); 14108c2ecf20Sopenharmony_ci data->fan_full_speed[nr] = val; 14118c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 14128c2ecf20Sopenharmony_ci 14138c2ecf20Sopenharmony_ci return count; 14148c2ecf20Sopenharmony_ci} 14158c2ecf20Sopenharmony_ci 14168c2ecf20Sopenharmony_cistatic ssize_t show_fan_beep(struct device *dev, struct device_attribute 14178c2ecf20Sopenharmony_ci *devattr, char *buf) 14188c2ecf20Sopenharmony_ci{ 14198c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 14208c2ecf20Sopenharmony_ci int nr = to_sensor_dev_attr_2(devattr)->index; 14218c2ecf20Sopenharmony_ci 14228c2ecf20Sopenharmony_ci if (data->fan_beep & (1 << nr)) 14238c2ecf20Sopenharmony_ci return sprintf(buf, "1\n"); 14248c2ecf20Sopenharmony_ci else 14258c2ecf20Sopenharmony_ci return sprintf(buf, "0\n"); 14268c2ecf20Sopenharmony_ci} 14278c2ecf20Sopenharmony_ci 14288c2ecf20Sopenharmony_cistatic ssize_t store_fan_beep(struct device *dev, struct device_attribute 14298c2ecf20Sopenharmony_ci *devattr, const char *buf, size_t count) 14308c2ecf20Sopenharmony_ci{ 14318c2ecf20Sopenharmony_ci struct f71882fg_data *data = dev_get_drvdata(dev); 14328c2ecf20Sopenharmony_ci int err, nr = to_sensor_dev_attr_2(devattr)->index; 14338c2ecf20Sopenharmony_ci unsigned long val; 14348c2ecf20Sopenharmony_ci 14358c2ecf20Sopenharmony_ci err = kstrtoul(buf, 10, &val); 14368c2ecf20Sopenharmony_ci if (err) 14378c2ecf20Sopenharmony_ci return err; 14388c2ecf20Sopenharmony_ci 14398c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 14408c2ecf20Sopenharmony_ci data->fan_beep = f71882fg_read8(data, F71882FG_REG_FAN_BEEP); 14418c2ecf20Sopenharmony_ci if (val) 14428c2ecf20Sopenharmony_ci data->fan_beep |= 1 << nr; 14438c2ecf20Sopenharmony_ci else 14448c2ecf20Sopenharmony_ci data->fan_beep &= ~(1 << nr); 14458c2ecf20Sopenharmony_ci 14468c2ecf20Sopenharmony_ci f71882fg_write8(data, F71882FG_REG_FAN_BEEP, data->fan_beep); 14478c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 14488c2ecf20Sopenharmony_ci 14498c2ecf20Sopenharmony_ci return count; 14508c2ecf20Sopenharmony_ci} 14518c2ecf20Sopenharmony_ci 14528c2ecf20Sopenharmony_cistatic ssize_t show_fan_alarm(struct device *dev, struct device_attribute 14538c2ecf20Sopenharmony_ci *devattr, char *buf) 14548c2ecf20Sopenharmony_ci{ 14558c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 14568c2ecf20Sopenharmony_ci int nr = to_sensor_dev_attr_2(devattr)->index; 14578c2ecf20Sopenharmony_ci 14588c2ecf20Sopenharmony_ci if (data->fan_status & (1 << nr)) 14598c2ecf20Sopenharmony_ci return sprintf(buf, "1\n"); 14608c2ecf20Sopenharmony_ci else 14618c2ecf20Sopenharmony_ci return sprintf(buf, "0\n"); 14628c2ecf20Sopenharmony_ci} 14638c2ecf20Sopenharmony_ci 14648c2ecf20Sopenharmony_cistatic ssize_t show_in(struct device *dev, struct device_attribute *devattr, 14658c2ecf20Sopenharmony_ci char *buf) 14668c2ecf20Sopenharmony_ci{ 14678c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 14688c2ecf20Sopenharmony_ci int nr = to_sensor_dev_attr_2(devattr)->index; 14698c2ecf20Sopenharmony_ci 14708c2ecf20Sopenharmony_ci return sprintf(buf, "%d\n", data->in[nr] * 8); 14718c2ecf20Sopenharmony_ci} 14728c2ecf20Sopenharmony_ci 14738c2ecf20Sopenharmony_cistatic ssize_t show_in_max(struct device *dev, struct device_attribute 14748c2ecf20Sopenharmony_ci *devattr, char *buf) 14758c2ecf20Sopenharmony_ci{ 14768c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 14778c2ecf20Sopenharmony_ci 14788c2ecf20Sopenharmony_ci return sprintf(buf, "%d\n", data->in1_max * 8); 14798c2ecf20Sopenharmony_ci} 14808c2ecf20Sopenharmony_ci 14818c2ecf20Sopenharmony_cistatic ssize_t store_in_max(struct device *dev, struct device_attribute 14828c2ecf20Sopenharmony_ci *devattr, const char *buf, size_t count) 14838c2ecf20Sopenharmony_ci{ 14848c2ecf20Sopenharmony_ci struct f71882fg_data *data = dev_get_drvdata(dev); 14858c2ecf20Sopenharmony_ci int err; 14868c2ecf20Sopenharmony_ci long val; 14878c2ecf20Sopenharmony_ci 14888c2ecf20Sopenharmony_ci err = kstrtol(buf, 10, &val); 14898c2ecf20Sopenharmony_ci if (err) 14908c2ecf20Sopenharmony_ci return err; 14918c2ecf20Sopenharmony_ci 14928c2ecf20Sopenharmony_ci val /= 8; 14938c2ecf20Sopenharmony_ci val = clamp_val(val, 0, 255); 14948c2ecf20Sopenharmony_ci 14958c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 14968c2ecf20Sopenharmony_ci if (data->type == f81866a) 14978c2ecf20Sopenharmony_ci f71882fg_write8(data, F81866_REG_IN1_HIGH, val); 14988c2ecf20Sopenharmony_ci else 14998c2ecf20Sopenharmony_ci f71882fg_write8(data, F71882FG_REG_IN1_HIGH, val); 15008c2ecf20Sopenharmony_ci data->in1_max = val; 15018c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 15028c2ecf20Sopenharmony_ci 15038c2ecf20Sopenharmony_ci return count; 15048c2ecf20Sopenharmony_ci} 15058c2ecf20Sopenharmony_ci 15068c2ecf20Sopenharmony_cistatic ssize_t show_in_beep(struct device *dev, struct device_attribute 15078c2ecf20Sopenharmony_ci *devattr, char *buf) 15088c2ecf20Sopenharmony_ci{ 15098c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 15108c2ecf20Sopenharmony_ci int nr = to_sensor_dev_attr_2(devattr)->index; 15118c2ecf20Sopenharmony_ci 15128c2ecf20Sopenharmony_ci if (data->in_beep & (1 << nr)) 15138c2ecf20Sopenharmony_ci return sprintf(buf, "1\n"); 15148c2ecf20Sopenharmony_ci else 15158c2ecf20Sopenharmony_ci return sprintf(buf, "0\n"); 15168c2ecf20Sopenharmony_ci} 15178c2ecf20Sopenharmony_ci 15188c2ecf20Sopenharmony_cistatic ssize_t store_in_beep(struct device *dev, struct device_attribute 15198c2ecf20Sopenharmony_ci *devattr, const char *buf, size_t count) 15208c2ecf20Sopenharmony_ci{ 15218c2ecf20Sopenharmony_ci struct f71882fg_data *data = dev_get_drvdata(dev); 15228c2ecf20Sopenharmony_ci int err, nr = to_sensor_dev_attr_2(devattr)->index; 15238c2ecf20Sopenharmony_ci unsigned long val; 15248c2ecf20Sopenharmony_ci 15258c2ecf20Sopenharmony_ci err = kstrtoul(buf, 10, &val); 15268c2ecf20Sopenharmony_ci if (err) 15278c2ecf20Sopenharmony_ci return err; 15288c2ecf20Sopenharmony_ci 15298c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 15308c2ecf20Sopenharmony_ci if (data->type == f81866a) 15318c2ecf20Sopenharmony_ci data->in_beep = f71882fg_read8(data, F81866_REG_IN_BEEP); 15328c2ecf20Sopenharmony_ci else 15338c2ecf20Sopenharmony_ci data->in_beep = f71882fg_read8(data, F71882FG_REG_IN_BEEP); 15348c2ecf20Sopenharmony_ci 15358c2ecf20Sopenharmony_ci if (val) 15368c2ecf20Sopenharmony_ci data->in_beep |= 1 << nr; 15378c2ecf20Sopenharmony_ci else 15388c2ecf20Sopenharmony_ci data->in_beep &= ~(1 << nr); 15398c2ecf20Sopenharmony_ci 15408c2ecf20Sopenharmony_ci if (data->type == f81866a) 15418c2ecf20Sopenharmony_ci f71882fg_write8(data, F81866_REG_IN_BEEP, data->in_beep); 15428c2ecf20Sopenharmony_ci else 15438c2ecf20Sopenharmony_ci f71882fg_write8(data, F71882FG_REG_IN_BEEP, data->in_beep); 15448c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 15458c2ecf20Sopenharmony_ci 15468c2ecf20Sopenharmony_ci return count; 15478c2ecf20Sopenharmony_ci} 15488c2ecf20Sopenharmony_ci 15498c2ecf20Sopenharmony_cistatic ssize_t show_in_alarm(struct device *dev, struct device_attribute 15508c2ecf20Sopenharmony_ci *devattr, char *buf) 15518c2ecf20Sopenharmony_ci{ 15528c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 15538c2ecf20Sopenharmony_ci int nr = to_sensor_dev_attr_2(devattr)->index; 15548c2ecf20Sopenharmony_ci 15558c2ecf20Sopenharmony_ci if (data->in_status & (1 << nr)) 15568c2ecf20Sopenharmony_ci return sprintf(buf, "1\n"); 15578c2ecf20Sopenharmony_ci else 15588c2ecf20Sopenharmony_ci return sprintf(buf, "0\n"); 15598c2ecf20Sopenharmony_ci} 15608c2ecf20Sopenharmony_ci 15618c2ecf20Sopenharmony_cistatic ssize_t show_temp(struct device *dev, struct device_attribute *devattr, 15628c2ecf20Sopenharmony_ci char *buf) 15638c2ecf20Sopenharmony_ci{ 15648c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 15658c2ecf20Sopenharmony_ci int nr = to_sensor_dev_attr_2(devattr)->index; 15668c2ecf20Sopenharmony_ci int sign, temp; 15678c2ecf20Sopenharmony_ci 15688c2ecf20Sopenharmony_ci if (data->type == f71858fg) { 15698c2ecf20Sopenharmony_ci /* TEMP_TABLE_SEL 1 or 3 ? */ 15708c2ecf20Sopenharmony_ci if (data->temp_config & 1) { 15718c2ecf20Sopenharmony_ci sign = data->temp[nr] & 0x0001; 15728c2ecf20Sopenharmony_ci temp = (data->temp[nr] >> 5) & 0x7ff; 15738c2ecf20Sopenharmony_ci } else { 15748c2ecf20Sopenharmony_ci sign = data->temp[nr] & 0x8000; 15758c2ecf20Sopenharmony_ci temp = (data->temp[nr] >> 5) & 0x3ff; 15768c2ecf20Sopenharmony_ci } 15778c2ecf20Sopenharmony_ci temp *= 125; 15788c2ecf20Sopenharmony_ci if (sign) 15798c2ecf20Sopenharmony_ci temp -= 128000; 15808c2ecf20Sopenharmony_ci } else { 15818c2ecf20Sopenharmony_ci temp = ((s8)data->temp[nr]) * 1000; 15828c2ecf20Sopenharmony_ci } 15838c2ecf20Sopenharmony_ci 15848c2ecf20Sopenharmony_ci return sprintf(buf, "%d\n", temp); 15858c2ecf20Sopenharmony_ci} 15868c2ecf20Sopenharmony_ci 15878c2ecf20Sopenharmony_cistatic ssize_t show_temp_max(struct device *dev, struct device_attribute 15888c2ecf20Sopenharmony_ci *devattr, char *buf) 15898c2ecf20Sopenharmony_ci{ 15908c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 15918c2ecf20Sopenharmony_ci int nr = to_sensor_dev_attr_2(devattr)->index; 15928c2ecf20Sopenharmony_ci 15938c2ecf20Sopenharmony_ci return sprintf(buf, "%d\n", data->temp_high[nr] * 1000); 15948c2ecf20Sopenharmony_ci} 15958c2ecf20Sopenharmony_ci 15968c2ecf20Sopenharmony_cistatic ssize_t store_temp_max(struct device *dev, struct device_attribute 15978c2ecf20Sopenharmony_ci *devattr, const char *buf, size_t count) 15988c2ecf20Sopenharmony_ci{ 15998c2ecf20Sopenharmony_ci struct f71882fg_data *data = dev_get_drvdata(dev); 16008c2ecf20Sopenharmony_ci int err, nr = to_sensor_dev_attr_2(devattr)->index; 16018c2ecf20Sopenharmony_ci long val; 16028c2ecf20Sopenharmony_ci 16038c2ecf20Sopenharmony_ci err = kstrtol(buf, 10, &val); 16048c2ecf20Sopenharmony_ci if (err) 16058c2ecf20Sopenharmony_ci return err; 16068c2ecf20Sopenharmony_ci 16078c2ecf20Sopenharmony_ci val /= 1000; 16088c2ecf20Sopenharmony_ci val = clamp_val(val, 0, 255); 16098c2ecf20Sopenharmony_ci 16108c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 16118c2ecf20Sopenharmony_ci f71882fg_write8(data, F71882FG_REG_TEMP_HIGH(nr), val); 16128c2ecf20Sopenharmony_ci data->temp_high[nr] = val; 16138c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 16148c2ecf20Sopenharmony_ci 16158c2ecf20Sopenharmony_ci return count; 16168c2ecf20Sopenharmony_ci} 16178c2ecf20Sopenharmony_ci 16188c2ecf20Sopenharmony_cistatic ssize_t show_temp_max_hyst(struct device *dev, struct device_attribute 16198c2ecf20Sopenharmony_ci *devattr, char *buf) 16208c2ecf20Sopenharmony_ci{ 16218c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 16228c2ecf20Sopenharmony_ci int nr = to_sensor_dev_attr_2(devattr)->index; 16238c2ecf20Sopenharmony_ci int temp_max_hyst; 16248c2ecf20Sopenharmony_ci 16258c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 16268c2ecf20Sopenharmony_ci if (nr & 1) 16278c2ecf20Sopenharmony_ci temp_max_hyst = data->temp_hyst[nr / 2] >> 4; 16288c2ecf20Sopenharmony_ci else 16298c2ecf20Sopenharmony_ci temp_max_hyst = data->temp_hyst[nr / 2] & 0x0f; 16308c2ecf20Sopenharmony_ci temp_max_hyst = (data->temp_high[nr] - temp_max_hyst) * 1000; 16318c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 16328c2ecf20Sopenharmony_ci 16338c2ecf20Sopenharmony_ci return sprintf(buf, "%d\n", temp_max_hyst); 16348c2ecf20Sopenharmony_ci} 16358c2ecf20Sopenharmony_ci 16368c2ecf20Sopenharmony_cistatic ssize_t store_temp_max_hyst(struct device *dev, struct device_attribute 16378c2ecf20Sopenharmony_ci *devattr, const char *buf, size_t count) 16388c2ecf20Sopenharmony_ci{ 16398c2ecf20Sopenharmony_ci struct f71882fg_data *data = dev_get_drvdata(dev); 16408c2ecf20Sopenharmony_ci int err, nr = to_sensor_dev_attr_2(devattr)->index; 16418c2ecf20Sopenharmony_ci ssize_t ret = count; 16428c2ecf20Sopenharmony_ci u8 reg; 16438c2ecf20Sopenharmony_ci long val; 16448c2ecf20Sopenharmony_ci 16458c2ecf20Sopenharmony_ci err = kstrtol(buf, 10, &val); 16468c2ecf20Sopenharmony_ci if (err) 16478c2ecf20Sopenharmony_ci return err; 16488c2ecf20Sopenharmony_ci 16498c2ecf20Sopenharmony_ci val /= 1000; 16508c2ecf20Sopenharmony_ci 16518c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 16528c2ecf20Sopenharmony_ci 16538c2ecf20Sopenharmony_ci /* convert abs to relative and check */ 16548c2ecf20Sopenharmony_ci data->temp_high[nr] = f71882fg_read8(data, F71882FG_REG_TEMP_HIGH(nr)); 16558c2ecf20Sopenharmony_ci val = clamp_val(val, data->temp_high[nr] - 15, data->temp_high[nr]); 16568c2ecf20Sopenharmony_ci val = data->temp_high[nr] - val; 16578c2ecf20Sopenharmony_ci 16588c2ecf20Sopenharmony_ci /* convert value to register contents */ 16598c2ecf20Sopenharmony_ci reg = f71882fg_read8(data, F71882FG_REG_TEMP_HYST(nr / 2)); 16608c2ecf20Sopenharmony_ci if (nr & 1) 16618c2ecf20Sopenharmony_ci reg = (reg & 0x0f) | (val << 4); 16628c2ecf20Sopenharmony_ci else 16638c2ecf20Sopenharmony_ci reg = (reg & 0xf0) | val; 16648c2ecf20Sopenharmony_ci f71882fg_write8(data, F71882FG_REG_TEMP_HYST(nr / 2), reg); 16658c2ecf20Sopenharmony_ci data->temp_hyst[nr / 2] = reg; 16668c2ecf20Sopenharmony_ci 16678c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 16688c2ecf20Sopenharmony_ci return ret; 16698c2ecf20Sopenharmony_ci} 16708c2ecf20Sopenharmony_ci 16718c2ecf20Sopenharmony_cistatic ssize_t show_temp_crit(struct device *dev, struct device_attribute 16728c2ecf20Sopenharmony_ci *devattr, char *buf) 16738c2ecf20Sopenharmony_ci{ 16748c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 16758c2ecf20Sopenharmony_ci int nr = to_sensor_dev_attr_2(devattr)->index; 16768c2ecf20Sopenharmony_ci 16778c2ecf20Sopenharmony_ci return sprintf(buf, "%d\n", data->temp_ovt[nr] * 1000); 16788c2ecf20Sopenharmony_ci} 16798c2ecf20Sopenharmony_ci 16808c2ecf20Sopenharmony_cistatic ssize_t store_temp_crit(struct device *dev, struct device_attribute 16818c2ecf20Sopenharmony_ci *devattr, const char *buf, size_t count) 16828c2ecf20Sopenharmony_ci{ 16838c2ecf20Sopenharmony_ci struct f71882fg_data *data = dev_get_drvdata(dev); 16848c2ecf20Sopenharmony_ci int err, nr = to_sensor_dev_attr_2(devattr)->index; 16858c2ecf20Sopenharmony_ci long val; 16868c2ecf20Sopenharmony_ci 16878c2ecf20Sopenharmony_ci err = kstrtol(buf, 10, &val); 16888c2ecf20Sopenharmony_ci if (err) 16898c2ecf20Sopenharmony_ci return err; 16908c2ecf20Sopenharmony_ci 16918c2ecf20Sopenharmony_ci val /= 1000; 16928c2ecf20Sopenharmony_ci val = clamp_val(val, 0, 255); 16938c2ecf20Sopenharmony_ci 16948c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 16958c2ecf20Sopenharmony_ci f71882fg_write8(data, F71882FG_REG_TEMP_OVT(nr), val); 16968c2ecf20Sopenharmony_ci data->temp_ovt[nr] = val; 16978c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 16988c2ecf20Sopenharmony_ci 16998c2ecf20Sopenharmony_ci return count; 17008c2ecf20Sopenharmony_ci} 17018c2ecf20Sopenharmony_ci 17028c2ecf20Sopenharmony_cistatic ssize_t show_temp_crit_hyst(struct device *dev, struct device_attribute 17038c2ecf20Sopenharmony_ci *devattr, char *buf) 17048c2ecf20Sopenharmony_ci{ 17058c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 17068c2ecf20Sopenharmony_ci int nr = to_sensor_dev_attr_2(devattr)->index; 17078c2ecf20Sopenharmony_ci int temp_crit_hyst; 17088c2ecf20Sopenharmony_ci 17098c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 17108c2ecf20Sopenharmony_ci if (nr & 1) 17118c2ecf20Sopenharmony_ci temp_crit_hyst = data->temp_hyst[nr / 2] >> 4; 17128c2ecf20Sopenharmony_ci else 17138c2ecf20Sopenharmony_ci temp_crit_hyst = data->temp_hyst[nr / 2] & 0x0f; 17148c2ecf20Sopenharmony_ci temp_crit_hyst = (data->temp_ovt[nr] - temp_crit_hyst) * 1000; 17158c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 17168c2ecf20Sopenharmony_ci 17178c2ecf20Sopenharmony_ci return sprintf(buf, "%d\n", temp_crit_hyst); 17188c2ecf20Sopenharmony_ci} 17198c2ecf20Sopenharmony_ci 17208c2ecf20Sopenharmony_cistatic ssize_t show_temp_type(struct device *dev, struct device_attribute 17218c2ecf20Sopenharmony_ci *devattr, char *buf) 17228c2ecf20Sopenharmony_ci{ 17238c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 17248c2ecf20Sopenharmony_ci int nr = to_sensor_dev_attr_2(devattr)->index; 17258c2ecf20Sopenharmony_ci 17268c2ecf20Sopenharmony_ci return sprintf(buf, "%d\n", data->temp_type[nr]); 17278c2ecf20Sopenharmony_ci} 17288c2ecf20Sopenharmony_ci 17298c2ecf20Sopenharmony_cistatic ssize_t show_temp_beep(struct device *dev, struct device_attribute 17308c2ecf20Sopenharmony_ci *devattr, char *buf) 17318c2ecf20Sopenharmony_ci{ 17328c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 17338c2ecf20Sopenharmony_ci int nr = to_sensor_dev_attr_2(devattr)->index; 17348c2ecf20Sopenharmony_ci 17358c2ecf20Sopenharmony_ci if (data->temp_beep & (1 << nr)) 17368c2ecf20Sopenharmony_ci return sprintf(buf, "1\n"); 17378c2ecf20Sopenharmony_ci else 17388c2ecf20Sopenharmony_ci return sprintf(buf, "0\n"); 17398c2ecf20Sopenharmony_ci} 17408c2ecf20Sopenharmony_ci 17418c2ecf20Sopenharmony_cistatic ssize_t store_temp_beep(struct device *dev, struct device_attribute 17428c2ecf20Sopenharmony_ci *devattr, const char *buf, size_t count) 17438c2ecf20Sopenharmony_ci{ 17448c2ecf20Sopenharmony_ci struct f71882fg_data *data = dev_get_drvdata(dev); 17458c2ecf20Sopenharmony_ci int err, nr = to_sensor_dev_attr_2(devattr)->index; 17468c2ecf20Sopenharmony_ci unsigned long val; 17478c2ecf20Sopenharmony_ci 17488c2ecf20Sopenharmony_ci err = kstrtoul(buf, 10, &val); 17498c2ecf20Sopenharmony_ci if (err) 17508c2ecf20Sopenharmony_ci return err; 17518c2ecf20Sopenharmony_ci 17528c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 17538c2ecf20Sopenharmony_ci data->temp_beep = f71882fg_read8(data, F71882FG_REG_TEMP_BEEP); 17548c2ecf20Sopenharmony_ci if (val) 17558c2ecf20Sopenharmony_ci data->temp_beep |= 1 << nr; 17568c2ecf20Sopenharmony_ci else 17578c2ecf20Sopenharmony_ci data->temp_beep &= ~(1 << nr); 17588c2ecf20Sopenharmony_ci 17598c2ecf20Sopenharmony_ci f71882fg_write8(data, F71882FG_REG_TEMP_BEEP, data->temp_beep); 17608c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 17618c2ecf20Sopenharmony_ci 17628c2ecf20Sopenharmony_ci return count; 17638c2ecf20Sopenharmony_ci} 17648c2ecf20Sopenharmony_ci 17658c2ecf20Sopenharmony_cistatic ssize_t show_temp_alarm(struct device *dev, struct device_attribute 17668c2ecf20Sopenharmony_ci *devattr, char *buf) 17678c2ecf20Sopenharmony_ci{ 17688c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 17698c2ecf20Sopenharmony_ci int nr = to_sensor_dev_attr_2(devattr)->index; 17708c2ecf20Sopenharmony_ci 17718c2ecf20Sopenharmony_ci if (data->temp_status & (1 << nr)) 17728c2ecf20Sopenharmony_ci return sprintf(buf, "1\n"); 17738c2ecf20Sopenharmony_ci else 17748c2ecf20Sopenharmony_ci return sprintf(buf, "0\n"); 17758c2ecf20Sopenharmony_ci} 17768c2ecf20Sopenharmony_ci 17778c2ecf20Sopenharmony_cistatic ssize_t show_temp_fault(struct device *dev, struct device_attribute 17788c2ecf20Sopenharmony_ci *devattr, char *buf) 17798c2ecf20Sopenharmony_ci{ 17808c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 17818c2ecf20Sopenharmony_ci int nr = to_sensor_dev_attr_2(devattr)->index; 17828c2ecf20Sopenharmony_ci 17838c2ecf20Sopenharmony_ci if (data->temp_diode_open & (1 << nr)) 17848c2ecf20Sopenharmony_ci return sprintf(buf, "1\n"); 17858c2ecf20Sopenharmony_ci else 17868c2ecf20Sopenharmony_ci return sprintf(buf, "0\n"); 17878c2ecf20Sopenharmony_ci} 17888c2ecf20Sopenharmony_ci 17898c2ecf20Sopenharmony_cistatic ssize_t show_pwm(struct device *dev, 17908c2ecf20Sopenharmony_ci struct device_attribute *devattr, char *buf) 17918c2ecf20Sopenharmony_ci{ 17928c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 17938c2ecf20Sopenharmony_ci int val, nr = to_sensor_dev_attr_2(devattr)->index; 17948c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 17958c2ecf20Sopenharmony_ci if (data->pwm_enable & (1 << (2 * nr))) 17968c2ecf20Sopenharmony_ci /* PWM mode */ 17978c2ecf20Sopenharmony_ci val = data->pwm[nr]; 17988c2ecf20Sopenharmony_ci else { 17998c2ecf20Sopenharmony_ci /* RPM mode */ 18008c2ecf20Sopenharmony_ci val = 255 * fan_from_reg(data->fan_target[nr]) 18018c2ecf20Sopenharmony_ci / fan_from_reg(data->fan_full_speed[nr]); 18028c2ecf20Sopenharmony_ci } 18038c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 18048c2ecf20Sopenharmony_ci return sprintf(buf, "%d\n", val); 18058c2ecf20Sopenharmony_ci} 18068c2ecf20Sopenharmony_ci 18078c2ecf20Sopenharmony_cistatic ssize_t store_pwm(struct device *dev, 18088c2ecf20Sopenharmony_ci struct device_attribute *devattr, const char *buf, 18098c2ecf20Sopenharmony_ci size_t count) 18108c2ecf20Sopenharmony_ci{ 18118c2ecf20Sopenharmony_ci struct f71882fg_data *data = dev_get_drvdata(dev); 18128c2ecf20Sopenharmony_ci int err, nr = to_sensor_dev_attr_2(devattr)->index; 18138c2ecf20Sopenharmony_ci long val; 18148c2ecf20Sopenharmony_ci 18158c2ecf20Sopenharmony_ci err = kstrtol(buf, 10, &val); 18168c2ecf20Sopenharmony_ci if (err) 18178c2ecf20Sopenharmony_ci return err; 18188c2ecf20Sopenharmony_ci 18198c2ecf20Sopenharmony_ci val = clamp_val(val, 0, 255); 18208c2ecf20Sopenharmony_ci 18218c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 18228c2ecf20Sopenharmony_ci data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE); 18238c2ecf20Sopenharmony_ci if ((data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 3) != 2) || 18248c2ecf20Sopenharmony_ci (data->type != f8000 && !((data->pwm_enable >> 2 * nr) & 2))) { 18258c2ecf20Sopenharmony_ci count = -EROFS; 18268c2ecf20Sopenharmony_ci goto leave; 18278c2ecf20Sopenharmony_ci } 18288c2ecf20Sopenharmony_ci if (data->pwm_enable & (1 << (2 * nr))) { 18298c2ecf20Sopenharmony_ci /* PWM mode */ 18308c2ecf20Sopenharmony_ci f71882fg_write8(data, F71882FG_REG_PWM(nr), val); 18318c2ecf20Sopenharmony_ci data->pwm[nr] = val; 18328c2ecf20Sopenharmony_ci } else { 18338c2ecf20Sopenharmony_ci /* RPM mode */ 18348c2ecf20Sopenharmony_ci int target, full_speed; 18358c2ecf20Sopenharmony_ci full_speed = f71882fg_read16(data, 18368c2ecf20Sopenharmony_ci F71882FG_REG_FAN_FULL_SPEED(nr)); 18378c2ecf20Sopenharmony_ci target = fan_to_reg(val * fan_from_reg(full_speed) / 255); 18388c2ecf20Sopenharmony_ci f71882fg_write16(data, F71882FG_REG_FAN_TARGET(nr), target); 18398c2ecf20Sopenharmony_ci data->fan_target[nr] = target; 18408c2ecf20Sopenharmony_ci data->fan_full_speed[nr] = full_speed; 18418c2ecf20Sopenharmony_ci } 18428c2ecf20Sopenharmony_cileave: 18438c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 18448c2ecf20Sopenharmony_ci 18458c2ecf20Sopenharmony_ci return count; 18468c2ecf20Sopenharmony_ci} 18478c2ecf20Sopenharmony_ci 18488c2ecf20Sopenharmony_cistatic ssize_t show_simple_pwm(struct device *dev, 18498c2ecf20Sopenharmony_ci struct device_attribute *devattr, char *buf) 18508c2ecf20Sopenharmony_ci{ 18518c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 18528c2ecf20Sopenharmony_ci int val, nr = to_sensor_dev_attr_2(devattr)->index; 18538c2ecf20Sopenharmony_ci 18548c2ecf20Sopenharmony_ci val = data->pwm[nr]; 18558c2ecf20Sopenharmony_ci return sprintf(buf, "%d\n", val); 18568c2ecf20Sopenharmony_ci} 18578c2ecf20Sopenharmony_ci 18588c2ecf20Sopenharmony_cistatic ssize_t store_simple_pwm(struct device *dev, 18598c2ecf20Sopenharmony_ci struct device_attribute *devattr, 18608c2ecf20Sopenharmony_ci const char *buf, size_t count) 18618c2ecf20Sopenharmony_ci{ 18628c2ecf20Sopenharmony_ci struct f71882fg_data *data = dev_get_drvdata(dev); 18638c2ecf20Sopenharmony_ci int err, nr = to_sensor_dev_attr_2(devattr)->index; 18648c2ecf20Sopenharmony_ci long val; 18658c2ecf20Sopenharmony_ci 18668c2ecf20Sopenharmony_ci err = kstrtol(buf, 10, &val); 18678c2ecf20Sopenharmony_ci if (err) 18688c2ecf20Sopenharmony_ci return err; 18698c2ecf20Sopenharmony_ci 18708c2ecf20Sopenharmony_ci val = clamp_val(val, 0, 255); 18718c2ecf20Sopenharmony_ci 18728c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 18738c2ecf20Sopenharmony_ci f71882fg_write8(data, F71882FG_REG_PWM(nr), val); 18748c2ecf20Sopenharmony_ci data->pwm[nr] = val; 18758c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 18768c2ecf20Sopenharmony_ci 18778c2ecf20Sopenharmony_ci return count; 18788c2ecf20Sopenharmony_ci} 18798c2ecf20Sopenharmony_ci 18808c2ecf20Sopenharmony_cistatic ssize_t show_pwm_enable(struct device *dev, 18818c2ecf20Sopenharmony_ci struct device_attribute *devattr, char *buf) 18828c2ecf20Sopenharmony_ci{ 18838c2ecf20Sopenharmony_ci int result = 0; 18848c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 18858c2ecf20Sopenharmony_ci int nr = to_sensor_dev_attr_2(devattr)->index; 18868c2ecf20Sopenharmony_ci 18878c2ecf20Sopenharmony_ci switch ((data->pwm_enable >> 2 * nr) & 3) { 18888c2ecf20Sopenharmony_ci case 0: 18898c2ecf20Sopenharmony_ci case 1: 18908c2ecf20Sopenharmony_ci result = 2; /* Normal auto mode */ 18918c2ecf20Sopenharmony_ci break; 18928c2ecf20Sopenharmony_ci case 2: 18938c2ecf20Sopenharmony_ci result = 1; /* Manual mode */ 18948c2ecf20Sopenharmony_ci break; 18958c2ecf20Sopenharmony_ci case 3: 18968c2ecf20Sopenharmony_ci if (data->type == f8000) 18978c2ecf20Sopenharmony_ci result = 3; /* Thermostat mode */ 18988c2ecf20Sopenharmony_ci else 18998c2ecf20Sopenharmony_ci result = 1; /* Manual mode */ 19008c2ecf20Sopenharmony_ci break; 19018c2ecf20Sopenharmony_ci } 19028c2ecf20Sopenharmony_ci 19038c2ecf20Sopenharmony_ci return sprintf(buf, "%d\n", result); 19048c2ecf20Sopenharmony_ci} 19058c2ecf20Sopenharmony_ci 19068c2ecf20Sopenharmony_cistatic ssize_t store_pwm_enable(struct device *dev, struct device_attribute 19078c2ecf20Sopenharmony_ci *devattr, const char *buf, size_t count) 19088c2ecf20Sopenharmony_ci{ 19098c2ecf20Sopenharmony_ci struct f71882fg_data *data = dev_get_drvdata(dev); 19108c2ecf20Sopenharmony_ci int err, nr = to_sensor_dev_attr_2(devattr)->index; 19118c2ecf20Sopenharmony_ci long val; 19128c2ecf20Sopenharmony_ci 19138c2ecf20Sopenharmony_ci err = kstrtol(buf, 10, &val); 19148c2ecf20Sopenharmony_ci if (err) 19158c2ecf20Sopenharmony_ci return err; 19168c2ecf20Sopenharmony_ci 19178c2ecf20Sopenharmony_ci /* Special case for F8000 pwm channel 3 which only does auto mode */ 19188c2ecf20Sopenharmony_ci if (data->type == f8000 && nr == 2 && val != 2) 19198c2ecf20Sopenharmony_ci return -EINVAL; 19208c2ecf20Sopenharmony_ci 19218c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 19228c2ecf20Sopenharmony_ci data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE); 19238c2ecf20Sopenharmony_ci /* Special case for F8000 auto PWM mode / Thermostat mode */ 19248c2ecf20Sopenharmony_ci if (data->type == f8000 && ((data->pwm_enable >> 2 * nr) & 1)) { 19258c2ecf20Sopenharmony_ci switch (val) { 19268c2ecf20Sopenharmony_ci case 2: 19278c2ecf20Sopenharmony_ci data->pwm_enable &= ~(2 << (2 * nr)); 19288c2ecf20Sopenharmony_ci break; /* Normal auto mode */ 19298c2ecf20Sopenharmony_ci case 3: 19308c2ecf20Sopenharmony_ci data->pwm_enable |= 2 << (2 * nr); 19318c2ecf20Sopenharmony_ci break; /* Thermostat mode */ 19328c2ecf20Sopenharmony_ci default: 19338c2ecf20Sopenharmony_ci count = -EINVAL; 19348c2ecf20Sopenharmony_ci goto leave; 19358c2ecf20Sopenharmony_ci } 19368c2ecf20Sopenharmony_ci } else { 19378c2ecf20Sopenharmony_ci switch (val) { 19388c2ecf20Sopenharmony_ci case 1: 19398c2ecf20Sopenharmony_ci /* The f71858fg does not support manual RPM mode */ 19408c2ecf20Sopenharmony_ci if (data->type == f71858fg && 19418c2ecf20Sopenharmony_ci ((data->pwm_enable >> (2 * nr)) & 1)) { 19428c2ecf20Sopenharmony_ci count = -EINVAL; 19438c2ecf20Sopenharmony_ci goto leave; 19448c2ecf20Sopenharmony_ci } 19458c2ecf20Sopenharmony_ci data->pwm_enable |= 2 << (2 * nr); 19468c2ecf20Sopenharmony_ci break; /* Manual */ 19478c2ecf20Sopenharmony_ci case 2: 19488c2ecf20Sopenharmony_ci data->pwm_enable &= ~(2 << (2 * nr)); 19498c2ecf20Sopenharmony_ci break; /* Normal auto mode */ 19508c2ecf20Sopenharmony_ci default: 19518c2ecf20Sopenharmony_ci count = -EINVAL; 19528c2ecf20Sopenharmony_ci goto leave; 19538c2ecf20Sopenharmony_ci } 19548c2ecf20Sopenharmony_ci } 19558c2ecf20Sopenharmony_ci f71882fg_write8(data, F71882FG_REG_PWM_ENABLE, data->pwm_enable); 19568c2ecf20Sopenharmony_cileave: 19578c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 19588c2ecf20Sopenharmony_ci 19598c2ecf20Sopenharmony_ci return count; 19608c2ecf20Sopenharmony_ci} 19618c2ecf20Sopenharmony_ci 19628c2ecf20Sopenharmony_cistatic ssize_t show_pwm_auto_point_pwm(struct device *dev, 19638c2ecf20Sopenharmony_ci struct device_attribute *devattr, 19648c2ecf20Sopenharmony_ci char *buf) 19658c2ecf20Sopenharmony_ci{ 19668c2ecf20Sopenharmony_ci int result; 19678c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 19688c2ecf20Sopenharmony_ci int pwm = to_sensor_dev_attr_2(devattr)->index; 19698c2ecf20Sopenharmony_ci int point = to_sensor_dev_attr_2(devattr)->nr; 19708c2ecf20Sopenharmony_ci 19718c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 19728c2ecf20Sopenharmony_ci if (data->pwm_enable & (1 << (2 * pwm))) { 19738c2ecf20Sopenharmony_ci /* PWM mode */ 19748c2ecf20Sopenharmony_ci result = data->pwm_auto_point_pwm[pwm][point]; 19758c2ecf20Sopenharmony_ci } else { 19768c2ecf20Sopenharmony_ci /* RPM mode */ 19778c2ecf20Sopenharmony_ci result = 32 * 255 / (32 + data->pwm_auto_point_pwm[pwm][point]); 19788c2ecf20Sopenharmony_ci } 19798c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 19808c2ecf20Sopenharmony_ci 19818c2ecf20Sopenharmony_ci return sprintf(buf, "%d\n", result); 19828c2ecf20Sopenharmony_ci} 19838c2ecf20Sopenharmony_ci 19848c2ecf20Sopenharmony_cistatic ssize_t store_pwm_auto_point_pwm(struct device *dev, 19858c2ecf20Sopenharmony_ci struct device_attribute *devattr, 19868c2ecf20Sopenharmony_ci const char *buf, size_t count) 19878c2ecf20Sopenharmony_ci{ 19888c2ecf20Sopenharmony_ci struct f71882fg_data *data = dev_get_drvdata(dev); 19898c2ecf20Sopenharmony_ci int err, pwm = to_sensor_dev_attr_2(devattr)->index; 19908c2ecf20Sopenharmony_ci int point = to_sensor_dev_attr_2(devattr)->nr; 19918c2ecf20Sopenharmony_ci long val; 19928c2ecf20Sopenharmony_ci 19938c2ecf20Sopenharmony_ci err = kstrtol(buf, 10, &val); 19948c2ecf20Sopenharmony_ci if (err) 19958c2ecf20Sopenharmony_ci return err; 19968c2ecf20Sopenharmony_ci 19978c2ecf20Sopenharmony_ci val = clamp_val(val, 0, 255); 19988c2ecf20Sopenharmony_ci 19998c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 20008c2ecf20Sopenharmony_ci data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE); 20018c2ecf20Sopenharmony_ci if (data->pwm_enable & (1 << (2 * pwm))) { 20028c2ecf20Sopenharmony_ci /* PWM mode */ 20038c2ecf20Sopenharmony_ci } else { 20048c2ecf20Sopenharmony_ci /* RPM mode */ 20058c2ecf20Sopenharmony_ci if (val < 29) /* Prevent negative numbers */ 20068c2ecf20Sopenharmony_ci val = 255; 20078c2ecf20Sopenharmony_ci else 20088c2ecf20Sopenharmony_ci val = (255 - val) * 32 / val; 20098c2ecf20Sopenharmony_ci } 20108c2ecf20Sopenharmony_ci f71882fg_write8(data, F71882FG_REG_POINT_PWM(pwm, point), val); 20118c2ecf20Sopenharmony_ci data->pwm_auto_point_pwm[pwm][point] = val; 20128c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 20138c2ecf20Sopenharmony_ci 20148c2ecf20Sopenharmony_ci return count; 20158c2ecf20Sopenharmony_ci} 20168c2ecf20Sopenharmony_ci 20178c2ecf20Sopenharmony_cistatic ssize_t show_pwm_auto_point_temp_hyst(struct device *dev, 20188c2ecf20Sopenharmony_ci struct device_attribute *devattr, 20198c2ecf20Sopenharmony_ci char *buf) 20208c2ecf20Sopenharmony_ci{ 20218c2ecf20Sopenharmony_ci int result = 0; 20228c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 20238c2ecf20Sopenharmony_ci int nr = to_sensor_dev_attr_2(devattr)->index; 20248c2ecf20Sopenharmony_ci int point = to_sensor_dev_attr_2(devattr)->nr; 20258c2ecf20Sopenharmony_ci 20268c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 20278c2ecf20Sopenharmony_ci if (nr & 1) 20288c2ecf20Sopenharmony_ci result = data->pwm_auto_point_hyst[nr / 2] >> 4; 20298c2ecf20Sopenharmony_ci else 20308c2ecf20Sopenharmony_ci result = data->pwm_auto_point_hyst[nr / 2] & 0x0f; 20318c2ecf20Sopenharmony_ci result = 1000 * (data->pwm_auto_point_temp[nr][point] - result); 20328c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 20338c2ecf20Sopenharmony_ci 20348c2ecf20Sopenharmony_ci return sprintf(buf, "%d\n", result); 20358c2ecf20Sopenharmony_ci} 20368c2ecf20Sopenharmony_ci 20378c2ecf20Sopenharmony_cistatic ssize_t store_pwm_auto_point_temp_hyst(struct device *dev, 20388c2ecf20Sopenharmony_ci struct device_attribute *devattr, 20398c2ecf20Sopenharmony_ci const char *buf, size_t count) 20408c2ecf20Sopenharmony_ci{ 20418c2ecf20Sopenharmony_ci struct f71882fg_data *data = dev_get_drvdata(dev); 20428c2ecf20Sopenharmony_ci int err, nr = to_sensor_dev_attr_2(devattr)->index; 20438c2ecf20Sopenharmony_ci int point = to_sensor_dev_attr_2(devattr)->nr; 20448c2ecf20Sopenharmony_ci u8 reg; 20458c2ecf20Sopenharmony_ci long val; 20468c2ecf20Sopenharmony_ci 20478c2ecf20Sopenharmony_ci err = kstrtol(buf, 10, &val); 20488c2ecf20Sopenharmony_ci if (err) 20498c2ecf20Sopenharmony_ci return err; 20508c2ecf20Sopenharmony_ci 20518c2ecf20Sopenharmony_ci val /= 1000; 20528c2ecf20Sopenharmony_ci 20538c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 20548c2ecf20Sopenharmony_ci data->pwm_auto_point_temp[nr][point] = 20558c2ecf20Sopenharmony_ci f71882fg_read8(data, F71882FG_REG_POINT_TEMP(nr, point)); 20568c2ecf20Sopenharmony_ci val = clamp_val(val, data->pwm_auto_point_temp[nr][point] - 15, 20578c2ecf20Sopenharmony_ci data->pwm_auto_point_temp[nr][point]); 20588c2ecf20Sopenharmony_ci val = data->pwm_auto_point_temp[nr][point] - val; 20598c2ecf20Sopenharmony_ci 20608c2ecf20Sopenharmony_ci reg = f71882fg_read8(data, F71882FG_REG_FAN_HYST(nr / 2)); 20618c2ecf20Sopenharmony_ci if (nr & 1) 20628c2ecf20Sopenharmony_ci reg = (reg & 0x0f) | (val << 4); 20638c2ecf20Sopenharmony_ci else 20648c2ecf20Sopenharmony_ci reg = (reg & 0xf0) | val; 20658c2ecf20Sopenharmony_ci 20668c2ecf20Sopenharmony_ci f71882fg_write8(data, F71882FG_REG_FAN_HYST(nr / 2), reg); 20678c2ecf20Sopenharmony_ci data->pwm_auto_point_hyst[nr / 2] = reg; 20688c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 20698c2ecf20Sopenharmony_ci 20708c2ecf20Sopenharmony_ci return count; 20718c2ecf20Sopenharmony_ci} 20728c2ecf20Sopenharmony_ci 20738c2ecf20Sopenharmony_cistatic ssize_t show_pwm_interpolate(struct device *dev, 20748c2ecf20Sopenharmony_ci struct device_attribute *devattr, char *buf) 20758c2ecf20Sopenharmony_ci{ 20768c2ecf20Sopenharmony_ci int result; 20778c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 20788c2ecf20Sopenharmony_ci int nr = to_sensor_dev_attr_2(devattr)->index; 20798c2ecf20Sopenharmony_ci 20808c2ecf20Sopenharmony_ci result = (data->pwm_auto_point_mapping[nr] >> 4) & 1; 20818c2ecf20Sopenharmony_ci 20828c2ecf20Sopenharmony_ci return sprintf(buf, "%d\n", result); 20838c2ecf20Sopenharmony_ci} 20848c2ecf20Sopenharmony_ci 20858c2ecf20Sopenharmony_cistatic ssize_t store_pwm_interpolate(struct device *dev, 20868c2ecf20Sopenharmony_ci struct device_attribute *devattr, 20878c2ecf20Sopenharmony_ci const char *buf, size_t count) 20888c2ecf20Sopenharmony_ci{ 20898c2ecf20Sopenharmony_ci struct f71882fg_data *data = dev_get_drvdata(dev); 20908c2ecf20Sopenharmony_ci int err, nr = to_sensor_dev_attr_2(devattr)->index; 20918c2ecf20Sopenharmony_ci unsigned long val; 20928c2ecf20Sopenharmony_ci 20938c2ecf20Sopenharmony_ci err = kstrtoul(buf, 10, &val); 20948c2ecf20Sopenharmony_ci if (err) 20958c2ecf20Sopenharmony_ci return err; 20968c2ecf20Sopenharmony_ci 20978c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 20988c2ecf20Sopenharmony_ci data->pwm_auto_point_mapping[nr] = 20998c2ecf20Sopenharmony_ci f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr)); 21008c2ecf20Sopenharmony_ci if (val) 21018c2ecf20Sopenharmony_ci val = data->pwm_auto_point_mapping[nr] | (1 << 4); 21028c2ecf20Sopenharmony_ci else 21038c2ecf20Sopenharmony_ci val = data->pwm_auto_point_mapping[nr] & (~(1 << 4)); 21048c2ecf20Sopenharmony_ci f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val); 21058c2ecf20Sopenharmony_ci data->pwm_auto_point_mapping[nr] = val; 21068c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 21078c2ecf20Sopenharmony_ci 21088c2ecf20Sopenharmony_ci return count; 21098c2ecf20Sopenharmony_ci} 21108c2ecf20Sopenharmony_ci 21118c2ecf20Sopenharmony_cistatic ssize_t show_pwm_auto_point_channel(struct device *dev, 21128c2ecf20Sopenharmony_ci struct device_attribute *devattr, 21138c2ecf20Sopenharmony_ci char *buf) 21148c2ecf20Sopenharmony_ci{ 21158c2ecf20Sopenharmony_ci int result; 21168c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 21178c2ecf20Sopenharmony_ci int nr = to_sensor_dev_attr_2(devattr)->index; 21188c2ecf20Sopenharmony_ci 21198c2ecf20Sopenharmony_ci result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) - 21208c2ecf20Sopenharmony_ci data->temp_start); 21218c2ecf20Sopenharmony_ci 21228c2ecf20Sopenharmony_ci return sprintf(buf, "%d\n", result); 21238c2ecf20Sopenharmony_ci} 21248c2ecf20Sopenharmony_ci 21258c2ecf20Sopenharmony_cistatic ssize_t store_pwm_auto_point_channel(struct device *dev, 21268c2ecf20Sopenharmony_ci struct device_attribute *devattr, 21278c2ecf20Sopenharmony_ci const char *buf, size_t count) 21288c2ecf20Sopenharmony_ci{ 21298c2ecf20Sopenharmony_ci struct f71882fg_data *data = dev_get_drvdata(dev); 21308c2ecf20Sopenharmony_ci int err, nr = to_sensor_dev_attr_2(devattr)->index; 21318c2ecf20Sopenharmony_ci long val; 21328c2ecf20Sopenharmony_ci 21338c2ecf20Sopenharmony_ci err = kstrtol(buf, 10, &val); 21348c2ecf20Sopenharmony_ci if (err) 21358c2ecf20Sopenharmony_ci return err; 21368c2ecf20Sopenharmony_ci 21378c2ecf20Sopenharmony_ci switch (val) { 21388c2ecf20Sopenharmony_ci case 1: 21398c2ecf20Sopenharmony_ci val = 0; 21408c2ecf20Sopenharmony_ci break; 21418c2ecf20Sopenharmony_ci case 2: 21428c2ecf20Sopenharmony_ci val = 1; 21438c2ecf20Sopenharmony_ci break; 21448c2ecf20Sopenharmony_ci case 4: 21458c2ecf20Sopenharmony_ci val = 2; 21468c2ecf20Sopenharmony_ci break; 21478c2ecf20Sopenharmony_ci default: 21488c2ecf20Sopenharmony_ci return -EINVAL; 21498c2ecf20Sopenharmony_ci } 21508c2ecf20Sopenharmony_ci val += data->temp_start; 21518c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 21528c2ecf20Sopenharmony_ci data->pwm_auto_point_mapping[nr] = 21538c2ecf20Sopenharmony_ci f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr)); 21548c2ecf20Sopenharmony_ci val = (data->pwm_auto_point_mapping[nr] & 0xfc) | val; 21558c2ecf20Sopenharmony_ci f71882fg_write8(data, F71882FG_REG_POINT_MAPPING(nr), val); 21568c2ecf20Sopenharmony_ci data->pwm_auto_point_mapping[nr] = val; 21578c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 21588c2ecf20Sopenharmony_ci 21598c2ecf20Sopenharmony_ci return count; 21608c2ecf20Sopenharmony_ci} 21618c2ecf20Sopenharmony_ci 21628c2ecf20Sopenharmony_cistatic ssize_t show_pwm_auto_point_temp(struct device *dev, 21638c2ecf20Sopenharmony_ci struct device_attribute *devattr, 21648c2ecf20Sopenharmony_ci char *buf) 21658c2ecf20Sopenharmony_ci{ 21668c2ecf20Sopenharmony_ci int result; 21678c2ecf20Sopenharmony_ci struct f71882fg_data *data = f71882fg_update_device(dev); 21688c2ecf20Sopenharmony_ci int pwm = to_sensor_dev_attr_2(devattr)->index; 21698c2ecf20Sopenharmony_ci int point = to_sensor_dev_attr_2(devattr)->nr; 21708c2ecf20Sopenharmony_ci 21718c2ecf20Sopenharmony_ci result = data->pwm_auto_point_temp[pwm][point]; 21728c2ecf20Sopenharmony_ci return sprintf(buf, "%d\n", 1000 * result); 21738c2ecf20Sopenharmony_ci} 21748c2ecf20Sopenharmony_ci 21758c2ecf20Sopenharmony_cistatic ssize_t store_pwm_auto_point_temp(struct device *dev, 21768c2ecf20Sopenharmony_ci struct device_attribute *devattr, 21778c2ecf20Sopenharmony_ci const char *buf, size_t count) 21788c2ecf20Sopenharmony_ci{ 21798c2ecf20Sopenharmony_ci struct f71882fg_data *data = dev_get_drvdata(dev); 21808c2ecf20Sopenharmony_ci int err, pwm = to_sensor_dev_attr_2(devattr)->index; 21818c2ecf20Sopenharmony_ci int point = to_sensor_dev_attr_2(devattr)->nr; 21828c2ecf20Sopenharmony_ci long val; 21838c2ecf20Sopenharmony_ci 21848c2ecf20Sopenharmony_ci err = kstrtol(buf, 10, &val); 21858c2ecf20Sopenharmony_ci if (err) 21868c2ecf20Sopenharmony_ci return err; 21878c2ecf20Sopenharmony_ci 21888c2ecf20Sopenharmony_ci val /= 1000; 21898c2ecf20Sopenharmony_ci 21908c2ecf20Sopenharmony_ci if (data->auto_point_temp_signed) 21918c2ecf20Sopenharmony_ci val = clamp_val(val, -128, 127); 21928c2ecf20Sopenharmony_ci else 21938c2ecf20Sopenharmony_ci val = clamp_val(val, 0, 127); 21948c2ecf20Sopenharmony_ci 21958c2ecf20Sopenharmony_ci mutex_lock(&data->update_lock); 21968c2ecf20Sopenharmony_ci f71882fg_write8(data, F71882FG_REG_POINT_TEMP(pwm, point), val); 21978c2ecf20Sopenharmony_ci data->pwm_auto_point_temp[pwm][point] = val; 21988c2ecf20Sopenharmony_ci mutex_unlock(&data->update_lock); 21998c2ecf20Sopenharmony_ci 22008c2ecf20Sopenharmony_ci return count; 22018c2ecf20Sopenharmony_ci} 22028c2ecf20Sopenharmony_ci 22038c2ecf20Sopenharmony_cistatic ssize_t name_show(struct device *dev, struct device_attribute *devattr, 22048c2ecf20Sopenharmony_ci char *buf) 22058c2ecf20Sopenharmony_ci{ 22068c2ecf20Sopenharmony_ci struct f71882fg_data *data = dev_get_drvdata(dev); 22078c2ecf20Sopenharmony_ci return sprintf(buf, "%s\n", f71882fg_names[data->type]); 22088c2ecf20Sopenharmony_ci} 22098c2ecf20Sopenharmony_ci 22108c2ecf20Sopenharmony_cistatic int f71882fg_create_sysfs_files(struct platform_device *pdev, 22118c2ecf20Sopenharmony_ci struct sensor_device_attribute_2 *attr, int count) 22128c2ecf20Sopenharmony_ci{ 22138c2ecf20Sopenharmony_ci int err, i; 22148c2ecf20Sopenharmony_ci 22158c2ecf20Sopenharmony_ci for (i = 0; i < count; i++) { 22168c2ecf20Sopenharmony_ci err = device_create_file(&pdev->dev, &attr[i].dev_attr); 22178c2ecf20Sopenharmony_ci if (err) 22188c2ecf20Sopenharmony_ci return err; 22198c2ecf20Sopenharmony_ci } 22208c2ecf20Sopenharmony_ci return 0; 22218c2ecf20Sopenharmony_ci} 22228c2ecf20Sopenharmony_ci 22238c2ecf20Sopenharmony_cistatic void f71882fg_remove_sysfs_files(struct platform_device *pdev, 22248c2ecf20Sopenharmony_ci struct sensor_device_attribute_2 *attr, int count) 22258c2ecf20Sopenharmony_ci{ 22268c2ecf20Sopenharmony_ci int i; 22278c2ecf20Sopenharmony_ci 22288c2ecf20Sopenharmony_ci for (i = 0; i < count; i++) 22298c2ecf20Sopenharmony_ci device_remove_file(&pdev->dev, &attr[i].dev_attr); 22308c2ecf20Sopenharmony_ci} 22318c2ecf20Sopenharmony_ci 22328c2ecf20Sopenharmony_cistatic int f71882fg_create_fan_sysfs_files( 22338c2ecf20Sopenharmony_ci struct platform_device *pdev, int idx) 22348c2ecf20Sopenharmony_ci{ 22358c2ecf20Sopenharmony_ci struct f71882fg_data *data = platform_get_drvdata(pdev); 22368c2ecf20Sopenharmony_ci int err; 22378c2ecf20Sopenharmony_ci 22388c2ecf20Sopenharmony_ci /* Sanity check the pwm setting */ 22398c2ecf20Sopenharmony_ci err = 0; 22408c2ecf20Sopenharmony_ci switch (data->type) { 22418c2ecf20Sopenharmony_ci case f71858fg: 22428c2ecf20Sopenharmony_ci if (((data->pwm_enable >> (idx * 2)) & 3) == 3) 22438c2ecf20Sopenharmony_ci err = 1; 22448c2ecf20Sopenharmony_ci break; 22458c2ecf20Sopenharmony_ci case f71862fg: 22468c2ecf20Sopenharmony_ci if (((data->pwm_enable >> (idx * 2)) & 1) != 1) 22478c2ecf20Sopenharmony_ci err = 1; 22488c2ecf20Sopenharmony_ci break; 22498c2ecf20Sopenharmony_ci case f8000: 22508c2ecf20Sopenharmony_ci if (idx == 2) 22518c2ecf20Sopenharmony_ci err = data->pwm_enable & 0x20; 22528c2ecf20Sopenharmony_ci break; 22538c2ecf20Sopenharmony_ci default: 22548c2ecf20Sopenharmony_ci break; 22558c2ecf20Sopenharmony_ci } 22568c2ecf20Sopenharmony_ci if (err) { 22578c2ecf20Sopenharmony_ci dev_err(&pdev->dev, 22588c2ecf20Sopenharmony_ci "Invalid (reserved) pwm settings: 0x%02x, " 22598c2ecf20Sopenharmony_ci "skipping fan %d\n", 22608c2ecf20Sopenharmony_ci (data->pwm_enable >> (idx * 2)) & 3, idx + 1); 22618c2ecf20Sopenharmony_ci return 0; /* This is a non fatal condition */ 22628c2ecf20Sopenharmony_ci } 22638c2ecf20Sopenharmony_ci 22648c2ecf20Sopenharmony_ci err = f71882fg_create_sysfs_files(pdev, &fxxxx_fan_attr[idx][0], 22658c2ecf20Sopenharmony_ci ARRAY_SIZE(fxxxx_fan_attr[0])); 22668c2ecf20Sopenharmony_ci if (err) 22678c2ecf20Sopenharmony_ci return err; 22688c2ecf20Sopenharmony_ci 22698c2ecf20Sopenharmony_ci if (f71882fg_fan_has_beep[data->type]) { 22708c2ecf20Sopenharmony_ci err = f71882fg_create_sysfs_files(pdev, 22718c2ecf20Sopenharmony_ci &fxxxx_fan_beep_attr[idx], 22728c2ecf20Sopenharmony_ci 1); 22738c2ecf20Sopenharmony_ci if (err) 22748c2ecf20Sopenharmony_ci return err; 22758c2ecf20Sopenharmony_ci } 22768c2ecf20Sopenharmony_ci 22778c2ecf20Sopenharmony_ci dev_info(&pdev->dev, "Fan: %d is in %s mode\n", idx + 1, 22788c2ecf20Sopenharmony_ci (data->pwm_enable & (1 << (2 * idx))) ? "duty-cycle" : "RPM"); 22798c2ecf20Sopenharmony_ci 22808c2ecf20Sopenharmony_ci /* Check for unsupported auto pwm settings */ 22818c2ecf20Sopenharmony_ci switch (data->type) { 22828c2ecf20Sopenharmony_ci case f71808e: 22838c2ecf20Sopenharmony_ci case f71808a: 22848c2ecf20Sopenharmony_ci case f71869: 22858c2ecf20Sopenharmony_ci case f71869a: 22868c2ecf20Sopenharmony_ci case f71889fg: 22878c2ecf20Sopenharmony_ci case f71889ed: 22888c2ecf20Sopenharmony_ci case f71889a: 22898c2ecf20Sopenharmony_ci data->pwm_auto_point_mapping[idx] = 22908c2ecf20Sopenharmony_ci f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(idx)); 22918c2ecf20Sopenharmony_ci if ((data->pwm_auto_point_mapping[idx] & 0x80) || 22928c2ecf20Sopenharmony_ci (data->pwm_auto_point_mapping[idx] & 3) == 0) { 22938c2ecf20Sopenharmony_ci dev_warn(&pdev->dev, 22948c2ecf20Sopenharmony_ci "Auto pwm controlled by raw digital " 22958c2ecf20Sopenharmony_ci "data, disabling pwm auto_point " 22968c2ecf20Sopenharmony_ci "sysfs attributes for fan %d\n", idx + 1); 22978c2ecf20Sopenharmony_ci return 0; /* This is a non fatal condition */ 22988c2ecf20Sopenharmony_ci } 22998c2ecf20Sopenharmony_ci break; 23008c2ecf20Sopenharmony_ci default: 23018c2ecf20Sopenharmony_ci break; 23028c2ecf20Sopenharmony_ci } 23038c2ecf20Sopenharmony_ci 23048c2ecf20Sopenharmony_ci switch (data->type) { 23058c2ecf20Sopenharmony_ci case f71862fg: 23068c2ecf20Sopenharmony_ci err = f71882fg_create_sysfs_files(pdev, 23078c2ecf20Sopenharmony_ci &f71862fg_auto_pwm_attr[idx][0], 23088c2ecf20Sopenharmony_ci ARRAY_SIZE(f71862fg_auto_pwm_attr[0])); 23098c2ecf20Sopenharmony_ci break; 23108c2ecf20Sopenharmony_ci case f71808e: 23118c2ecf20Sopenharmony_ci case f71869: 23128c2ecf20Sopenharmony_ci err = f71882fg_create_sysfs_files(pdev, 23138c2ecf20Sopenharmony_ci &f71869_auto_pwm_attr[idx][0], 23148c2ecf20Sopenharmony_ci ARRAY_SIZE(f71869_auto_pwm_attr[0])); 23158c2ecf20Sopenharmony_ci break; 23168c2ecf20Sopenharmony_ci case f8000: 23178c2ecf20Sopenharmony_ci err = f71882fg_create_sysfs_files(pdev, 23188c2ecf20Sopenharmony_ci &f8000_auto_pwm_attr[idx][0], 23198c2ecf20Sopenharmony_ci ARRAY_SIZE(f8000_auto_pwm_attr[0])); 23208c2ecf20Sopenharmony_ci break; 23218c2ecf20Sopenharmony_ci default: 23228c2ecf20Sopenharmony_ci err = f71882fg_create_sysfs_files(pdev, 23238c2ecf20Sopenharmony_ci &fxxxx_auto_pwm_attr[idx][0], 23248c2ecf20Sopenharmony_ci ARRAY_SIZE(fxxxx_auto_pwm_attr[0])); 23258c2ecf20Sopenharmony_ci } 23268c2ecf20Sopenharmony_ci 23278c2ecf20Sopenharmony_ci return err; 23288c2ecf20Sopenharmony_ci} 23298c2ecf20Sopenharmony_ci 23308c2ecf20Sopenharmony_cistatic int f71882fg_probe(struct platform_device *pdev) 23318c2ecf20Sopenharmony_ci{ 23328c2ecf20Sopenharmony_ci struct f71882fg_data *data; 23338c2ecf20Sopenharmony_ci struct f71882fg_sio_data *sio_data = dev_get_platdata(&pdev->dev); 23348c2ecf20Sopenharmony_ci int nr_fans = f71882fg_nr_fans[sio_data->type]; 23358c2ecf20Sopenharmony_ci int nr_temps = f71882fg_nr_temps[sio_data->type]; 23368c2ecf20Sopenharmony_ci int err, i; 23378c2ecf20Sopenharmony_ci int size; 23388c2ecf20Sopenharmony_ci u8 start_reg, reg; 23398c2ecf20Sopenharmony_ci 23408c2ecf20Sopenharmony_ci data = devm_kzalloc(&pdev->dev, sizeof(struct f71882fg_data), 23418c2ecf20Sopenharmony_ci GFP_KERNEL); 23428c2ecf20Sopenharmony_ci if (!data) 23438c2ecf20Sopenharmony_ci return -ENOMEM; 23448c2ecf20Sopenharmony_ci 23458c2ecf20Sopenharmony_ci data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; 23468c2ecf20Sopenharmony_ci data->type = sio_data->type; 23478c2ecf20Sopenharmony_ci data->temp_start = 23488c2ecf20Sopenharmony_ci (data->type == f71858fg || data->type == f8000 || 23498c2ecf20Sopenharmony_ci data->type == f81866a) ? 0 : 1; 23508c2ecf20Sopenharmony_ci mutex_init(&data->update_lock); 23518c2ecf20Sopenharmony_ci platform_set_drvdata(pdev, data); 23528c2ecf20Sopenharmony_ci 23538c2ecf20Sopenharmony_ci start_reg = f71882fg_read8(data, F71882FG_REG_START); 23548c2ecf20Sopenharmony_ci if (start_reg & 0x04) { 23558c2ecf20Sopenharmony_ci dev_warn(&pdev->dev, "Hardware monitor is powered down\n"); 23568c2ecf20Sopenharmony_ci return -ENODEV; 23578c2ecf20Sopenharmony_ci } 23588c2ecf20Sopenharmony_ci if (!(start_reg & 0x03)) { 23598c2ecf20Sopenharmony_ci dev_warn(&pdev->dev, "Hardware monitoring not activated\n"); 23608c2ecf20Sopenharmony_ci return -ENODEV; 23618c2ecf20Sopenharmony_ci } 23628c2ecf20Sopenharmony_ci 23638c2ecf20Sopenharmony_ci /* Register sysfs interface files */ 23648c2ecf20Sopenharmony_ci err = device_create_file(&pdev->dev, &dev_attr_name); 23658c2ecf20Sopenharmony_ci if (err) 23668c2ecf20Sopenharmony_ci goto exit_unregister_sysfs; 23678c2ecf20Sopenharmony_ci 23688c2ecf20Sopenharmony_ci if (start_reg & 0x01) { 23698c2ecf20Sopenharmony_ci switch (data->type) { 23708c2ecf20Sopenharmony_ci case f71858fg: 23718c2ecf20Sopenharmony_ci data->temp_config = 23728c2ecf20Sopenharmony_ci f71882fg_read8(data, F71882FG_REG_TEMP_CONFIG); 23738c2ecf20Sopenharmony_ci if (data->temp_config & 0x10) 23748c2ecf20Sopenharmony_ci /* 23758c2ecf20Sopenharmony_ci * The f71858fg temperature alarms behave as 23768c2ecf20Sopenharmony_ci * the f8000 alarms in this mode 23778c2ecf20Sopenharmony_ci */ 23788c2ecf20Sopenharmony_ci err = f71882fg_create_sysfs_files(pdev, 23798c2ecf20Sopenharmony_ci f8000_temp_attr, 23808c2ecf20Sopenharmony_ci ARRAY_SIZE(f8000_temp_attr)); 23818c2ecf20Sopenharmony_ci else 23828c2ecf20Sopenharmony_ci err = f71882fg_create_sysfs_files(pdev, 23838c2ecf20Sopenharmony_ci f71858fg_temp_attr, 23848c2ecf20Sopenharmony_ci ARRAY_SIZE(f71858fg_temp_attr)); 23858c2ecf20Sopenharmony_ci break; 23868c2ecf20Sopenharmony_ci case f8000: 23878c2ecf20Sopenharmony_ci err = f71882fg_create_sysfs_files(pdev, 23888c2ecf20Sopenharmony_ci f8000_temp_attr, 23898c2ecf20Sopenharmony_ci ARRAY_SIZE(f8000_temp_attr)); 23908c2ecf20Sopenharmony_ci break; 23918c2ecf20Sopenharmony_ci case f81866a: 23928c2ecf20Sopenharmony_ci err = f71882fg_create_sysfs_files(pdev, 23938c2ecf20Sopenharmony_ci f71858fg_temp_attr, 23948c2ecf20Sopenharmony_ci ARRAY_SIZE(f71858fg_temp_attr)); 23958c2ecf20Sopenharmony_ci break; 23968c2ecf20Sopenharmony_ci default: 23978c2ecf20Sopenharmony_ci err = f71882fg_create_sysfs_files(pdev, 23988c2ecf20Sopenharmony_ci &fxxxx_temp_attr[0][0], 23998c2ecf20Sopenharmony_ci ARRAY_SIZE(fxxxx_temp_attr[0]) * nr_temps); 24008c2ecf20Sopenharmony_ci } 24018c2ecf20Sopenharmony_ci if (err) 24028c2ecf20Sopenharmony_ci goto exit_unregister_sysfs; 24038c2ecf20Sopenharmony_ci 24048c2ecf20Sopenharmony_ci if (f71882fg_temp_has_beep[data->type]) { 24058c2ecf20Sopenharmony_ci if (data->type == f81866a) { 24068c2ecf20Sopenharmony_ci size = ARRAY_SIZE(f81866_temp_beep_attr[0]); 24078c2ecf20Sopenharmony_ci err = f71882fg_create_sysfs_files(pdev, 24088c2ecf20Sopenharmony_ci &f81866_temp_beep_attr[0][0], 24098c2ecf20Sopenharmony_ci size * nr_temps); 24108c2ecf20Sopenharmony_ci 24118c2ecf20Sopenharmony_ci } else { 24128c2ecf20Sopenharmony_ci size = ARRAY_SIZE(fxxxx_temp_beep_attr[0]); 24138c2ecf20Sopenharmony_ci err = f71882fg_create_sysfs_files(pdev, 24148c2ecf20Sopenharmony_ci &fxxxx_temp_beep_attr[0][0], 24158c2ecf20Sopenharmony_ci size * nr_temps); 24168c2ecf20Sopenharmony_ci } 24178c2ecf20Sopenharmony_ci if (err) 24188c2ecf20Sopenharmony_ci goto exit_unregister_sysfs; 24198c2ecf20Sopenharmony_ci } 24208c2ecf20Sopenharmony_ci 24218c2ecf20Sopenharmony_ci for (i = 0; i < F71882FG_MAX_INS; i++) { 24228c2ecf20Sopenharmony_ci if (f71882fg_has_in[data->type][i]) { 24238c2ecf20Sopenharmony_ci err = device_create_file(&pdev->dev, 24248c2ecf20Sopenharmony_ci &fxxxx_in_attr[i].dev_attr); 24258c2ecf20Sopenharmony_ci if (err) 24268c2ecf20Sopenharmony_ci goto exit_unregister_sysfs; 24278c2ecf20Sopenharmony_ci } 24288c2ecf20Sopenharmony_ci } 24298c2ecf20Sopenharmony_ci if (f71882fg_has_in1_alarm[data->type]) { 24308c2ecf20Sopenharmony_ci err = f71882fg_create_sysfs_files(pdev, 24318c2ecf20Sopenharmony_ci fxxxx_in1_alarm_attr, 24328c2ecf20Sopenharmony_ci ARRAY_SIZE(fxxxx_in1_alarm_attr)); 24338c2ecf20Sopenharmony_ci if (err) 24348c2ecf20Sopenharmony_ci goto exit_unregister_sysfs; 24358c2ecf20Sopenharmony_ci } 24368c2ecf20Sopenharmony_ci } 24378c2ecf20Sopenharmony_ci 24388c2ecf20Sopenharmony_ci if (start_reg & 0x02) { 24398c2ecf20Sopenharmony_ci switch (data->type) { 24408c2ecf20Sopenharmony_ci case f71808e: 24418c2ecf20Sopenharmony_ci case f71808a: 24428c2ecf20Sopenharmony_ci case f71869: 24438c2ecf20Sopenharmony_ci case f71869a: 24448c2ecf20Sopenharmony_ci /* These always have signed auto point temps */ 24458c2ecf20Sopenharmony_ci data->auto_point_temp_signed = 1; 24468c2ecf20Sopenharmony_ci fallthrough; /* to select correct fan/pwm reg bank! */ 24478c2ecf20Sopenharmony_ci case f71889fg: 24488c2ecf20Sopenharmony_ci case f71889ed: 24498c2ecf20Sopenharmony_ci case f71889a: 24508c2ecf20Sopenharmony_ci reg = f71882fg_read8(data, F71882FG_REG_FAN_FAULT_T); 24518c2ecf20Sopenharmony_ci if (reg & F71882FG_FAN_NEG_TEMP_EN) 24528c2ecf20Sopenharmony_ci data->auto_point_temp_signed = 1; 24538c2ecf20Sopenharmony_ci /* Ensure banked pwm registers point to right bank */ 24548c2ecf20Sopenharmony_ci reg &= ~F71882FG_FAN_PROG_SEL; 24558c2ecf20Sopenharmony_ci f71882fg_write8(data, F71882FG_REG_FAN_FAULT_T, reg); 24568c2ecf20Sopenharmony_ci break; 24578c2ecf20Sopenharmony_ci default: 24588c2ecf20Sopenharmony_ci break; 24598c2ecf20Sopenharmony_ci } 24608c2ecf20Sopenharmony_ci 24618c2ecf20Sopenharmony_ci data->pwm_enable = 24628c2ecf20Sopenharmony_ci f71882fg_read8(data, F71882FG_REG_PWM_ENABLE); 24638c2ecf20Sopenharmony_ci 24648c2ecf20Sopenharmony_ci for (i = 0; i < nr_fans; i++) { 24658c2ecf20Sopenharmony_ci err = f71882fg_create_fan_sysfs_files(pdev, i); 24668c2ecf20Sopenharmony_ci if (err) 24678c2ecf20Sopenharmony_ci goto exit_unregister_sysfs; 24688c2ecf20Sopenharmony_ci } 24698c2ecf20Sopenharmony_ci 24708c2ecf20Sopenharmony_ci /* Some types have 1 extra fan with limited functionality */ 24718c2ecf20Sopenharmony_ci switch (data->type) { 24728c2ecf20Sopenharmony_ci case f71808a: 24738c2ecf20Sopenharmony_ci err = f71882fg_create_sysfs_files(pdev, 24748c2ecf20Sopenharmony_ci f71808a_fan3_attr, 24758c2ecf20Sopenharmony_ci ARRAY_SIZE(f71808a_fan3_attr)); 24768c2ecf20Sopenharmony_ci break; 24778c2ecf20Sopenharmony_ci case f8000: 24788c2ecf20Sopenharmony_ci err = f71882fg_create_sysfs_files(pdev, 24798c2ecf20Sopenharmony_ci f8000_fan_attr, 24808c2ecf20Sopenharmony_ci ARRAY_SIZE(f8000_fan_attr)); 24818c2ecf20Sopenharmony_ci break; 24828c2ecf20Sopenharmony_ci default: 24838c2ecf20Sopenharmony_ci break; 24848c2ecf20Sopenharmony_ci } 24858c2ecf20Sopenharmony_ci if (err) 24868c2ecf20Sopenharmony_ci goto exit_unregister_sysfs; 24878c2ecf20Sopenharmony_ci } 24888c2ecf20Sopenharmony_ci 24898c2ecf20Sopenharmony_ci data->hwmon_dev = hwmon_device_register(&pdev->dev); 24908c2ecf20Sopenharmony_ci if (IS_ERR(data->hwmon_dev)) { 24918c2ecf20Sopenharmony_ci err = PTR_ERR(data->hwmon_dev); 24928c2ecf20Sopenharmony_ci data->hwmon_dev = NULL; 24938c2ecf20Sopenharmony_ci goto exit_unregister_sysfs; 24948c2ecf20Sopenharmony_ci } 24958c2ecf20Sopenharmony_ci 24968c2ecf20Sopenharmony_ci return 0; 24978c2ecf20Sopenharmony_ci 24988c2ecf20Sopenharmony_ciexit_unregister_sysfs: 24998c2ecf20Sopenharmony_ci f71882fg_remove(pdev); /* Will unregister the sysfs files for us */ 25008c2ecf20Sopenharmony_ci return err; /* f71882fg_remove() also frees our data */ 25018c2ecf20Sopenharmony_ci} 25028c2ecf20Sopenharmony_ci 25038c2ecf20Sopenharmony_cistatic int f71882fg_remove(struct platform_device *pdev) 25048c2ecf20Sopenharmony_ci{ 25058c2ecf20Sopenharmony_ci struct f71882fg_data *data = platform_get_drvdata(pdev); 25068c2ecf20Sopenharmony_ci int nr_fans = f71882fg_nr_fans[data->type]; 25078c2ecf20Sopenharmony_ci int nr_temps = f71882fg_nr_temps[data->type]; 25088c2ecf20Sopenharmony_ci int i; 25098c2ecf20Sopenharmony_ci u8 start_reg = f71882fg_read8(data, F71882FG_REG_START); 25108c2ecf20Sopenharmony_ci 25118c2ecf20Sopenharmony_ci if (data->hwmon_dev) 25128c2ecf20Sopenharmony_ci hwmon_device_unregister(data->hwmon_dev); 25138c2ecf20Sopenharmony_ci 25148c2ecf20Sopenharmony_ci device_remove_file(&pdev->dev, &dev_attr_name); 25158c2ecf20Sopenharmony_ci 25168c2ecf20Sopenharmony_ci if (start_reg & 0x01) { 25178c2ecf20Sopenharmony_ci switch (data->type) { 25188c2ecf20Sopenharmony_ci case f71858fg: 25198c2ecf20Sopenharmony_ci if (data->temp_config & 0x10) 25208c2ecf20Sopenharmony_ci f71882fg_remove_sysfs_files(pdev, 25218c2ecf20Sopenharmony_ci f8000_temp_attr, 25228c2ecf20Sopenharmony_ci ARRAY_SIZE(f8000_temp_attr)); 25238c2ecf20Sopenharmony_ci else 25248c2ecf20Sopenharmony_ci f71882fg_remove_sysfs_files(pdev, 25258c2ecf20Sopenharmony_ci f71858fg_temp_attr, 25268c2ecf20Sopenharmony_ci ARRAY_SIZE(f71858fg_temp_attr)); 25278c2ecf20Sopenharmony_ci break; 25288c2ecf20Sopenharmony_ci case f8000: 25298c2ecf20Sopenharmony_ci f71882fg_remove_sysfs_files(pdev, 25308c2ecf20Sopenharmony_ci f8000_temp_attr, 25318c2ecf20Sopenharmony_ci ARRAY_SIZE(f8000_temp_attr)); 25328c2ecf20Sopenharmony_ci break; 25338c2ecf20Sopenharmony_ci case f81866a: 25348c2ecf20Sopenharmony_ci f71882fg_remove_sysfs_files(pdev, 25358c2ecf20Sopenharmony_ci f71858fg_temp_attr, 25368c2ecf20Sopenharmony_ci ARRAY_SIZE(f71858fg_temp_attr)); 25378c2ecf20Sopenharmony_ci break; 25388c2ecf20Sopenharmony_ci default: 25398c2ecf20Sopenharmony_ci f71882fg_remove_sysfs_files(pdev, 25408c2ecf20Sopenharmony_ci &fxxxx_temp_attr[0][0], 25418c2ecf20Sopenharmony_ci ARRAY_SIZE(fxxxx_temp_attr[0]) * nr_temps); 25428c2ecf20Sopenharmony_ci } 25438c2ecf20Sopenharmony_ci if (f71882fg_temp_has_beep[data->type]) { 25448c2ecf20Sopenharmony_ci if (data->type == f81866a) 25458c2ecf20Sopenharmony_ci f71882fg_remove_sysfs_files(pdev, 25468c2ecf20Sopenharmony_ci &f81866_temp_beep_attr[0][0], 25478c2ecf20Sopenharmony_ci ARRAY_SIZE(f81866_temp_beep_attr[0]) 25488c2ecf20Sopenharmony_ci * nr_temps); 25498c2ecf20Sopenharmony_ci else 25508c2ecf20Sopenharmony_ci f71882fg_remove_sysfs_files(pdev, 25518c2ecf20Sopenharmony_ci &fxxxx_temp_beep_attr[0][0], 25528c2ecf20Sopenharmony_ci ARRAY_SIZE(fxxxx_temp_beep_attr[0]) 25538c2ecf20Sopenharmony_ci * nr_temps); 25548c2ecf20Sopenharmony_ci } 25558c2ecf20Sopenharmony_ci 25568c2ecf20Sopenharmony_ci for (i = 0; i < F71882FG_MAX_INS; i++) { 25578c2ecf20Sopenharmony_ci if (f71882fg_has_in[data->type][i]) { 25588c2ecf20Sopenharmony_ci device_remove_file(&pdev->dev, 25598c2ecf20Sopenharmony_ci &fxxxx_in_attr[i].dev_attr); 25608c2ecf20Sopenharmony_ci } 25618c2ecf20Sopenharmony_ci } 25628c2ecf20Sopenharmony_ci if (f71882fg_has_in1_alarm[data->type]) { 25638c2ecf20Sopenharmony_ci f71882fg_remove_sysfs_files(pdev, 25648c2ecf20Sopenharmony_ci fxxxx_in1_alarm_attr, 25658c2ecf20Sopenharmony_ci ARRAY_SIZE(fxxxx_in1_alarm_attr)); 25668c2ecf20Sopenharmony_ci } 25678c2ecf20Sopenharmony_ci } 25688c2ecf20Sopenharmony_ci 25698c2ecf20Sopenharmony_ci if (start_reg & 0x02) { 25708c2ecf20Sopenharmony_ci f71882fg_remove_sysfs_files(pdev, &fxxxx_fan_attr[0][0], 25718c2ecf20Sopenharmony_ci ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans); 25728c2ecf20Sopenharmony_ci 25738c2ecf20Sopenharmony_ci if (f71882fg_fan_has_beep[data->type]) { 25748c2ecf20Sopenharmony_ci f71882fg_remove_sysfs_files(pdev, 25758c2ecf20Sopenharmony_ci fxxxx_fan_beep_attr, nr_fans); 25768c2ecf20Sopenharmony_ci } 25778c2ecf20Sopenharmony_ci 25788c2ecf20Sopenharmony_ci switch (data->type) { 25798c2ecf20Sopenharmony_ci case f71808a: 25808c2ecf20Sopenharmony_ci f71882fg_remove_sysfs_files(pdev, 25818c2ecf20Sopenharmony_ci &fxxxx_auto_pwm_attr[0][0], 25828c2ecf20Sopenharmony_ci ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans); 25838c2ecf20Sopenharmony_ci f71882fg_remove_sysfs_files(pdev, 25848c2ecf20Sopenharmony_ci f71808a_fan3_attr, 25858c2ecf20Sopenharmony_ci ARRAY_SIZE(f71808a_fan3_attr)); 25868c2ecf20Sopenharmony_ci break; 25878c2ecf20Sopenharmony_ci case f71862fg: 25888c2ecf20Sopenharmony_ci f71882fg_remove_sysfs_files(pdev, 25898c2ecf20Sopenharmony_ci &f71862fg_auto_pwm_attr[0][0], 25908c2ecf20Sopenharmony_ci ARRAY_SIZE(f71862fg_auto_pwm_attr[0]) * 25918c2ecf20Sopenharmony_ci nr_fans); 25928c2ecf20Sopenharmony_ci break; 25938c2ecf20Sopenharmony_ci case f71808e: 25948c2ecf20Sopenharmony_ci case f71869: 25958c2ecf20Sopenharmony_ci f71882fg_remove_sysfs_files(pdev, 25968c2ecf20Sopenharmony_ci &f71869_auto_pwm_attr[0][0], 25978c2ecf20Sopenharmony_ci ARRAY_SIZE(f71869_auto_pwm_attr[0]) * nr_fans); 25988c2ecf20Sopenharmony_ci break; 25998c2ecf20Sopenharmony_ci case f8000: 26008c2ecf20Sopenharmony_ci f71882fg_remove_sysfs_files(pdev, 26018c2ecf20Sopenharmony_ci f8000_fan_attr, 26028c2ecf20Sopenharmony_ci ARRAY_SIZE(f8000_fan_attr)); 26038c2ecf20Sopenharmony_ci f71882fg_remove_sysfs_files(pdev, 26048c2ecf20Sopenharmony_ci &f8000_auto_pwm_attr[0][0], 26058c2ecf20Sopenharmony_ci ARRAY_SIZE(f8000_auto_pwm_attr[0]) * nr_fans); 26068c2ecf20Sopenharmony_ci break; 26078c2ecf20Sopenharmony_ci default: 26088c2ecf20Sopenharmony_ci f71882fg_remove_sysfs_files(pdev, 26098c2ecf20Sopenharmony_ci &fxxxx_auto_pwm_attr[0][0], 26108c2ecf20Sopenharmony_ci ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans); 26118c2ecf20Sopenharmony_ci } 26128c2ecf20Sopenharmony_ci } 26138c2ecf20Sopenharmony_ci return 0; 26148c2ecf20Sopenharmony_ci} 26158c2ecf20Sopenharmony_ci 26168c2ecf20Sopenharmony_cistatic int __init f71882fg_find(int sioaddr, struct f71882fg_sio_data *sio_data) 26178c2ecf20Sopenharmony_ci{ 26188c2ecf20Sopenharmony_ci u16 devid; 26198c2ecf20Sopenharmony_ci unsigned short address; 26208c2ecf20Sopenharmony_ci int err = superio_enter(sioaddr); 26218c2ecf20Sopenharmony_ci if (err) 26228c2ecf20Sopenharmony_ci return err; 26238c2ecf20Sopenharmony_ci 26248c2ecf20Sopenharmony_ci devid = superio_inw(sioaddr, SIO_REG_MANID); 26258c2ecf20Sopenharmony_ci if (devid != SIO_FINTEK_ID) { 26268c2ecf20Sopenharmony_ci pr_debug("Not a Fintek device\n"); 26278c2ecf20Sopenharmony_ci err = -ENODEV; 26288c2ecf20Sopenharmony_ci goto exit; 26298c2ecf20Sopenharmony_ci } 26308c2ecf20Sopenharmony_ci 26318c2ecf20Sopenharmony_ci devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID); 26328c2ecf20Sopenharmony_ci switch (devid) { 26338c2ecf20Sopenharmony_ci case SIO_F71808E_ID: 26348c2ecf20Sopenharmony_ci sio_data->type = f71808e; 26358c2ecf20Sopenharmony_ci break; 26368c2ecf20Sopenharmony_ci case SIO_F71808A_ID: 26378c2ecf20Sopenharmony_ci sio_data->type = f71808a; 26388c2ecf20Sopenharmony_ci break; 26398c2ecf20Sopenharmony_ci case SIO_F71858_ID: 26408c2ecf20Sopenharmony_ci sio_data->type = f71858fg; 26418c2ecf20Sopenharmony_ci break; 26428c2ecf20Sopenharmony_ci case SIO_F71862_ID: 26438c2ecf20Sopenharmony_ci sio_data->type = f71862fg; 26448c2ecf20Sopenharmony_ci break; 26458c2ecf20Sopenharmony_ci case SIO_F71868_ID: 26468c2ecf20Sopenharmony_ci sio_data->type = f71868a; 26478c2ecf20Sopenharmony_ci break; 26488c2ecf20Sopenharmony_ci case SIO_F71869_ID: 26498c2ecf20Sopenharmony_ci sio_data->type = f71869; 26508c2ecf20Sopenharmony_ci break; 26518c2ecf20Sopenharmony_ci case SIO_F71869A_ID: 26528c2ecf20Sopenharmony_ci sio_data->type = f71869a; 26538c2ecf20Sopenharmony_ci break; 26548c2ecf20Sopenharmony_ci case SIO_F71882_ID: 26558c2ecf20Sopenharmony_ci sio_data->type = f71882fg; 26568c2ecf20Sopenharmony_ci break; 26578c2ecf20Sopenharmony_ci case SIO_F71889_ID: 26588c2ecf20Sopenharmony_ci sio_data->type = f71889fg; 26598c2ecf20Sopenharmony_ci break; 26608c2ecf20Sopenharmony_ci case SIO_F71889E_ID: 26618c2ecf20Sopenharmony_ci sio_data->type = f71889ed; 26628c2ecf20Sopenharmony_ci break; 26638c2ecf20Sopenharmony_ci case SIO_F71889A_ID: 26648c2ecf20Sopenharmony_ci sio_data->type = f71889a; 26658c2ecf20Sopenharmony_ci break; 26668c2ecf20Sopenharmony_ci case SIO_F8000_ID: 26678c2ecf20Sopenharmony_ci sio_data->type = f8000; 26688c2ecf20Sopenharmony_ci break; 26698c2ecf20Sopenharmony_ci case SIO_F81768D_ID: 26708c2ecf20Sopenharmony_ci sio_data->type = f81768d; 26718c2ecf20Sopenharmony_ci break; 26728c2ecf20Sopenharmony_ci case SIO_F81865_ID: 26738c2ecf20Sopenharmony_ci sio_data->type = f81865f; 26748c2ecf20Sopenharmony_ci break; 26758c2ecf20Sopenharmony_ci case SIO_F81866_ID: 26768c2ecf20Sopenharmony_ci sio_data->type = f81866a; 26778c2ecf20Sopenharmony_ci break; 26788c2ecf20Sopenharmony_ci default: 26798c2ecf20Sopenharmony_ci pr_info("Unsupported Fintek device: %04x\n", 26808c2ecf20Sopenharmony_ci (unsigned int)devid); 26818c2ecf20Sopenharmony_ci err = -ENODEV; 26828c2ecf20Sopenharmony_ci goto exit; 26838c2ecf20Sopenharmony_ci } 26848c2ecf20Sopenharmony_ci 26858c2ecf20Sopenharmony_ci if (sio_data->type == f71858fg) 26868c2ecf20Sopenharmony_ci superio_select(sioaddr, SIO_F71858FG_LD_HWM); 26878c2ecf20Sopenharmony_ci else 26888c2ecf20Sopenharmony_ci superio_select(sioaddr, SIO_F71882FG_LD_HWM); 26898c2ecf20Sopenharmony_ci 26908c2ecf20Sopenharmony_ci if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { 26918c2ecf20Sopenharmony_ci pr_warn("Device not activated\n"); 26928c2ecf20Sopenharmony_ci err = -ENODEV; 26938c2ecf20Sopenharmony_ci goto exit; 26948c2ecf20Sopenharmony_ci } 26958c2ecf20Sopenharmony_ci 26968c2ecf20Sopenharmony_ci address = superio_inw(sioaddr, SIO_REG_ADDR); 26978c2ecf20Sopenharmony_ci if (address == 0) { 26988c2ecf20Sopenharmony_ci pr_warn("Base address not set\n"); 26998c2ecf20Sopenharmony_ci err = -ENODEV; 27008c2ecf20Sopenharmony_ci goto exit; 27018c2ecf20Sopenharmony_ci } 27028c2ecf20Sopenharmony_ci address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ 27038c2ecf20Sopenharmony_ci 27048c2ecf20Sopenharmony_ci err = address; 27058c2ecf20Sopenharmony_ci pr_info("Found %s chip at %#x, revision %d\n", 27068c2ecf20Sopenharmony_ci f71882fg_names[sio_data->type], (unsigned int)address, 27078c2ecf20Sopenharmony_ci (int)superio_inb(sioaddr, SIO_REG_DEVREV)); 27088c2ecf20Sopenharmony_ciexit: 27098c2ecf20Sopenharmony_ci superio_exit(sioaddr); 27108c2ecf20Sopenharmony_ci return err; 27118c2ecf20Sopenharmony_ci} 27128c2ecf20Sopenharmony_ci 27138c2ecf20Sopenharmony_cistatic int __init f71882fg_device_add(int address, 27148c2ecf20Sopenharmony_ci const struct f71882fg_sio_data *sio_data) 27158c2ecf20Sopenharmony_ci{ 27168c2ecf20Sopenharmony_ci struct resource res = { 27178c2ecf20Sopenharmony_ci .start = address, 27188c2ecf20Sopenharmony_ci .end = address + REGION_LENGTH - 1, 27198c2ecf20Sopenharmony_ci .flags = IORESOURCE_IO, 27208c2ecf20Sopenharmony_ci }; 27218c2ecf20Sopenharmony_ci int err; 27228c2ecf20Sopenharmony_ci 27238c2ecf20Sopenharmony_ci f71882fg_pdev = platform_device_alloc(DRVNAME, address); 27248c2ecf20Sopenharmony_ci if (!f71882fg_pdev) 27258c2ecf20Sopenharmony_ci return -ENOMEM; 27268c2ecf20Sopenharmony_ci 27278c2ecf20Sopenharmony_ci res.name = f71882fg_pdev->name; 27288c2ecf20Sopenharmony_ci err = acpi_check_resource_conflict(&res); 27298c2ecf20Sopenharmony_ci if (err) 27308c2ecf20Sopenharmony_ci goto exit_device_put; 27318c2ecf20Sopenharmony_ci 27328c2ecf20Sopenharmony_ci err = platform_device_add_resources(f71882fg_pdev, &res, 1); 27338c2ecf20Sopenharmony_ci if (err) { 27348c2ecf20Sopenharmony_ci pr_err("Device resource addition failed\n"); 27358c2ecf20Sopenharmony_ci goto exit_device_put; 27368c2ecf20Sopenharmony_ci } 27378c2ecf20Sopenharmony_ci 27388c2ecf20Sopenharmony_ci err = platform_device_add_data(f71882fg_pdev, sio_data, 27398c2ecf20Sopenharmony_ci sizeof(struct f71882fg_sio_data)); 27408c2ecf20Sopenharmony_ci if (err) { 27418c2ecf20Sopenharmony_ci pr_err("Platform data allocation failed\n"); 27428c2ecf20Sopenharmony_ci goto exit_device_put; 27438c2ecf20Sopenharmony_ci } 27448c2ecf20Sopenharmony_ci 27458c2ecf20Sopenharmony_ci err = platform_device_add(f71882fg_pdev); 27468c2ecf20Sopenharmony_ci if (err) { 27478c2ecf20Sopenharmony_ci pr_err("Device addition failed\n"); 27488c2ecf20Sopenharmony_ci goto exit_device_put; 27498c2ecf20Sopenharmony_ci } 27508c2ecf20Sopenharmony_ci 27518c2ecf20Sopenharmony_ci return 0; 27528c2ecf20Sopenharmony_ci 27538c2ecf20Sopenharmony_ciexit_device_put: 27548c2ecf20Sopenharmony_ci platform_device_put(f71882fg_pdev); 27558c2ecf20Sopenharmony_ci 27568c2ecf20Sopenharmony_ci return err; 27578c2ecf20Sopenharmony_ci} 27588c2ecf20Sopenharmony_ci 27598c2ecf20Sopenharmony_cistatic int __init f71882fg_init(void) 27608c2ecf20Sopenharmony_ci{ 27618c2ecf20Sopenharmony_ci int err; 27628c2ecf20Sopenharmony_ci int address; 27638c2ecf20Sopenharmony_ci struct f71882fg_sio_data sio_data; 27648c2ecf20Sopenharmony_ci 27658c2ecf20Sopenharmony_ci memset(&sio_data, 0, sizeof(sio_data)); 27668c2ecf20Sopenharmony_ci 27678c2ecf20Sopenharmony_ci address = f71882fg_find(0x2e, &sio_data); 27688c2ecf20Sopenharmony_ci if (address < 0) 27698c2ecf20Sopenharmony_ci address = f71882fg_find(0x4e, &sio_data); 27708c2ecf20Sopenharmony_ci if (address < 0) 27718c2ecf20Sopenharmony_ci return address; 27728c2ecf20Sopenharmony_ci 27738c2ecf20Sopenharmony_ci err = platform_driver_register(&f71882fg_driver); 27748c2ecf20Sopenharmony_ci if (err) 27758c2ecf20Sopenharmony_ci return err; 27768c2ecf20Sopenharmony_ci 27778c2ecf20Sopenharmony_ci err = f71882fg_device_add(address, &sio_data); 27788c2ecf20Sopenharmony_ci if (err) 27798c2ecf20Sopenharmony_ci goto exit_driver; 27808c2ecf20Sopenharmony_ci 27818c2ecf20Sopenharmony_ci return 0; 27828c2ecf20Sopenharmony_ci 27838c2ecf20Sopenharmony_ciexit_driver: 27848c2ecf20Sopenharmony_ci platform_driver_unregister(&f71882fg_driver); 27858c2ecf20Sopenharmony_ci return err; 27868c2ecf20Sopenharmony_ci} 27878c2ecf20Sopenharmony_ci 27888c2ecf20Sopenharmony_cistatic void __exit f71882fg_exit(void) 27898c2ecf20Sopenharmony_ci{ 27908c2ecf20Sopenharmony_ci platform_device_unregister(f71882fg_pdev); 27918c2ecf20Sopenharmony_ci platform_driver_unregister(&f71882fg_driver); 27928c2ecf20Sopenharmony_ci} 27938c2ecf20Sopenharmony_ci 27948c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver"); 27958c2ecf20Sopenharmony_ciMODULE_AUTHOR("Hans Edgington, Hans de Goede <hdegoede@redhat.com>"); 27968c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 27978c2ecf20Sopenharmony_ci 27988c2ecf20Sopenharmony_cimodule_init(f71882fg_init); 27998c2ecf20Sopenharmony_cimodule_exit(f71882fg_exit); 2800