Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * nct6775 - Driver for the hardware monitoring functionality of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *	       Nuvoton NCT677x Super-I/O chips
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Copyright (C) 2012  Guenter Roeck <linux@roeck-us.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * Derived from w83627ehf driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * Copyright (C) 2005-2012  Jean Delvare <jdelvare@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  * Copyright (C) 2006  Yuan Mu (Winbond),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  *		       Rudolf Marek <r.marek@assembler.cz>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  *		       David Hubbard <david.c.hubbard@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  *		       Daniel J Blueman <daniel.blueman@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  * Copyright (C) 2010  Sheng-Yuan Huang (Nuvoton) (PS00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  * Shamelessly ripped from the w83627hf driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  * Copyright (C) 2003  Mark Studebaker
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  * Supports the following chips:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  * Chip        #vin    #fan    #pwm    #temp  chip IDs       man ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22)  * nct6106d     9      3       3       6+3    0xc450 0xc1    0x5ca3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23)  * nct6116d     9      5       5       3+3    0xd280 0xc1    0x5ca3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24)  * nct6775f     9      4       3       6+3    0xb470 0xc1    0x5ca3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25)  * nct6776f     9      5       3       6+3    0xc330 0xc1    0x5ca3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26)  * nct6779d    15      5       5       2+6    0xc560 0xc1    0x5ca3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27)  * nct6791d    15      6       6       2+6    0xc800 0xc1    0x5ca3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28)  * nct6792d    15      6       6       2+6    0xc910 0xc1    0x5ca3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29)  * nct6793d    15      6       6       2+6    0xd120 0xc1    0x5ca3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30)  * nct6795d    14      6       6       2+6    0xd350 0xc1    0x5ca3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31)  * nct6796d    14      7       7       2+6    0xd420 0xc1    0x5ca3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32)  * nct6797d    14      7       7       2+6    0xd450 0xc1    0x5ca3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33)  *                                           (0xd451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34)  * nct6798d    14      7       7       2+6    0xd428 0xc1    0x5ca3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35)  *                                           (0xd429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37)  * #temp lists the number of monitored temperature sources (first value) plus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38)  * the number of directly connectable temperature sensors (second value).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #include <linux/hwmon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #include <linux/hwmon-sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #include <linux/hwmon-vid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #include <linux/dmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #include <linux/nospec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #include "lm75.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #define USE_ALTERNATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) enum kinds { nct6106, nct6116, nct6775, nct6776, nct6779, nct6791, nct6792,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	     nct6793, nct6795, nct6796, nct6797, nct6798 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) /* used to set data->name = nct6775_device_names[data->sio_kind] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) static const char * const nct6775_device_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	"nct6106",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	"nct6116",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	"nct6775",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	"nct6776",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 	"nct6779",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	"nct6791",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	"nct6792",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	"nct6793",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	"nct6795",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	"nct6796",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	"nct6797",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	"nct6798",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) static const char * const nct6775_sio_names[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	"NCT6106D",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	"NCT6116D",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	"NCT6775F",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	"NCT6776D/F",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	"NCT6779D",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	"NCT6791D",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	"NCT6792D",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	"NCT6793D",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	"NCT6795D",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	"NCT6796D",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	"NCT6797D",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	"NCT6798D",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) static unsigned short force_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) module_param(force_id, ushort, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) MODULE_PARM_DESC(force_id, "Override the detected device ID");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) static unsigned short fan_debounce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) module_param(fan_debounce, ushort, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) #define DRVNAME "nct6775"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107)  * Super-I/O constants and functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) #define NCT6775_LD_ACPI		0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) #define NCT6775_LD_HWM		0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) #define NCT6775_LD_VID		0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) #define NCT6775_LD_12		0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) #define SIO_REG_LDSEL		0x07	/* Logical device select */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) #define SIO_REG_DEVID		0x20	/* Device ID (2 bytes) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) #define SIO_REG_ENABLE		0x30	/* Logical device enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) #define SIO_REG_ADDR		0x60	/* Logical device address (2 bytes) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) #define SIO_NCT6106_ID		0xc450
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) #define SIO_NCT6116_ID		0xd280
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) #define SIO_NCT6775_ID		0xb470
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) #define SIO_NCT6776_ID		0xc330
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) #define SIO_NCT6779_ID		0xc560
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) #define SIO_NCT6791_ID		0xc800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) #define SIO_NCT6792_ID		0xc910
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) #define SIO_NCT6793_ID		0xd120
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) #define SIO_NCT6795_ID		0xd350
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) #define SIO_NCT6796_ID		0xd420
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) #define SIO_NCT6797_ID		0xd450
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) #define SIO_NCT6798_ID		0xd428
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) #define SIO_ID_MASK		0xFFF8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) enum pwm_enable { off, manual, thermal_cruise, speed_cruise, sf3, sf4 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) superio_outb(int ioreg, int reg, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	outb(reg, ioreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	outb(val, ioreg + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) superio_inb(int ioreg, int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	outb(reg, ioreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	return inb(ioreg + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) superio_select(int ioreg, int ld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	outb(SIO_REG_LDSEL, ioreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	outb(ld, ioreg + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) superio_enter(int ioreg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	 * Try to reserve <ioreg> and <ioreg + 1> for exclusive access.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	if (!request_muxed_region(ioreg, 2, DRVNAME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	outb(0x87, ioreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	outb(0x87, ioreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) superio_exit(int ioreg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	outb(0xaa, ioreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	outb(0x02, ioreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	outb(0x02, ioreg + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	release_region(ioreg, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182)  * ISA constants
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) #define IOREGION_ALIGNMENT	(~7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) #define IOREGION_OFFSET		5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) #define IOREGION_LENGTH		2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) #define ADDR_REG_OFFSET		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) #define DATA_REG_OFFSET		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) #define NCT6775_REG_BANK	0x4E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) #define NCT6775_REG_CONFIG	0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195)  * Not currently used:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196)  * REG_MAN_ID has the value 0x5ca3 for all supported chips.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197)  * REG_CHIP_ID == 0x88/0xa1/0xc1 depending on chip model.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198)  * REG_MAN_ID is at port 0x4f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199)  * REG_CHIP_ID is at port 0x58
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) #define NUM_TEMP	10	/* Max number of temp attribute sets w/ limits*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) #define NUM_TEMP_FIXED	6	/* Max number of fixed temp attribute sets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) #define NUM_REG_ALARM	7	/* Max number of alarm registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) #define NUM_REG_BEEP	5	/* Max number of beep registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) #define NUM_FAN		7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) /* Common and NCT6775 specific data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) /* Voltage min/max registers for nr=7..14 are in bank 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) static const u16 NCT6775_REG_IN_MAX[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	0x2b, 0x2d, 0x2f, 0x31, 0x33, 0x35, 0x37, 0x554, 0x556, 0x558, 0x55a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	0x55c, 0x55e, 0x560, 0x562 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) static const u16 NCT6775_REG_IN_MIN[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x555, 0x557, 0x559, 0x55b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	0x55d, 0x55f, 0x561, 0x563 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) static const u16 NCT6775_REG_IN[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x550, 0x551, 0x552
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) #define NCT6775_REG_VBAT		0x5D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) #define NCT6775_REG_DIODE		0x5E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) #define NCT6775_DIODE_MASK		0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) #define NCT6775_REG_FANDIV1		0x506
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) #define NCT6775_REG_FANDIV2		0x507
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) #define NCT6775_REG_CR_FAN_DEBOUNCE	0xf0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) static const u16 NCT6775_REG_ALARM[NUM_REG_ALARM] = { 0x459, 0x45A, 0x45B };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) /* 0..15 voltages, 16..23 fans, 24..29 temperatures, 30..31 intrusion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) static const s8 NCT6775_ALARM_BITS[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	0, 1, 2, 3, 8, 21, 20, 16,	/* in0.. in7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	17, -1, -1, -1, -1, -1, -1,	/* in8..in14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	-1,				/* unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	6, 7, 11, -1, -1,		/* fan1..fan5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	-1, -1, -1,			/* unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	4, 5, 13, -1, -1, -1,		/* temp1..temp6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	12, -1 };			/* intrusion0, intrusion1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) #define FAN_ALARM_BASE		16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) #define TEMP_ALARM_BASE		24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) #define INTRUSION_ALARM_BASE	30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) static const u16 NCT6775_REG_BEEP[NUM_REG_BEEP] = { 0x56, 0x57, 0x453, 0x4e };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253)  * 0..14 voltages, 15 global beep enable, 16..23 fans, 24..29 temperatures,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254)  * 30..31 intrusion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) static const s8 NCT6775_BEEP_BITS[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	0, 1, 2, 3, 8, 9, 10, 16,	/* in0.. in7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	17, -1, -1, -1, -1, -1, -1,	/* in8..in14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	21,				/* global beep enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	6, 7, 11, 28, -1,		/* fan1..fan5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	-1, -1, -1,			/* unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	4, 5, 13, -1, -1, -1,		/* temp1..temp6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	12, -1 };			/* intrusion0, intrusion1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) #define BEEP_ENABLE_BASE		15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) static const u8 NCT6775_REG_CR_CASEOPEN_CLR[] = { 0xe6, 0xee };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) static const u8 NCT6775_CR_CASEOPEN_CLR_MASK[] = { 0x20, 0x01 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) /* DC or PWM output fan configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) static const u8 NCT6775_REG_PWM_MODE[] = { 0x04, 0x04, 0x12 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) static const u8 NCT6775_PWM_MODE_MASK[] = { 0x01, 0x02, 0x01 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) /* Advanced Fan control, some values are common for all fans */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) static const u16 NCT6775_REG_TARGET[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	0x101, 0x201, 0x301, 0x801, 0x901, 0xa01, 0xb01 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) static const u16 NCT6775_REG_FAN_MODE[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	0x102, 0x202, 0x302, 0x802, 0x902, 0xa02, 0xb02 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) static const u16 NCT6775_REG_FAN_STEP_DOWN_TIME[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	0x103, 0x203, 0x303, 0x803, 0x903, 0xa03, 0xb03 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) static const u16 NCT6775_REG_FAN_STEP_UP_TIME[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	0x104, 0x204, 0x304, 0x804, 0x904, 0xa04, 0xb04 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	0x105, 0x205, 0x305, 0x805, 0x905, 0xa05, 0xb05 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) static const u16 NCT6775_REG_FAN_START_OUTPUT[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	0x106, 0x206, 0x306, 0x806, 0x906, 0xa06, 0xb06 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) static const u16 NCT6775_REG_FAN_MAX_OUTPUT[] = { 0x10a, 0x20a, 0x30a };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) static const u16 NCT6775_REG_FAN_STEP_OUTPUT[] = { 0x10b, 0x20b, 0x30b };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) static const u16 NCT6775_REG_FAN_STOP_TIME[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	0x107, 0x207, 0x307, 0x807, 0x907, 0xa07, 0xb07 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) static const u16 NCT6775_REG_PWM[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	0x109, 0x209, 0x309, 0x809, 0x909, 0xa09, 0xb09 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) static const u16 NCT6775_REG_PWM_READ[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	0x01, 0x03, 0x11, 0x13, 0x15, 0xa09, 0xb09 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) static const u16 NCT6775_REG_FAN[] = { 0x630, 0x632, 0x634, 0x636, 0x638 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) static const u16 NCT6775_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) static const u16 NCT6775_REG_FAN_PULSES[NUM_FAN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	0x641, 0x642, 0x643, 0x644 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) static const u16 NCT6775_FAN_PULSE_SHIFT[NUM_FAN] = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) static const u16 NCT6775_REG_TEMP[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	0x27, 0x150, 0x250, 0x62b, 0x62c, 0x62d };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) static const u16 NCT6775_REG_TEMP_MON[] = { 0x73, 0x75, 0x77 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) static const u16 NCT6775_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	0, 0x152, 0x252, 0x628, 0x629, 0x62A };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) static const u16 NCT6775_REG_TEMP_HYST[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	0x3a, 0x153, 0x253, 0x673, 0x678, 0x67D };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) static const u16 NCT6775_REG_TEMP_OVER[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	0x39, 0x155, 0x255, 0x672, 0x677, 0x67C };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) static const u16 NCT6775_REG_TEMP_SOURCE[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	0x621, 0x622, 0x623, 0x624, 0x625, 0x626 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) static const u16 NCT6775_REG_TEMP_SEL[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	0x100, 0x200, 0x300, 0x800, 0x900, 0xa00, 0xb00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) static const u16 NCT6775_REG_WEIGHT_TEMP_SEL[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	0x139, 0x239, 0x339, 0x839, 0x939, 0xa39 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) static const u16 NCT6775_REG_WEIGHT_TEMP_STEP[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	0x13a, 0x23a, 0x33a, 0x83a, 0x93a, 0xa3a };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) static const u16 NCT6775_REG_WEIGHT_TEMP_STEP_TOL[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	0x13b, 0x23b, 0x33b, 0x83b, 0x93b, 0xa3b };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) static const u16 NCT6775_REG_WEIGHT_DUTY_STEP[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	0x13c, 0x23c, 0x33c, 0x83c, 0x93c, 0xa3c };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) static const u16 NCT6775_REG_WEIGHT_TEMP_BASE[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	0x13d, 0x23d, 0x33d, 0x83d, 0x93d, 0xa3d };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) static const u16 NCT6775_REG_TEMP_OFFSET[] = { 0x454, 0x455, 0x456 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) static const u16 NCT6775_REG_AUTO_TEMP[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	0x121, 0x221, 0x321, 0x821, 0x921, 0xa21, 0xb21 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) static const u16 NCT6775_REG_AUTO_PWM[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	0x127, 0x227, 0x327, 0x827, 0x927, 0xa27, 0xb27 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) #define NCT6775_AUTO_TEMP(data, nr, p)	((data)->REG_AUTO_TEMP[nr] + (p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) #define NCT6775_AUTO_PWM(data, nr, p)	((data)->REG_AUTO_PWM[nr] + (p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) static const u16 NCT6775_REG_CRITICAL_ENAB[] = { 0x134, 0x234, 0x334 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) static const u16 NCT6775_REG_CRITICAL_TEMP[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	0x135, 0x235, 0x335, 0x835, 0x935, 0xa35, 0xb35 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) static const u16 NCT6775_REG_CRITICAL_TEMP_TOLERANCE[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	0x138, 0x238, 0x338, 0x838, 0x938, 0xa38, 0xb38 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) static const char *const nct6775_temp_label[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	"SYSTIN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	"CPUTIN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	"AUXTIN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	"AMD SB-TSI",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	"PECI Agent 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	"PECI Agent 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	"PECI Agent 2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	"PECI Agent 3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	"PECI Agent 4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	"PECI Agent 5",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	"PECI Agent 6",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	"PECI Agent 7",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	"PCH_CHIP_CPU_MAX_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	"PCH_CHIP_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	"PCH_CPU_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	"PCH_MCH_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	"PCH_DIM0_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	"PCH_DIM1_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	"PCH_DIM2_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	"PCH_DIM3_TEMP"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) #define NCT6775_TEMP_MASK	0x001ffffe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) #define NCT6775_VIRT_TEMP_MASK	0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) static const u16 NCT6775_REG_TEMP_ALTERNATE[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	[13] = 0x661,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	[14] = 0x662,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	[15] = 0x664,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) static const u16 NCT6775_REG_TEMP_CRIT[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	[4] = 0xa00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	[5] = 0xa01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	[6] = 0xa02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	[7] = 0xa03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	[8] = 0xa04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	[9] = 0xa05,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	[10] = 0xa06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	[11] = 0xa07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) /* NCT6776 specific data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) /* STEP_UP_TIME and STEP_DOWN_TIME regs are swapped for all chips but NCT6775 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) #define NCT6776_REG_FAN_STEP_UP_TIME NCT6775_REG_FAN_STEP_DOWN_TIME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) #define NCT6776_REG_FAN_STEP_DOWN_TIME NCT6775_REG_FAN_STEP_UP_TIME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) static const s8 NCT6776_ALARM_BITS[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	0, 1, 2, 3, 8, 21, 20, 16,	/* in0.. in7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	17, -1, -1, -1, -1, -1, -1,	/* in8..in14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	-1,				/* unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	6, 7, 11, 10, 23,		/* fan1..fan5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	-1, -1, -1,			/* unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	4, 5, 13, -1, -1, -1,		/* temp1..temp6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	12, 9 };			/* intrusion0, intrusion1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) static const u16 NCT6776_REG_BEEP[NUM_REG_BEEP] = { 0xb2, 0xb3, 0xb4, 0xb5 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) static const s8 NCT6776_BEEP_BITS[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	0, 1, 2, 3, 4, 5, 6, 7,		/* in0.. in7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	8, -1, -1, -1, -1, -1, -1,	/* in8..in14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	24,				/* global beep enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	25, 26, 27, 28, 29,		/* fan1..fan5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	-1, -1, -1,			/* unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	16, 17, 18, 19, 20, 21,		/* temp1..temp6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	30, 31 };			/* intrusion0, intrusion1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) static const u16 NCT6776_REG_TOLERANCE_H[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	0x10c, 0x20c, 0x30c, 0x80c, 0x90c, 0xa0c, 0xb0c };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) static const u8 NCT6776_REG_PWM_MODE[] = { 0x04, 0, 0, 0, 0, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) static const u8 NCT6776_PWM_MODE_MASK[] = { 0x01, 0, 0, 0, 0, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) static const u16 NCT6776_REG_FAN_MIN[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	0x63a, 0x63c, 0x63e, 0x640, 0x642, 0x64a, 0x64c };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) static const u16 NCT6776_REG_FAN_PULSES[NUM_FAN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	0x644, 0x645, 0x646, 0x647, 0x648, 0x649 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) static const u16 NCT6776_REG_WEIGHT_DUTY_BASE[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	0x13e, 0x23e, 0x33e, 0x83e, 0x93e, 0xa3e };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) static const u16 NCT6776_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	0x18, 0x152, 0x252, 0x628, 0x629, 0x62A };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) static const char *const nct6776_temp_label[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	"SYSTIN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	"CPUTIN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	"AUXTIN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	"SMBUSMASTER 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	"SMBUSMASTER 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	"SMBUSMASTER 2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	"SMBUSMASTER 3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	"SMBUSMASTER 4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	"SMBUSMASTER 5",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	"SMBUSMASTER 6",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	"SMBUSMASTER 7",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	"PECI Agent 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	"PECI Agent 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	"PCH_CHIP_CPU_MAX_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	"PCH_CHIP_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	"PCH_CPU_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	"PCH_MCH_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	"PCH_DIM0_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	"PCH_DIM1_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	"PCH_DIM2_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	"PCH_DIM3_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	"BYTE_TEMP"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) #define NCT6776_TEMP_MASK	0x007ffffe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) #define NCT6776_VIRT_TEMP_MASK	0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) static const u16 NCT6776_REG_TEMP_ALTERNATE[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	[14] = 0x401,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	[15] = 0x402,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	[16] = 0x404,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) static const u16 NCT6776_REG_TEMP_CRIT[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	[11] = 0x709,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	[12] = 0x70a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) /* NCT6779 specific data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) static const u16 NCT6779_REG_IN[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	0x480, 0x481, 0x482, 0x483, 0x484, 0x485, 0x486, 0x487,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	0x488, 0x489, 0x48a, 0x48b, 0x48c, 0x48d, 0x48e };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) static const u16 NCT6779_REG_ALARM[NUM_REG_ALARM] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	0x459, 0x45A, 0x45B, 0x568 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) static const s8 NCT6779_ALARM_BITS[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	0, 1, 2, 3, 8, 21, 20, 16,	/* in0.. in7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	17, 24, 25, 26, 27, 28, 29,	/* in8..in14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	-1,				/* unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	6, 7, 11, 10, 23,		/* fan1..fan5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	-1, -1, -1,			/* unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	4, 5, 13, -1, -1, -1,		/* temp1..temp6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	12, 9 };			/* intrusion0, intrusion1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) static const s8 NCT6779_BEEP_BITS[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	0, 1, 2, 3, 4, 5, 6, 7,		/* in0.. in7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	8, 9, 10, 11, 12, 13, 14,	/* in8..in14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	24,				/* global beep enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	25, 26, 27, 28, 29,		/* fan1..fan5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	-1, -1, -1,			/* unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	16, 17, -1, -1, -1, -1,		/* temp1..temp6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	30, 31 };			/* intrusion0, intrusion1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) static const u16 NCT6779_REG_FAN[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	0x4c0, 0x4c2, 0x4c4, 0x4c6, 0x4c8, 0x4ca, 0x4ce };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) static const u16 NCT6779_REG_FAN_PULSES[NUM_FAN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	0x644, 0x645, 0x646, 0x647, 0x648, 0x649, 0x64f };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) static const u16 NCT6779_REG_CRITICAL_PWM_ENABLE[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	0x136, 0x236, 0x336, 0x836, 0x936, 0xa36, 0xb36 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) #define NCT6779_CRITICAL_PWM_ENABLE_MASK	0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) static const u16 NCT6779_REG_CRITICAL_PWM[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	0x137, 0x237, 0x337, 0x837, 0x937, 0xa37, 0xb37 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) static const u16 NCT6779_REG_TEMP[] = { 0x27, 0x150 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) static const u16 NCT6779_REG_TEMP_MON[] = { 0x73, 0x75, 0x77, 0x79, 0x7b };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) static const u16 NCT6779_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	0x18, 0x152 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) static const u16 NCT6779_REG_TEMP_HYST[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	0x3a, 0x153 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) static const u16 NCT6779_REG_TEMP_OVER[ARRAY_SIZE(NCT6779_REG_TEMP)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	0x39, 0x155 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) static const u16 NCT6779_REG_TEMP_OFFSET[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	0x454, 0x455, 0x456, 0x44a, 0x44b, 0x44c };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) static const char *const nct6779_temp_label[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	"SYSTIN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	"CPUTIN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	"AUXTIN0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	"AUXTIN1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	"AUXTIN2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	"AUXTIN3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	"SMBUSMASTER 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	"SMBUSMASTER 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	"SMBUSMASTER 2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	"SMBUSMASTER 3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	"SMBUSMASTER 4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	"SMBUSMASTER 5",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	"SMBUSMASTER 6",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	"SMBUSMASTER 7",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	"PECI Agent 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	"PECI Agent 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	"PCH_CHIP_CPU_MAX_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	"PCH_CHIP_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	"PCH_CPU_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	"PCH_MCH_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	"PCH_DIM0_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	"PCH_DIM1_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	"PCH_DIM2_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	"PCH_DIM3_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	"BYTE_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	"Virtual_TEMP"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) #define NCT6779_TEMP_MASK	0x07ffff7e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) #define NCT6779_VIRT_TEMP_MASK	0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) #define NCT6791_TEMP_MASK	0x87ffff7e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) #define NCT6791_VIRT_TEMP_MASK	0x80000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) static const u16 NCT6779_REG_TEMP_ALTERNATE[32]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	= { 0x490, 0x491, 0x492, 0x493, 0x494, 0x495, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	    0, 0, 0, 0, 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	    0, 0x400, 0x401, 0x402, 0x404, 0x405, 0x406, 0x407,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	    0x408, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) static const u16 NCT6779_REG_TEMP_CRIT[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	[15] = 0x709,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	[16] = 0x70a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) /* NCT6791 specific data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) #define NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE	0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) static const u16 NCT6791_REG_WEIGHT_TEMP_SEL[NUM_FAN] = { 0, 0x239 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) static const u16 NCT6791_REG_WEIGHT_TEMP_STEP[NUM_FAN] = { 0, 0x23a };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) static const u16 NCT6791_REG_WEIGHT_TEMP_STEP_TOL[NUM_FAN] = { 0, 0x23b };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) static const u16 NCT6791_REG_WEIGHT_DUTY_STEP[NUM_FAN] = { 0, 0x23c };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) static const u16 NCT6791_REG_WEIGHT_TEMP_BASE[NUM_FAN] = { 0, 0x23d };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) static const u16 NCT6791_REG_WEIGHT_DUTY_BASE[NUM_FAN] = { 0, 0x23e };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) static const u16 NCT6791_REG_ALARM[NUM_REG_ALARM] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	0x459, 0x45A, 0x45B, 0x568, 0x45D };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) static const s8 NCT6791_ALARM_BITS[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	0, 1, 2, 3, 8, 21, 20, 16,	/* in0.. in7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	17, 24, 25, 26, 27, 28, 29,	/* in8..in14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	-1,				/* unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	6, 7, 11, 10, 23, 33,		/* fan1..fan6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	-1, -1,				/* unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	4, 5, 13, -1, -1, -1,		/* temp1..temp6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	12, 9 };			/* intrusion0, intrusion1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) /* NCT6792/NCT6793 specific data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) static const u16 NCT6792_REG_TEMP_MON[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	0x73, 0x75, 0x77, 0x79, 0x7b, 0x7d };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) static const u16 NCT6792_REG_BEEP[NUM_REG_BEEP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	0xb2, 0xb3, 0xb4, 0xb5, 0xbf };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) static const char *const nct6792_temp_label[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	"SYSTIN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	"CPUTIN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	"AUXTIN0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	"AUXTIN1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	"AUXTIN2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	"AUXTIN3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	"SMBUSMASTER 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	"SMBUSMASTER 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	"SMBUSMASTER 2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	"SMBUSMASTER 3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	"SMBUSMASTER 4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	"SMBUSMASTER 5",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	"SMBUSMASTER 6",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	"SMBUSMASTER 7",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	"PECI Agent 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	"PECI Agent 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	"PCH_CHIP_CPU_MAX_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	"PCH_CHIP_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	"PCH_CPU_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	"PCH_MCH_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	"PCH_DIM0_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	"PCH_DIM1_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	"PCH_DIM2_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	"PCH_DIM3_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	"BYTE_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	"PECI Agent 0 Calibration",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	"PECI Agent 1 Calibration",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	"Virtual_TEMP"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) #define NCT6792_TEMP_MASK	0x9fffff7e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) #define NCT6792_VIRT_TEMP_MASK	0x80000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) static const char *const nct6793_temp_label[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	"SYSTIN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	"CPUTIN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	"AUXTIN0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	"AUXTIN1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	"AUXTIN2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	"AUXTIN3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	"SMBUSMASTER 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	"SMBUSMASTER 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	"PECI Agent 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	"PECI Agent 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	"PCH_CHIP_CPU_MAX_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	"PCH_CHIP_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	"PCH_CPU_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	"PCH_MCH_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	"Agent0 Dimm0 ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	"Agent0 Dimm1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	"Agent1 Dimm0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	"Agent1 Dimm1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	"BYTE_TEMP0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	"BYTE_TEMP1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	"PECI Agent 0 Calibration",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	"PECI Agent 1 Calibration",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	"Virtual_TEMP"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) #define NCT6793_TEMP_MASK	0xbfff037e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) #define NCT6793_VIRT_TEMP_MASK	0x80000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) static const char *const nct6795_temp_label[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	"SYSTIN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	"CPUTIN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	"AUXTIN0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	"AUXTIN1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	"AUXTIN2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	"AUXTIN3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	"SMBUSMASTER 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	"SMBUSMASTER 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	"SMBUSMASTER 2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	"SMBUSMASTER 3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	"SMBUSMASTER 4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	"SMBUSMASTER 5",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	"SMBUSMASTER 6",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	"SMBUSMASTER 7",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	"PECI Agent 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	"PECI Agent 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	"PCH_CHIP_CPU_MAX_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	"PCH_CHIP_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	"PCH_CPU_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	"PCH_MCH_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	"Agent0 Dimm0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	"Agent0 Dimm1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	"Agent1 Dimm0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	"Agent1 Dimm1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	"BYTE_TEMP0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	"BYTE_TEMP1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	"PECI Agent 0 Calibration",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	"PECI Agent 1 Calibration",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	"Virtual_TEMP"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) #define NCT6795_TEMP_MASK	0xbfffff7e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) #define NCT6795_VIRT_TEMP_MASK	0x80000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) static const char *const nct6796_temp_label[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	"SYSTIN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	"CPUTIN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	"AUXTIN0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	"AUXTIN1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	"AUXTIN2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	"AUXTIN3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	"AUXTIN4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	"SMBUSMASTER 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	"SMBUSMASTER 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	"Virtual_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	"Virtual_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	"PECI Agent 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	"PECI Agent 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	"PCH_CHIP_CPU_MAX_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	"PCH_CHIP_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	"PCH_CPU_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	"PCH_MCH_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	"Agent0 Dimm0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	"Agent0 Dimm1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	"Agent1 Dimm0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	"Agent1 Dimm1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	"BYTE_TEMP0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	"BYTE_TEMP1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	"PECI Agent 0 Calibration",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	"PECI Agent 1 Calibration",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	"Virtual_TEMP"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) #define NCT6796_TEMP_MASK	0xbfff0ffe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) #define NCT6796_VIRT_TEMP_MASK	0x80000c00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) static const char *const nct6798_temp_label[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	"SYSTIN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	"CPUTIN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	"AUXTIN0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	"AUXTIN1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	"AUXTIN2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	"AUXTIN3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	"AUXTIN4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	"SMBUSMASTER 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	"SMBUSMASTER 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	"Virtual_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	"Virtual_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	"PECI Agent 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	"PECI Agent 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	"PCH_CHIP_CPU_MAX_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	"PCH_CHIP_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	"PCH_CPU_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	"PCH_MCH_TEMP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	"Agent0 Dimm0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	"Agent0 Dimm1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	"Agent1 Dimm0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	"Agent1 Dimm1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	"BYTE_TEMP0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	"BYTE_TEMP1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	"PECI Agent 0 Calibration",	/* undocumented */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	"PECI Agent 1 Calibration",	/* undocumented */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	"Virtual_TEMP"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) #define NCT6798_TEMP_MASK	0xbfff0ffe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) #define NCT6798_VIRT_TEMP_MASK	0x80000c00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) /* NCT6102D/NCT6106D specific data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) #define NCT6106_REG_VBAT	0x318
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) #define NCT6106_REG_DIODE	0x319
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) #define NCT6106_DIODE_MASK	0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) static const u16 NCT6106_REG_IN_MAX[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9e, 0xa0, 0xa2 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) static const u16 NCT6106_REG_IN_MIN[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	0x91, 0x93, 0x95, 0x97, 0x99, 0x9b, 0x9f, 0xa1, 0xa3 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) static const u16 NCT6106_REG_IN[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x09 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) static const u16 NCT6106_REG_TEMP[] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) static const u16 NCT6106_REG_TEMP_MON[] = { 0x18, 0x19, 0x1a };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) static const u16 NCT6106_REG_TEMP_HYST[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	0xc3, 0xc7, 0xcb, 0xcf, 0xd3, 0xd7 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) static const u16 NCT6106_REG_TEMP_OVER[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	0xc2, 0xc6, 0xca, 0xce, 0xd2, 0xd6 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) static const u16 NCT6106_REG_TEMP_CRIT_L[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	0xc0, 0xc4, 0xc8, 0xcc, 0xd0, 0xd4 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) static const u16 NCT6106_REG_TEMP_CRIT_H[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	0xc1, 0xc5, 0xc9, 0xcf, 0xd1, 0xd5 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) static const u16 NCT6106_REG_TEMP_OFFSET[] = { 0x311, 0x312, 0x313 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) static const u16 NCT6106_REG_TEMP_CONFIG[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) static const u16 NCT6106_REG_FAN[] = { 0x20, 0x22, 0x24 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) static const u16 NCT6106_REG_FAN_MIN[] = { 0xe0, 0xe2, 0xe4 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) static const u16 NCT6106_REG_FAN_PULSES[] = { 0xf6, 0xf6, 0xf6 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) static const u16 NCT6106_FAN_PULSE_SHIFT[] = { 0, 2, 4 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) static const u8 NCT6106_REG_PWM_MODE[] = { 0xf3, 0xf3, 0xf3 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) static const u8 NCT6106_PWM_MODE_MASK[] = { 0x01, 0x02, 0x04 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) static const u16 NCT6106_REG_PWM_READ[] = { 0x4a, 0x4b, 0x4c };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) static const u16 NCT6106_REG_FAN_MODE[] = { 0x113, 0x123, 0x133 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) static const u16 NCT6106_REG_TEMP_SOURCE[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) static const u16 NCT6106_REG_CRITICAL_TEMP[] = { 0x11a, 0x12a, 0x13a };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) static const u16 NCT6106_REG_CRITICAL_TEMP_TOLERANCE[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	0x11b, 0x12b, 0x13b };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) static const u16 NCT6106_REG_CRITICAL_PWM_ENABLE[] = { 0x11c, 0x12c, 0x13c };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) #define NCT6106_CRITICAL_PWM_ENABLE_MASK	0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) static const u16 NCT6106_REG_CRITICAL_PWM[] = { 0x11d, 0x12d, 0x13d };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) static const u16 NCT6106_REG_FAN_STEP_UP_TIME[] = { 0x114, 0x124, 0x134 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) static const u16 NCT6106_REG_FAN_STEP_DOWN_TIME[] = { 0x115, 0x125, 0x135 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) static const u16 NCT6106_REG_FAN_STOP_OUTPUT[] = { 0x116, 0x126, 0x136 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) static const u16 NCT6106_REG_FAN_START_OUTPUT[] = { 0x117, 0x127, 0x137 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) static const u16 NCT6106_REG_FAN_STOP_TIME[] = { 0x118, 0x128, 0x138 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) static const u16 NCT6106_REG_TOLERANCE_H[] = { 0x112, 0x122, 0x132 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) static const u16 NCT6106_REG_TARGET[] = { 0x111, 0x121, 0x131 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) static const u16 NCT6106_REG_WEIGHT_TEMP_SEL[] = { 0x168, 0x178, 0x188 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) static const u16 NCT6106_REG_WEIGHT_TEMP_STEP[] = { 0x169, 0x179, 0x189 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) static const u16 NCT6106_REG_WEIGHT_TEMP_STEP_TOL[] = { 0x16a, 0x17a, 0x18a };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) static const u16 NCT6106_REG_WEIGHT_DUTY_STEP[] = { 0x16b, 0x17b, 0x18b };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) static const u16 NCT6106_REG_WEIGHT_TEMP_BASE[] = { 0x16c, 0x17c, 0x18c };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) static const u16 NCT6106_REG_WEIGHT_DUTY_BASE[] = { 0x16d, 0x17d, 0x18d };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) static const u16 NCT6106_REG_AUTO_TEMP[] = { 0x160, 0x170, 0x180 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) static const u16 NCT6106_REG_AUTO_PWM[] = { 0x164, 0x174, 0x184 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) static const u16 NCT6106_REG_ALARM[NUM_REG_ALARM] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) static const s8 NCT6106_ALARM_BITS[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	0, 1, 2, 3, 4, 5, 7, 8,		/* in0.. in7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	9, -1, -1, -1, -1, -1, -1,	/* in8..in14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	-1,				/* unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	32, 33, 34, -1, -1,		/* fan1..fan5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	-1, -1, -1,			/* unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	16, 17, 18, 19, 20, 21,		/* temp1..temp6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	48, -1				/* intrusion0, intrusion1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) static const u16 NCT6106_REG_BEEP[NUM_REG_BEEP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	0x3c0, 0x3c1, 0x3c2, 0x3c3, 0x3c4 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) static const s8 NCT6106_BEEP_BITS[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	0, 1, 2, 3, 4, 5, 7, 8,		/* in0.. in7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	9, 10, 11, 12, -1, -1, -1,	/* in8..in14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	32,				/* global beep enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	24, 25, 26, 27, 28,		/* fan1..fan5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	-1, -1, -1,			/* unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	16, 17, 18, 19, 20, 21,		/* temp1..temp6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	34, -1				/* intrusion0, intrusion1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) static const u16 NCT6106_REG_TEMP_ALTERNATE[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	[14] = 0x51,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	[15] = 0x52,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	[16] = 0x54,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) static const u16 NCT6106_REG_TEMP_CRIT[32] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	[11] = 0x204,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	[12] = 0x205,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) /* NCT6112D/NCT6114D/NCT6116D specific data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) static const u16 NCT6116_REG_FAN[] = { 0x20, 0x22, 0x24, 0x26, 0x28 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) static const u16 NCT6116_REG_FAN_MIN[] = { 0xe0, 0xe2, 0xe4, 0xe6, 0xe8 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) static const u16 NCT6116_REG_FAN_PULSES[] = { 0xf6, 0xf6, 0xf6, 0xf6, 0xf5 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) static const u16 NCT6116_FAN_PULSE_SHIFT[] = { 0, 2, 4, 6, 6 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) static const u16 NCT6116_REG_PWM[] = { 0x119, 0x129, 0x139, 0x199, 0x1a9 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) static const u16 NCT6116_REG_FAN_MODE[] = { 0x113, 0x123, 0x133, 0x193, 0x1a3 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) static const u16 NCT6116_REG_TEMP_SEL[] = { 0x110, 0x120, 0x130, 0x190, 0x1a0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) static const u16 NCT6116_REG_TEMP_SOURCE[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	0xb0, 0xb1, 0xb2 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) static const u16 NCT6116_REG_CRITICAL_TEMP[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	0x11a, 0x12a, 0x13a, 0x19a, 0x1aa };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) static const u16 NCT6116_REG_CRITICAL_TEMP_TOLERANCE[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	0x11b, 0x12b, 0x13b, 0x19b, 0x1ab };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) static const u16 NCT6116_REG_CRITICAL_PWM_ENABLE[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	0x11c, 0x12c, 0x13c, 0x19c, 0x1ac };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) static const u16 NCT6116_REG_CRITICAL_PWM[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	0x11d, 0x12d, 0x13d, 0x19d, 0x1ad };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) static const u16 NCT6116_REG_FAN_STEP_UP_TIME[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	0x114, 0x124, 0x134, 0x194, 0x1a4 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) static const u16 NCT6116_REG_FAN_STEP_DOWN_TIME[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	0x115, 0x125, 0x135, 0x195, 0x1a5 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) static const u16 NCT6116_REG_FAN_STOP_OUTPUT[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	0x116, 0x126, 0x136, 0x196, 0x1a6 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) static const u16 NCT6116_REG_FAN_START_OUTPUT[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	0x117, 0x127, 0x137, 0x197, 0x1a7 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) static const u16 NCT6116_REG_FAN_STOP_TIME[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	0x118, 0x128, 0x138, 0x198, 0x1a8 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) static const u16 NCT6116_REG_TOLERANCE_H[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	0x112, 0x122, 0x132, 0x192, 0x1a2 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) static const u16 NCT6116_REG_TARGET[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	0x111, 0x121, 0x131, 0x191, 0x1a1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) static const u16 NCT6116_REG_AUTO_TEMP[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	0x160, 0x170, 0x180, 0x1d0, 0x1e0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) static const u16 NCT6116_REG_AUTO_PWM[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	0x164, 0x174, 0x184, 0x1d4, 0x1e4 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) static const s8 NCT6116_ALARM_BITS[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	0, 1, 2, 3, 4, 5, 7, 8,		/* in0.. in7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	9, -1, -1, -1, -1, -1, -1,	/* in8..in9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	-1,				/* unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	32, 33, 34, 35, 36,		/* fan1..fan5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	-1, -1, -1,			/* unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	16, 17, 18, -1, -1, -1,		/* temp1..temp6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	48, -1				/* intrusion0, intrusion1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) static const s8 NCT6116_BEEP_BITS[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	0, 1, 2, 3, 4, 5, 7, 8,		/* in0.. in7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	9, 10, 11, 12, -1, -1, -1,	/* in8..in14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	32,				/* global beep enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	24, 25, 26, 27, 28,		/* fan1..fan5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	-1, -1, -1,			/* unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	16, 17, 18, -1, -1, -1,		/* temp1..temp6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	34, -1				/* intrusion0, intrusion1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) static enum pwm_enable reg_to_pwm_enable(int pwm, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	if (mode == 0 && pwm == 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		return off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	return mode + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) static int pwm_enable_to_reg(enum pwm_enable mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	if (mode == off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	return mode - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980)  * Conversions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) /* 1 is DC mode, output in ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) static unsigned int step_time_from_reg(u8 reg, u8 mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	return mode ? 400 * reg : 100 * reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) static u8 step_time_to_reg(unsigned int msec, u8 mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	return clamp_val((mode ? (msec + 200) / 400 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 					(msec + 50) / 100), 1, 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) static unsigned int fan_from_reg8(u16 reg, unsigned int divreg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	if (reg == 0 || reg == 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	return 1350000U / (reg << divreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) static unsigned int fan_from_reg13(u16 reg, unsigned int divreg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	if ((reg & 0xff1f) == 0xff1f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	reg = (reg & 0x1f) | ((reg & 0xff00) >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	if (reg == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	return 1350000U / reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) static unsigned int fan_from_reg16(u16 reg, unsigned int divreg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	if (reg == 0 || reg == 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	 * Even though the registers are 16 bit wide, the fan divisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	 * still applies.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	return 1350000U / (reg << divreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) static unsigned int fan_from_reg_rpm(u16 reg, unsigned int divreg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	return reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) static u16 fan_to_reg(u32 fan, unsigned int divreg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	if (!fan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	return (1350000U / fan) >> divreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) static inline unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) div_from_reg(u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	return BIT(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)  * Some of the voltage inputs have internal scaling, the tables below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)  * contain 8 (the ADC LSB in mV) * scaling factor * 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) static const u16 scale_in[15] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 800, 800, 800, 800,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	800, 800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) static inline long in_from_reg(u8 reg, u8 nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	return DIV_ROUND_CLOSEST(reg * scale_in[nr], 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) static inline u8 in_to_reg(u32 val, u8 nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	return clamp_val(DIV_ROUND_CLOSEST(val * 100, scale_in[nr]), 0, 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)  * Data structures and manipulation thereof
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) struct nct6775_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	int addr;	/* IO base of hw monitor block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	int sioreg;	/* SIO register address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	enum kinds kind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	const struct attribute_group *groups[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	u16 reg_temp[5][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 				    * 3=temp_crit, 4=temp_lcrit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 				    */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	u8 temp_src[NUM_TEMP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	u16 reg_temp_config[NUM_TEMP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	const char * const *temp_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	u32 temp_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	u32 virt_temp_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	u16 REG_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	u16 REG_VBAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	u16 REG_DIODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	u8 DIODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	const s8 *ALARM_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	const s8 *BEEP_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	const u16 *REG_VIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	const u16 *REG_IN_MINMAX[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	const u16 *REG_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	const u16 *REG_FAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	const u16 *REG_FAN_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	const u16 *REG_FAN_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	const u16 *REG_FAN_PULSES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	const u16 *FAN_PULSE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	const u16 *REG_FAN_TIME[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	const u16 *REG_TOLERANCE_H;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	const u8 *REG_PWM_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	const u8 *PWM_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	const u16 *REG_PWM[7];	/* [0]=pwm, [1]=pwm_start, [2]=pwm_floor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 				 * [3]=pwm_max, [4]=pwm_step,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 				 * [5]=weight_duty_step, [6]=weight_duty_base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	const u16 *REG_PWM_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	const u16 *REG_CRITICAL_PWM_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	u8 CRITICAL_PWM_ENABLE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	const u16 *REG_CRITICAL_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	const u16 *REG_AUTO_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	const u16 *REG_AUTO_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	const u16 *REG_CRITICAL_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	const u16 *REG_CRITICAL_TEMP_TOLERANCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	const u16 *REG_TEMP_SOURCE;	/* temp register sources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	const u16 *REG_TEMP_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	const u16 *REG_WEIGHT_TEMP_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	const u16 *REG_WEIGHT_TEMP[3];	/* 0=base, 1=tolerance, 2=step */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	const u16 *REG_TEMP_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	const u16 *REG_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	const u16 *REG_BEEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	unsigned int (*fan_from_reg)(u16 reg, unsigned int divreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	unsigned int (*fan_from_reg_min)(u16 reg, unsigned int divreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	struct mutex update_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	bool valid;		/* true if following fields are valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	unsigned long last_updated;	/* In jiffies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	/* Register values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	u8 bank;		/* current register bank */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	u8 in_num;		/* number of in inputs we have */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	u8 in[15][3];		/* [0]=in, [1]=in_max, [2]=in_min */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	unsigned int rpm[NUM_FAN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	u16 fan_min[NUM_FAN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	u8 fan_pulses[NUM_FAN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	u8 fan_div[NUM_FAN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	u8 has_pwm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	u8 has_fan;		/* some fan inputs can be disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	u8 has_fan_min;		/* some fans don't have min register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	bool has_fan_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	u8 num_temp_alarms;	/* 2, 3, or 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	u8 num_temp_beeps;	/* 2, 3, or 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	u8 temp_fixed_num;	/* 3 or 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	u8 temp_type[NUM_TEMP_FIXED];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	s8 temp_offset[NUM_TEMP_FIXED];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	s16 temp[5][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 				* 3=temp_crit, 4=temp_lcrit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	u64 alarms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	u64 beeps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	u8 pwm_num;	/* number of pwm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	u8 pwm_mode[NUM_FAN];	/* 0->DC variable voltage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 				 * 1->PWM variable duty cycle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	enum pwm_enable pwm_enable[NUM_FAN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 			/* 0->off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 			 * 1->manual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 			 * 2->thermal cruise mode (also called SmartFan I)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 			 * 3->fan speed cruise mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 			 * 4->SmartFan III
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 			 * 5->enhanced variable thermal cruise (SmartFan IV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	u8 pwm[7][NUM_FAN];	/* [0]=pwm, [1]=pwm_start, [2]=pwm_floor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 				 * [3]=pwm_max, [4]=pwm_step,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 				 * [5]=weight_duty_step, [6]=weight_duty_base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	u8 target_temp[NUM_FAN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	u8 target_temp_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	u32 target_speed[NUM_FAN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	u32 target_speed_tolerance[NUM_FAN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	u8 speed_tolerance_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	u8 temp_tolerance[2][NUM_FAN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	u8 tolerance_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	u8 fan_time[3][NUM_FAN]; /* 0 = stop_time, 1 = step_up, 2 = step_down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	/* Automatic fan speed control registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 	int auto_pwm_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	u8 auto_pwm[NUM_FAN][7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	u8 auto_temp[NUM_FAN][7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	u8 pwm_temp_sel[NUM_FAN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	u8 pwm_weight_temp_sel[NUM_FAN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	u8 weight_temp[3][NUM_FAN];	/* 0->temp_step, 1->temp_step_tol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 					 * 2->temp_base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 					 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	u8 vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	u8 vrm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	bool have_vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	u16 have_temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	u16 have_temp_fixed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	u16 have_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	/* Remember extra register values over suspend/resume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	u8 vbat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	u8 fandiv1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	u8 fandiv2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	u8 sio_reg_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) struct nct6775_sio_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	int sioreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	enum kinds kind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) struct sensor_device_template {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	struct device_attribute dev_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 	union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 		struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 			u8 nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 			u8 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 		} s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 		int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	} u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	bool s2;	/* true if both index and nr are used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) struct sensor_device_attr_u {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 		struct sensor_device_attribute a1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 		struct sensor_device_attribute_2 a2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	} u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	char name[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) #define __TEMPLATE_ATTR(_template, _mode, _show, _store) {	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	.attr = {.name = _template, .mode = _mode },		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	.show	= _show,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	.store	= _store,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) #define SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store, _index)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	{ .dev_attr = __TEMPLATE_ATTR(_template, _mode, _show, _store),	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	  .u.index = _index,						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	  .s2 = false }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) #define SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store,	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 				 _nr, _index)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 	{ .dev_attr = __TEMPLATE_ATTR(_template, _mode, _show, _store),	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	  .u.s.index = _index,						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	  .u.s.nr = _nr,						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	  .s2 = true }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) #define SENSOR_TEMPLATE(_name, _template, _mode, _show, _store, _index)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) static struct sensor_device_template sensor_dev_template_##_name	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	= SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store,	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 				 _index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) #define SENSOR_TEMPLATE_2(_name, _template, _mode, _show, _store,	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 			  _nr, _index)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) static struct sensor_device_template sensor_dev_template_##_name	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	= SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store,	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 				 _nr, _index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) struct sensor_template_group {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	struct sensor_device_template **templates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	umode_t (*is_visible)(struct kobject *, struct attribute *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	int base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) static struct attribute_group *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) nct6775_create_attr_group(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 			  const struct sensor_template_group *tg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 			  int repeat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	struct attribute_group *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	struct sensor_device_attr_u *su;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	struct sensor_device_attribute *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	struct sensor_device_attribute_2 *a2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	struct attribute **attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	struct sensor_device_template **t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	int i, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	if (repeat <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 	t = tg->templates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	for (count = 0; *t; t++, count++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 		;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	if (count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	group = devm_kzalloc(dev, sizeof(*group), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	if (group == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	attrs = devm_kcalloc(dev, repeat * count + 1, sizeof(*attrs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 			     GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	if (attrs == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	su = devm_kzalloc(dev, array3_size(repeat, count, sizeof(*su)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 			       GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	if (su == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	group->attrs = attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	group->is_visible = tg->is_visible;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	for (i = 0; i < repeat; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 		t = tg->templates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 		while (*t != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 			snprintf(su->name, sizeof(su->name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 				 (*t)->dev_attr.attr.name, tg->base + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 			if ((*t)->s2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 				a2 = &su->u.a2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 				sysfs_attr_init(&a2->dev_attr.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 				a2->dev_attr.attr.name = su->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 				a2->nr = (*t)->u.s.nr + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 				a2->index = (*t)->u.s.index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 				a2->dev_attr.attr.mode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 				  (*t)->dev_attr.attr.mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 				a2->dev_attr.show = (*t)->dev_attr.show;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 				a2->dev_attr.store = (*t)->dev_attr.store;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 				*attrs = &a2->dev_attr.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 				a = &su->u.a1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 				sysfs_attr_init(&a->dev_attr.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 				a->dev_attr.attr.name = su->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 				a->index = (*t)->u.index + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 				a->dev_attr.attr.mode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 				  (*t)->dev_attr.attr.mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 				a->dev_attr.show = (*t)->dev_attr.show;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 				a->dev_attr.store = (*t)->dev_attr.store;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 				*attrs = &a->dev_attr.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 			attrs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 			su++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 			t++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	return group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) static bool is_word_sized(struct nct6775_data *data, u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	switch (data->kind) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	case nct6106:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 		return reg == 0x20 || reg == 0x22 || reg == 0x24 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 		  reg == 0xe0 || reg == 0xe2 || reg == 0xe4 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 		  reg == 0x111 || reg == 0x121 || reg == 0x131;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	case nct6116:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 		return reg == 0x20 || reg == 0x22 || reg == 0x24 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 		  reg == 0x26 || reg == 0x28 || reg == 0xe0 || reg == 0xe2 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 		  reg == 0xe4 || reg == 0xe6 || reg == 0xe8 || reg == 0x111 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 		  reg == 0x121 || reg == 0x131 || reg == 0x191 || reg == 0x1a1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	case nct6775:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 		return (((reg & 0xff00) == 0x100 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 		    (reg & 0xff00) == 0x200) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 		   ((reg & 0x00ff) == 0x50 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 		    (reg & 0x00ff) == 0x53 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 		    (reg & 0x00ff) == 0x55)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 		  (reg & 0xfff0) == 0x630 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 		  reg == 0x640 || reg == 0x642 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 		  reg == 0x662 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 		  ((reg & 0xfff0) == 0x650 && (reg & 0x000f) >= 0x06) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 		  reg == 0x73 || reg == 0x75 || reg == 0x77;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	case nct6776:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 		return (((reg & 0xff00) == 0x100 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 		    (reg & 0xff00) == 0x200) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 		   ((reg & 0x00ff) == 0x50 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 		    (reg & 0x00ff) == 0x53 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 		    (reg & 0x00ff) == 0x55)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 		  (reg & 0xfff0) == 0x630 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 		  reg == 0x402 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 		  reg == 0x640 || reg == 0x642 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 		  ((reg & 0xfff0) == 0x650 && (reg & 0x000f) >= 0x06) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 		  reg == 0x73 || reg == 0x75 || reg == 0x77;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	case nct6779:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	case nct6791:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	case nct6792:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	case nct6793:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	case nct6795:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 	case nct6796:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	case nct6797:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	case nct6798:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 		return reg == 0x150 || reg == 0x153 || reg == 0x155 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 		  (reg & 0xfff0) == 0x4c0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 		  reg == 0x402 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 		  reg == 0x63a || reg == 0x63c || reg == 0x63e ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 		  reg == 0x640 || reg == 0x642 || reg == 0x64a ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 		  reg == 0x64c ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 		  reg == 0x73 || reg == 0x75 || reg == 0x77 || reg == 0x79 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 		  reg == 0x7b || reg == 0x7d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)  * On older chips, only registers 0x50-0x5f are banked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)  * On more recent chips, all registers are banked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)  * Assume that is the case and set the bank number for each access.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)  * Cache the bank number so it only needs to be set if it changes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) static inline void nct6775_set_bank(struct nct6775_data *data, u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	u8 bank = reg >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	if (data->bank != bank) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 		outb_p(NCT6775_REG_BANK, data->addr + ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 		outb_p(bank, data->addr + DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 		data->bank = bank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) static u16 nct6775_read_value(struct nct6775_data *data, u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	int res, word_sized = is_word_sized(data, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	nct6775_set_bank(data, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	res = inb_p(data->addr + DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 	if (word_sized) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 		outb_p((reg & 0xff) + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 		       data->addr + ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 		res = (res << 8) + inb_p(data->addr + DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) static int nct6775_write_value(struct nct6775_data *data, u16 reg, u16 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 	int word_sized = is_word_sized(data, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 	nct6775_set_bank(data, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	outb_p(reg & 0xff, data->addr + ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 	if (word_sized) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 		outb_p(value >> 8, data->addr + DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 		outb_p((reg & 0xff) + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 		       data->addr + ADDR_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	outb_p(value & 0xff, data->addr + DATA_REG_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) /* We left-align 8-bit temperature values to make the code simpler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) static u16 nct6775_read_temp(struct nct6775_data *data, u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 	u16 res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 	res = nct6775_read_value(data, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 	if (!is_word_sized(data, reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 		res <<= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) static int nct6775_write_temp(struct nct6775_data *data, u16 reg, u16 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 	if (!is_word_sized(data, reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 		value >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 	return nct6775_write_value(data, reg, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) /* This function assumes that the caller holds data->update_lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) static void nct6775_write_fan_div(struct nct6775_data *data, int nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 	switch (nr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 		reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 		    | (data->fan_div[0] & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 		nct6775_write_value(data, NCT6775_REG_FANDIV1, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 		reg = (nct6775_read_value(data, NCT6775_REG_FANDIV1) & 0x7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 		    | ((data->fan_div[1] << 4) & 0x70);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 		nct6775_write_value(data, NCT6775_REG_FANDIV1, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 		reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 		    | (data->fan_div[2] & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 		nct6775_write_value(data, NCT6775_REG_FANDIV2, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 	case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 		reg = (nct6775_read_value(data, NCT6775_REG_FANDIV2) & 0x7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 		    | ((data->fan_div[3] << 4) & 0x70);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 		nct6775_write_value(data, NCT6775_REG_FANDIV2, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) static void nct6775_write_fan_div_common(struct nct6775_data *data, int nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 	if (data->kind == nct6775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 		nct6775_write_fan_div(data, nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) static void nct6775_update_fan_div(struct nct6775_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 	u8 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 	i = nct6775_read_value(data, NCT6775_REG_FANDIV1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 	data->fan_div[0] = i & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 	data->fan_div[1] = (i & 0x70) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 	i = nct6775_read_value(data, NCT6775_REG_FANDIV2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 	data->fan_div[2] = i & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	if (data->has_fan & BIT(3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 		data->fan_div[3] = (i & 0x70) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) static void nct6775_update_fan_div_common(struct nct6775_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 	if (data->kind == nct6775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 		nct6775_update_fan_div(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) static void nct6775_init_fan_div(struct nct6775_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 	nct6775_update_fan_div_common(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	 * For all fans, start with highest divider value if the divider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	 * register is not initialized. This ensures that we get a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 	 * reading from the fan count register, even if it is not optimal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	 * We'll compute a better divider later on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 	for (i = 0; i < ARRAY_SIZE(data->fan_div); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 		if (!(data->has_fan & BIT(i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 		if (data->fan_div[i] == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 			data->fan_div[i] = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 			nct6775_write_fan_div_common(data, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) static void nct6775_init_fan_common(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 				    struct nct6775_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 	if (data->has_fan_div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 		nct6775_init_fan_div(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	 * If fan_min is not set (0), set it to 0xff to disable it. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 	 * prevents the unnecessary warning when fanX_min is reported as 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 	for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 		if (data->has_fan_min & BIT(i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 			reg = nct6775_read_value(data, data->REG_FAN_MIN[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 			if (!reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 				nct6775_write_value(data, data->REG_FAN_MIN[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 						    data->has_fan_div ? 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 								      : 0xff1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) static void nct6775_select_fan_div(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 				   struct nct6775_data *data, int nr, u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 	u8 fan_div = data->fan_div[nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	u16 fan_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 	if (!data->has_fan_div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	 * If we failed to measure the fan speed, or the reported value is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 	 * in the optimal range, and the clock divider can be modified,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 	 * let's try that for next time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 	if (reg == 0x00 && fan_div < 0x07)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 		fan_div++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 	else if (reg != 0x00 && reg < 0x30 && fan_div > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 		fan_div--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 	if (fan_div != data->fan_div[nr]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 		dev_dbg(dev, "Modifying fan%d clock divider from %u to %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 			nr + 1, div_from_reg(data->fan_div[nr]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 			div_from_reg(fan_div));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 		/* Preserve min limit if possible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 		if (data->has_fan_min & BIT(nr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 			fan_min = data->fan_min[nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 			if (fan_div > data->fan_div[nr]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 				if (fan_min != 255 && fan_min > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 					fan_min >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 				if (fan_min != 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 					fan_min <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 					if (fan_min > 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 						fan_min = 254;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 			if (fan_min != data->fan_min[nr]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 				data->fan_min[nr] = fan_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 				nct6775_write_value(data, data->REG_FAN_MIN[nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 						    fan_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 		data->fan_div[nr] = fan_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 		nct6775_write_fan_div_common(data, nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) static void nct6775_update_pwm(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 	int fanmodecfg, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 	bool duty_is_dc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 	for (i = 0; i < data->pwm_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 		if (!(data->has_pwm & BIT(i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 		duty_is_dc = data->REG_PWM_MODE[i] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 		  (nct6775_read_value(data, data->REG_PWM_MODE[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 		   & data->PWM_MODE_MASK[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 		data->pwm_mode[i] = !duty_is_dc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 		fanmodecfg = nct6775_read_value(data, data->REG_FAN_MODE[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 		for (j = 0; j < ARRAY_SIZE(data->REG_PWM); j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 			if (data->REG_PWM[j] && data->REG_PWM[j][i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 				data->pwm[j][i]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 				  = nct6775_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 						       data->REG_PWM[j][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 		data->pwm_enable[i] = reg_to_pwm_enable(data->pwm[0][i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 							(fanmodecfg >> 4) & 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 		if (!data->temp_tolerance[0][i] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 		    data->pwm_enable[i] != speed_cruise)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 			data->temp_tolerance[0][i] = fanmodecfg & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 		if (!data->target_speed_tolerance[i] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 		    data->pwm_enable[i] == speed_cruise) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 			u8 t = fanmodecfg & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 			if (data->REG_TOLERANCE_H) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 				t |= (nct6775_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 				      data->REG_TOLERANCE_H[i]) & 0x70) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 			data->target_speed_tolerance[i] = t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 		data->temp_tolerance[1][i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 			nct6775_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 					data->REG_CRITICAL_TEMP_TOLERANCE[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 		reg = nct6775_read_value(data, data->REG_TEMP_SEL[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 		data->pwm_temp_sel[i] = reg & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 		/* If fan can stop, report floor as 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 		if (reg & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 			data->pwm[2][i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 		if (!data->REG_WEIGHT_TEMP_SEL[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 		reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 		data->pwm_weight_temp_sel[i] = reg & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 		/* If weight is disabled, report weight source as 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 		if (!(reg & 0x80))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 			data->pwm_weight_temp_sel[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 		/* Weight temp data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 		for (j = 0; j < ARRAY_SIZE(data->weight_temp); j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 			data->weight_temp[j][i]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 			  = nct6775_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 					       data->REG_WEIGHT_TEMP[j][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) static void nct6775_update_pwm_limits(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 	u16 reg_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 	for (i = 0; i < data->pwm_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 		if (!(data->has_pwm & BIT(i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 		for (j = 0; j < ARRAY_SIZE(data->fan_time); j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 			data->fan_time[j][i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 			  nct6775_read_value(data, data->REG_FAN_TIME[j][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 		reg_t = nct6775_read_value(data, data->REG_TARGET[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 		/* Update only in matching mode or if never updated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 		if (!data->target_temp[i] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 		    data->pwm_enable[i] == thermal_cruise)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 			data->target_temp[i] = reg_t & data->target_temp_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 		if (!data->target_speed[i] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 		    data->pwm_enable[i] == speed_cruise) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 			if (data->REG_TOLERANCE_H) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 				reg_t |= (nct6775_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 					data->REG_TOLERANCE_H[i]) & 0x0f) << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 			data->target_speed[i] = reg_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 		for (j = 0; j < data->auto_pwm_num; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 			data->auto_pwm[i][j] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 			  nct6775_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 					     NCT6775_AUTO_PWM(data, i, j));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 			data->auto_temp[i][j] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 			  nct6775_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 					     NCT6775_AUTO_TEMP(data, i, j));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 		/* critical auto_pwm temperature data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 		data->auto_temp[i][data->auto_pwm_num] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 			nct6775_read_value(data, data->REG_CRITICAL_TEMP[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 		switch (data->kind) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 		case nct6775:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 			reg = nct6775_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 						 NCT6775_REG_CRITICAL_ENAB[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 			data->auto_pwm[i][data->auto_pwm_num] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 						(reg & 0x02) ? 0xff : 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 		case nct6776:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 			data->auto_pwm[i][data->auto_pwm_num] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 		case nct6106:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 		case nct6116:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 		case nct6779:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 		case nct6791:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 		case nct6792:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 		case nct6793:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 		case nct6795:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 		case nct6796:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 		case nct6797:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 		case nct6798:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 			reg = nct6775_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 					data->REG_CRITICAL_PWM_ENABLE[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 			if (reg & data->CRITICAL_PWM_ENABLE_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 				reg = nct6775_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 					data->REG_CRITICAL_PWM[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 				reg = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 			data->auto_pwm[i][data->auto_pwm_num] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) static struct nct6775_data *nct6775_update_device(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 	    || !data->valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 		/* Fan clock dividers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 		nct6775_update_fan_div_common(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 		/* Measured voltages and limits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 		for (i = 0; i < data->in_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 			if (!(data->have_in & BIT(i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 			data->in[i][0] = nct6775_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 							    data->REG_VIN[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 			data->in[i][1] = nct6775_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 					  data->REG_IN_MINMAX[0][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 			data->in[i][2] = nct6775_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 					  data->REG_IN_MINMAX[1][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 		/* Measured fan speeds and limits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 		for (i = 0; i < ARRAY_SIZE(data->rpm); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 			u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 			if (!(data->has_fan & BIT(i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 			reg = nct6775_read_value(data, data->REG_FAN[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 			data->rpm[i] = data->fan_from_reg(reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 							  data->fan_div[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 			if (data->has_fan_min & BIT(i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 				data->fan_min[i] = nct6775_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 					   data->REG_FAN_MIN[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 			if (data->REG_FAN_PULSES[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 				data->fan_pulses[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 				  (nct6775_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 						      data->REG_FAN_PULSES[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 				   >> data->FAN_PULSE_SHIFT[i]) & 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 			nct6775_select_fan_div(dev, data, i, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 		nct6775_update_pwm(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 		nct6775_update_pwm_limits(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 		/* Measured temperatures and limits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 		for (i = 0; i < NUM_TEMP; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 			if (!(data->have_temp & BIT(i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 			for (j = 0; j < ARRAY_SIZE(data->reg_temp); j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 				if (data->reg_temp[j][i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 					data->temp[j][i]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 					  = nct6775_read_temp(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 						data->reg_temp[j][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 			if (i >= NUM_TEMP_FIXED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 			    !(data->have_temp_fixed & BIT(i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 			data->temp_offset[i]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 			  = nct6775_read_value(data, data->REG_TEMP_OFFSET[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 		data->alarms = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 		for (i = 0; i < NUM_REG_ALARM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 			u8 alarm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 			if (!data->REG_ALARM[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 			alarm = nct6775_read_value(data, data->REG_ALARM[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 			data->alarms |= ((u64)alarm) << (i << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 		data->beeps = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 		for (i = 0; i < NUM_REG_BEEP; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 			u8 beep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 			if (!data->REG_BEEP[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 			beep = nct6775_read_value(data, data->REG_BEEP[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 			data->beeps |= ((u64)beep) << (i << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 		data->last_updated = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 		data->valid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 	return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868)  * Sysfs callback functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) show_in_reg(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 	int index = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 	int nr = sattr->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 	return sprintf(buf, "%ld\n", in_from_reg(data->in[nr][index], nr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 	     size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 	int index = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 	int nr = sattr->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 	err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 	data->in[nr][index] = in_to_reg(val, nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 	nct6775_write_value(data, data->REG_IN_MINMAX[index - 1][nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 			    data->in[nr][index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) show_alarm(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 	int nr = data->ALARM_BITS[sattr->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 	return sprintf(buf, "%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 		       (unsigned int)((data->alarms >> nr) & 0x01));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) static int find_temp_source(struct nct6775_data *data, int index, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 	int source = data->temp_src[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 	int nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 	for (nr = 0; nr < count; nr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 		int src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 		src = nct6775_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 					 data->REG_TEMP_SOURCE[nr]) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 		if (src == source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 			return nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) show_temp_alarm(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 	unsigned int alarm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 	int nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 	 * For temperatures, there is no fixed mapping from registers to alarm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 	 * bits. Alarm bits are determined by the temperature source mapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 	nr = find_temp_source(data, sattr->index, data->num_temp_alarms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 	if (nr >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 		int bit = data->ALARM_BITS[nr + TEMP_ALARM_BASE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 		alarm = (data->alarms >> bit) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 	return sprintf(buf, "%u\n", alarm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) show_beep(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 	int nr = data->BEEP_BITS[sattr->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 	return sprintf(buf, "%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 		       (unsigned int)((data->beeps >> nr) & 0x01));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) store_beep(struct device *dev, struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 	   size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 	int nr = data->BEEP_BITS[sattr->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 	int regindex = nr >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 	err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 	if (val > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 	if (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 		data->beeps |= (1ULL << nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 		data->beeps &= ~(1ULL << nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 	nct6775_write_value(data, data->REG_BEEP[regindex],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 			    (data->beeps >> (regindex << 3)) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) show_temp_beep(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 	unsigned int beep = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 	int nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 	 * For temperatures, there is no fixed mapping from registers to beep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 	 * enable bits. Beep enable bits are determined by the temperature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 	 * source mapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 	nr = find_temp_source(data, sattr->index, data->num_temp_beeps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 	if (nr >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 		int bit = data->BEEP_BITS[nr + TEMP_ALARM_BASE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 		beep = (data->beeps >> bit) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 	return sprintf(buf, "%u\n", beep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) store_temp_beep(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 		const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 	int nr, bit, regindex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 	err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 	if (val > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 	nr = find_temp_source(data, sattr->index, data->num_temp_beeps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 	if (nr < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 		return nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 	bit = data->BEEP_BITS[nr + TEMP_ALARM_BASE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 	regindex = bit >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 	if (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 		data->beeps |= (1ULL << bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 		data->beeps &= ~(1ULL << bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 	nct6775_write_value(data, data->REG_BEEP[regindex],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 			    (data->beeps >> (regindex << 3)) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) static umode_t nct6775_in_is_visible(struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 				     struct attribute *attr, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 	struct device *dev = kobj_to_dev(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 	int in = index / 5;	/* voltage index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 	if (!(data->have_in & BIT(in)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 	return attr->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) SENSOR_TEMPLATE_2(in_input, "in%d_input", S_IRUGO, show_in_reg, NULL, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) SENSOR_TEMPLATE(in_alarm, "in%d_alarm", S_IRUGO, show_alarm, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) SENSOR_TEMPLATE(in_beep, "in%d_beep", S_IWUSR | S_IRUGO, show_beep, store_beep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 		0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) SENSOR_TEMPLATE_2(in_min, "in%d_min", S_IWUSR | S_IRUGO, show_in_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 		  store_in_reg, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) SENSOR_TEMPLATE_2(in_max, "in%d_max", S_IWUSR | S_IRUGO, show_in_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 		  store_in_reg, 0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070)  * nct6775_in_is_visible uses the index into the following array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071)  * to determine if attributes should be created or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072)  * Any change in order or content must be matched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) static struct sensor_device_template *nct6775_attributes_in_template[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 	&sensor_dev_template_in_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 	&sensor_dev_template_in_alarm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 	&sensor_dev_template_in_beep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 	&sensor_dev_template_in_min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 	&sensor_dev_template_in_max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) static const struct sensor_template_group nct6775_in_template_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 	.templates = nct6775_attributes_in_template,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 	.is_visible = nct6775_in_is_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) show_fan(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 	int nr = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 	return sprintf(buf, "%d\n", data->rpm[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) show_fan_min(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 	int nr = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 	return sprintf(buf, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 		       data->fan_from_reg_min(data->fan_min[nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 					      data->fan_div[nr]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) show_fan_div(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 	int nr = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 	return sprintf(buf, "%u\n", div_from_reg(data->fan_div[nr]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) store_fan_min(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 	      const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 	int nr = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 	unsigned int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 	u8 new_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 	err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 	if (!data->has_fan_div) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 		/* NCT6776F or NCT6779D; we know this is a 13 bit register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 		if (!val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 			val = 0xff1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 			if (val > 1350000U)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 				val = 135000U;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 			val = 1350000U / val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 			val = (val & 0x1f) | ((val << 3) & 0xff00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 		data->fan_min[nr] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 		goto write_min;	/* Leave fan divider alone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 	if (!val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 		/* No min limit, alarm disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 		data->fan_min[nr] = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 		new_div = data->fan_div[nr]; /* No change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 		dev_info(dev, "fan%u low limit and alarm disabled\n", nr + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 		goto write_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 	reg = 1350000U / val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 	if (reg >= 128 * 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 		 * Speed below this value cannot possibly be represented,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 		 * even with the highest divider (128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 		data->fan_min[nr] = 254;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 		new_div = 7; /* 128 == BIT(7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 		dev_warn(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 			 "fan%u low limit %lu below minimum %u, set to minimum\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 			 nr + 1, val, data->fan_from_reg_min(254, 7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 	} else if (!reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 		 * Speed above this value cannot possibly be represented,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 		 * even with the lowest divider (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 		data->fan_min[nr] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 		new_div = 0; /* 1 == BIT(0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 		dev_warn(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 			 "fan%u low limit %lu above maximum %u, set to maximum\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 			 nr + 1, val, data->fan_from_reg_min(1, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 		 * Automatically pick the best divider, i.e. the one such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 		 * that the min limit will correspond to a register value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 		 * in the 96..192 range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 		new_div = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 		while (reg > 192 && new_div < 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 			reg >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 			new_div++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 		data->fan_min[nr] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) write_div:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 	 * Write both the fan clock divider (if it changed) and the new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 	 * fan min (unconditionally)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 	if (new_div != data->fan_div[nr]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 		dev_dbg(dev, "fan%u clock divider changed from %u to %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 			nr + 1, div_from_reg(data->fan_div[nr]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 			div_from_reg(new_div));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 		data->fan_div[nr] = new_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 		nct6775_write_fan_div_common(data, nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 		/* Give the chip time to sample a new speed value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 		data->last_updated = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) write_min:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 	nct6775_write_value(data, data->REG_FAN_MIN[nr], data->fan_min[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) show_fan_pulses(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 	int p = data->fan_pulses[sattr->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 	return sprintf(buf, "%d\n", p ? : 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) store_fan_pulses(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 		 const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 	int nr = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 	err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 	if (val > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 	data->fan_pulses[nr] = val & 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 	reg = nct6775_read_value(data, data->REG_FAN_PULSES[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 	reg &= ~(0x03 << data->FAN_PULSE_SHIFT[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 	reg |= (val & 3) << data->FAN_PULSE_SHIFT[nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 	nct6775_write_value(data, data->REG_FAN_PULSES[nr], reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) static umode_t nct6775_fan_is_visible(struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 				      struct attribute *attr, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 	struct device *dev = kobj_to_dev(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 	int fan = index / 6;	/* fan index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 	int nr = index % 6;	/* attribute index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 	if (!(data->has_fan & BIT(fan)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 	if (nr == 1 && data->ALARM_BITS[FAN_ALARM_BASE + fan] == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 	if (nr == 2 && data->BEEP_BITS[FAN_ALARM_BASE + fan] == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 	if (nr == 3 && !data->REG_FAN_PULSES[fan])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 	if (nr == 4 && !(data->has_fan_min & BIT(fan)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 	if (nr == 5 && data->kind != nct6775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 	return attr->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) SENSOR_TEMPLATE(fan_input, "fan%d_input", S_IRUGO, show_fan, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) SENSOR_TEMPLATE(fan_alarm, "fan%d_alarm", S_IRUGO, show_alarm, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 		FAN_ALARM_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) SENSOR_TEMPLATE(fan_beep, "fan%d_beep", S_IWUSR | S_IRUGO, show_beep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 		store_beep, FAN_ALARM_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) SENSOR_TEMPLATE(fan_pulses, "fan%d_pulses", S_IWUSR | S_IRUGO, show_fan_pulses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 		store_fan_pulses, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) SENSOR_TEMPLATE(fan_min, "fan%d_min", S_IWUSR | S_IRUGO, show_fan_min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 		store_fan_min, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) SENSOR_TEMPLATE(fan_div, "fan%d_div", S_IRUGO, show_fan_div, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290)  * nct6775_fan_is_visible uses the index into the following array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291)  * to determine if attributes should be created or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292)  * Any change in order or content must be matched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) static struct sensor_device_template *nct6775_attributes_fan_template[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 	&sensor_dev_template_fan_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 	&sensor_dev_template_fan_alarm,	/* 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 	&sensor_dev_template_fan_beep,	/* 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 	&sensor_dev_template_fan_pulses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 	&sensor_dev_template_fan_min,	/* 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 	&sensor_dev_template_fan_div,	/* 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) static const struct sensor_template_group nct6775_fan_template_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 	.templates = nct6775_attributes_fan_template,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 	.is_visible = nct6775_fan_is_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 	.base = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) show_temp_label(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 	int nr = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 	return sprintf(buf, "%s\n", data->temp_label[data->temp_src[nr]]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) show_temp(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 	int nr = sattr->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 	int index = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 	return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->temp[index][nr]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) store_temp(struct device *dev, struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 	   size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 	int nr = sattr->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 	int index = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 	long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 	err = kstrtol(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 	data->temp[index][nr] = LM75_TEMP_TO_REG(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 	nct6775_write_temp(data, data->reg_temp[index][nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 			   data->temp[index][nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) show_temp_offset(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 	return sprintf(buf, "%d\n", data->temp_offset[sattr->index] * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) store_temp_offset(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 		  const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 	int nr = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 	long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 	err = kstrtol(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 	val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 	data->temp_offset[nr] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 	nct6775_write_value(data, data->REG_TEMP_OFFSET[nr], val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) show_temp_type(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 	int nr = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 	return sprintf(buf, "%d\n", (int)data->temp_type[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) store_temp_type(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 		const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 	int nr = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 	u8 vbat, diode, vbit, dbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 	err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 	if (val != 1 && val != 3 && val != 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 	data->temp_type[nr] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 	vbit = 0x02 << nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 	dbit = data->DIODE_MASK << nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 	vbat = nct6775_read_value(data, data->REG_VBAT) & ~vbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 	diode = nct6775_read_value(data, data->REG_DIODE) & ~dbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 	switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 	case 1:	/* CPU diode (diode, current mode) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 		vbat |= vbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 		diode |= dbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 	case 3: /* diode, voltage mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 		vbat |= dbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 	case 4:	/* thermistor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 	nct6775_write_value(data, data->REG_VBAT, vbat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 	nct6775_write_value(data, data->REG_DIODE, diode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) static umode_t nct6775_temp_is_visible(struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 				       struct attribute *attr, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 	struct device *dev = kobj_to_dev(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 	int temp = index / 10;	/* temp index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 	int nr = index % 10;	/* attribute index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 	if (!(data->have_temp & BIT(temp)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 	if (nr == 1 && !data->temp_label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 	if (nr == 2 && find_temp_source(data, temp, data->num_temp_alarms) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 		return 0;				/* alarm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 	if (nr == 3 && find_temp_source(data, temp, data->num_temp_beeps) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 		return 0;				/* beep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 	if (nr == 4 && !data->reg_temp[1][temp])	/* max */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 	if (nr == 5 && !data->reg_temp[2][temp])	/* max_hyst */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 	if (nr == 6 && !data->reg_temp[3][temp])	/* crit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 	if (nr == 7 && !data->reg_temp[4][temp])	/* lcrit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 	/* offset and type only apply to fixed sensors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 	if (nr > 7 && !(data->have_temp_fixed & BIT(temp)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 	return attr->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) SENSOR_TEMPLATE_2(temp_input, "temp%d_input", S_IRUGO, show_temp, NULL, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) SENSOR_TEMPLATE(temp_label, "temp%d_label", S_IRUGO, show_temp_label, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) SENSOR_TEMPLATE_2(temp_max, "temp%d_max", S_IRUGO | S_IWUSR, show_temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 		  store_temp, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) SENSOR_TEMPLATE_2(temp_max_hyst, "temp%d_max_hyst", S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 		  show_temp, store_temp, 0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) SENSOR_TEMPLATE_2(temp_crit, "temp%d_crit", S_IRUGO | S_IWUSR, show_temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 		  store_temp, 0, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) SENSOR_TEMPLATE_2(temp_lcrit, "temp%d_lcrit", S_IRUGO | S_IWUSR, show_temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 		  store_temp, 0, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) SENSOR_TEMPLATE(temp_offset, "temp%d_offset", S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 		show_temp_offset, store_temp_offset, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) SENSOR_TEMPLATE(temp_type, "temp%d_type", S_IRUGO | S_IWUSR, show_temp_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 		store_temp_type, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) SENSOR_TEMPLATE(temp_alarm, "temp%d_alarm", S_IRUGO, show_temp_alarm, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) SENSOR_TEMPLATE(temp_beep, "temp%d_beep", S_IRUGO | S_IWUSR, show_temp_beep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 		store_temp_beep, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498)  * nct6775_temp_is_visible uses the index into the following array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499)  * to determine if attributes should be created or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500)  * Any change in order or content must be matched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) static struct sensor_device_template *nct6775_attributes_temp_template[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 	&sensor_dev_template_temp_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 	&sensor_dev_template_temp_label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 	&sensor_dev_template_temp_alarm,	/* 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 	&sensor_dev_template_temp_beep,		/* 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 	&sensor_dev_template_temp_max,		/* 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 	&sensor_dev_template_temp_max_hyst,	/* 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 	&sensor_dev_template_temp_crit,		/* 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 	&sensor_dev_template_temp_lcrit,	/* 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 	&sensor_dev_template_temp_offset,	/* 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 	&sensor_dev_template_temp_type,		/* 9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) static const struct sensor_template_group nct6775_temp_template_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 	.templates = nct6775_attributes_temp_template,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 	.is_visible = nct6775_temp_is_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 	.base = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 	return sprintf(buf, "%d\n", data->pwm_mode[sattr->index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) store_pwm_mode(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 	       const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 	int nr = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 	err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 	if (val > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 	/* Setting DC mode (0) is not supported for all chips/channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 	if (data->REG_PWM_MODE[nr] == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 		if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 		return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 	data->pwm_mode[nr] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 	reg = nct6775_read_value(data, data->REG_PWM_MODE[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 	reg &= ~data->PWM_MODE_MASK[nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 	if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 		reg |= data->PWM_MODE_MASK[nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 	nct6775_write_value(data, data->REG_PWM_MODE[nr], reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 	int nr = sattr->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 	int index = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 	int pwm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 	 * For automatic fan control modes, show current pwm readings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 	 * Otherwise, show the configured value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 	if (index == 0 && data->pwm_enable[nr] > manual)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 		pwm = nct6775_read_value(data, data->REG_PWM_READ[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 		pwm = data->pwm[index][nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 	return sprintf(buf, "%d\n", pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) store_pwm(struct device *dev, struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 	  size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 	int nr = sattr->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 	int index = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 	int minval[7] = { 0, 1, 1, data->pwm[2][nr], 0, 0, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 	int maxval[7]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 	  = { 255, 255, data->pwm[3][nr] ? : 255, 255, 255, 255, 255 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 	err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 	val = clamp_val(val, minval[index], maxval[index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 	data->pwm[index][nr] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 	nct6775_write_value(data, data->REG_PWM[index][nr], val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 	if (index == 2)	{ /* floor: disable if val == 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 		reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 		reg &= 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 		if (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 			reg |= 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 		nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) /* Returns 0 if OK, -EINVAL otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) static int check_trip_points(struct nct6775_data *data, int nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 	for (i = 0; i < data->auto_pwm_num - 1; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 		if (data->auto_temp[nr][i] > data->auto_temp[nr][i + 1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 	for (i = 0; i < data->auto_pwm_num - 1; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 		if (data->auto_pwm[nr][i] > data->auto_pwm[nr][i + 1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 	/* validate critical temperature and pwm if enabled (pwm > 0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 	if (data->auto_pwm[nr][data->auto_pwm_num]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 		if (data->auto_temp[nr][data->auto_pwm_num - 1] >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 				data->auto_temp[nr][data->auto_pwm_num] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 		    data->auto_pwm[nr][data->auto_pwm_num - 1] >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 				data->auto_pwm[nr][data->auto_pwm_num])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) static void pwm_update_registers(struct nct6775_data *data, int nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 	switch (data->pwm_enable[nr]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 	case off:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 	case manual:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 	case speed_cruise:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 		reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 		reg = (reg & ~data->tolerance_mask) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 		  (data->target_speed_tolerance[nr] & data->tolerance_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 		nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 		nct6775_write_value(data, data->REG_TARGET[nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 				    data->target_speed[nr] & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 		if (data->REG_TOLERANCE_H) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 			reg = (data->target_speed[nr] >> 8) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 			reg |= (data->target_speed_tolerance[nr] & 0x38) << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 			nct6775_write_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 					    data->REG_TOLERANCE_H[nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 					    reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 	case thermal_cruise:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 		nct6775_write_value(data, data->REG_TARGET[nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 				    data->target_temp[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 		reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 		reg = (reg & ~data->tolerance_mask) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 		  data->temp_tolerance[0][nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 		nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 	return sprintf(buf, "%d\n", data->pwm_enable[sattr->index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) store_pwm_enable(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 		 const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 	int nr = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 	u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 	err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 	if (val > sf4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 	if (val == sf3 && data->kind != nct6775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 	if (val == sf4 && check_trip_points(data, nr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 		dev_err(dev, "Inconsistent trip points, not switching to SmartFan IV mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 		dev_err(dev, "Adjust trip points and try again\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 	data->pwm_enable[nr] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 	if (val == off) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 		 * turn off pwm control: select manual mode, set pwm to maximum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 		data->pwm[0][nr] = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 		nct6775_write_value(data, data->REG_PWM[0][nr], 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 	pwm_update_registers(data, nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) 	reg = nct6775_read_value(data, data->REG_FAN_MODE[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 	reg &= 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 	reg |= pwm_enable_to_reg(val) << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 	nct6775_write_value(data, data->REG_FAN_MODE[nr], reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) show_pwm_temp_sel_common(struct nct6775_data *data, char *buf, int src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 	int i, sel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 	for (i = 0; i < NUM_TEMP; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 		if (!(data->have_temp & BIT(i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 		if (src == data->temp_src[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 			sel = i + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 	return sprintf(buf, "%d\n", sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) show_pwm_temp_sel(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 	int index = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 	return show_pwm_temp_sel_common(data, buf, data->pwm_temp_sel[index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) store_pwm_temp_sel(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 		   const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 	int nr = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 	int err, reg, src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 	err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 	if (val == 0 || val > NUM_TEMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 	if (!(data->have_temp & BIT(val - 1)) || !data->temp_src[val - 1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 	src = data->temp_src[val - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 	data->pwm_temp_sel[nr] = src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 	reg = nct6775_read_value(data, data->REG_TEMP_SEL[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 	reg &= 0xe0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 	reg |= src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 	nct6775_write_value(data, data->REG_TEMP_SEL[nr], reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) show_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 			 char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 	int index = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 	return show_pwm_temp_sel_common(data, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 					data->pwm_weight_temp_sel[index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) store_pwm_weight_temp_sel(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 			  const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 	int nr = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) 	int err, reg, src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 	err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 	if (val > NUM_TEMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 	val = array_index_nospec(val, NUM_TEMP + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 	if (val && (!(data->have_temp & BIT(val - 1)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 		    !data->temp_src[val - 1]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 	if (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 		src = data->temp_src[val - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 		data->pwm_weight_temp_sel[nr] = src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 		reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 		reg &= 0xe0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 		reg |= (src | 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 		nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 		data->pwm_weight_temp_sel[nr] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 		reg = nct6775_read_value(data, data->REG_WEIGHT_TEMP_SEL[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 		reg &= 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 		nct6775_write_value(data, data->REG_WEIGHT_TEMP_SEL[nr], reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) show_target_temp(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 	return sprintf(buf, "%d\n", data->target_temp[sattr->index] * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) store_target_temp(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 		  const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 	int nr = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 	err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 	val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 			data->target_temp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 	data->target_temp[nr] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 	pwm_update_registers(data, nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) show_target_speed(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 	int nr = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 	return sprintf(buf, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 		       fan_from_reg16(data->target_speed[nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 				      data->fan_div[nr]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) store_target_speed(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 		   const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 	int nr = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 	u16 speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 	err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 	val = clamp_val(val, 0, 1350000U);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 	speed = fan_to_reg(val, data->fan_div[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 	data->target_speed[nr] = speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 	pwm_update_registers(data, nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) show_temp_tolerance(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 		    char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 	int nr = sattr->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 	int index = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 	return sprintf(buf, "%d\n", data->temp_tolerance[index][nr] * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) store_temp_tolerance(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 		     const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 	int nr = sattr->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 	int index = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 	err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 	/* Limit tolerance as needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 	val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, data->tolerance_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 	data->temp_tolerance[index][nr] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 	if (index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) 		pwm_update_registers(data, nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) 		nct6775_write_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 				    data->REG_CRITICAL_TEMP_TOLERANCE[nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 				    val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957)  * Fan speed tolerance is a tricky beast, since the associated register is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958)  * a tick counter, but the value is reported and configured as rpm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959)  * Compute resulting low and high rpm values and report the difference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960)  * A fan speed tolerance only makes sense if a fan target speed has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961)  * configured, so only display values other than 0 if that is the case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) show_speed_tolerance(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 		     char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) 	int nr = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 	int target = data->target_speed[nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 	int tolerance = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) 	if (target) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) 		int low = target - data->target_speed_tolerance[nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) 		int high = target + data->target_speed_tolerance[nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 		if (low <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) 			low = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 		if (high > 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) 			high = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 		if (high < low)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) 			high = low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 		tolerance = (fan_from_reg16(low, data->fan_div[nr])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) 			     - fan_from_reg16(high, data->fan_div[nr])) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 	return sprintf(buf, "%d\n", tolerance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) store_speed_tolerance(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) 		      const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) 	struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) 	int nr = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) 	int low, high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 	err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 	high = fan_from_reg16(data->target_speed[nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 			      data->fan_div[nr]) + val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 	low = fan_from_reg16(data->target_speed[nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 			     data->fan_div[nr]) - val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 	if (low <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 		low = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 	if (high < low)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 		high = low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 	val = (fan_to_reg(low, data->fan_div[nr]) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 	       fan_to_reg(high, data->fan_div[nr])) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 	/* Limit tolerance as needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 	val = clamp_val(val, 0, data->speed_tolerance_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 	data->target_speed_tolerance[nr] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 	pwm_update_registers(data, nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) SENSOR_TEMPLATE_2(pwm, "pwm%d", S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) SENSOR_TEMPLATE(pwm_mode, "pwm%d_mode", S_IWUSR | S_IRUGO, show_pwm_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) 		store_pwm_mode, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) SENSOR_TEMPLATE(pwm_enable, "pwm%d_enable", S_IWUSR | S_IRUGO, show_pwm_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 		store_pwm_enable, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) SENSOR_TEMPLATE(pwm_temp_sel, "pwm%d_temp_sel", S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 		show_pwm_temp_sel, store_pwm_temp_sel, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) SENSOR_TEMPLATE(pwm_target_temp, "pwm%d_target_temp", S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) 		show_target_temp, store_target_temp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) SENSOR_TEMPLATE(fan_target, "fan%d_target", S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 		show_target_speed, store_target_speed, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) SENSOR_TEMPLATE(fan_tolerance, "fan%d_tolerance", S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 		show_speed_tolerance, store_speed_tolerance, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) /* Smart Fan registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) show_weight_temp(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) 	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) 	int nr = sattr->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 	int index = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) 	return sprintf(buf, "%d\n", data->weight_temp[index][nr] * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) store_weight_temp(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 		  const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 	int nr = sattr->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 	int index = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 	err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) 	val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 255);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) 	data->weight_temp[index][nr] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) 	nct6775_write_value(data, data->REG_WEIGHT_TEMP[index][nr], val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) SENSOR_TEMPLATE(pwm_weight_temp_sel, "pwm%d_weight_temp_sel", S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 		  show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) SENSOR_TEMPLATE_2(pwm_weight_temp_step, "pwm%d_weight_temp_step",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) 		  S_IWUSR | S_IRUGO, show_weight_temp, store_weight_temp, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) SENSOR_TEMPLATE_2(pwm_weight_temp_step_tol, "pwm%d_weight_temp_step_tol",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 		  S_IWUSR | S_IRUGO, show_weight_temp, store_weight_temp, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) SENSOR_TEMPLATE_2(pwm_weight_temp_step_base, "pwm%d_weight_temp_step_base",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) 		  S_IWUSR | S_IRUGO, show_weight_temp, store_weight_temp, 0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) SENSOR_TEMPLATE_2(pwm_weight_duty_step, "pwm%d_weight_duty_step",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 		  S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) SENSOR_TEMPLATE_2(pwm_weight_duty_base, "pwm%d_weight_duty_base",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 		  S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) show_fan_time(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 	int nr = sattr->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 	int index = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) 	return sprintf(buf, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 		       step_time_from_reg(data->fan_time[index][nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 					  data->pwm_mode[nr]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) store_fan_time(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 	       const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 	int nr = sattr->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) 	int index = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 	err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 	val = step_time_to_reg(val, data->pwm_mode[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 	data->fan_time[index][nr] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 	nct6775_write_value(data, data->REG_FAN_TIME[index][nr], val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) show_auto_pwm(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) 	return sprintf(buf, "%d\n", data->auto_pwm[sattr->nr][sattr->index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) store_auto_pwm(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) 	       const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 	int nr = sattr->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 	int point = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 	err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) 	if (val > 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 	if (point == data->auto_pwm_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 		if (data->kind != nct6775 && !val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 		if (data->kind != nct6779 && val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 			val = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) 	data->auto_pwm[nr][point] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) 	if (point < data->auto_pwm_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) 		nct6775_write_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) 				    NCT6775_AUTO_PWM(data, nr, point),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) 				    data->auto_pwm[nr][point]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) 		switch (data->kind) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) 		case nct6775:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) 			/* disable if needed (pwm == 0) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) 			reg = nct6775_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) 						 NCT6775_REG_CRITICAL_ENAB[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) 			if (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) 				reg |= 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 				reg &= ~0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) 			nct6775_write_value(data, NCT6775_REG_CRITICAL_ENAB[nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) 					    reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) 		case nct6776:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) 			break; /* always enabled, nothing to do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) 		case nct6106:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) 		case nct6116:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 		case nct6779:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 		case nct6791:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) 		case nct6792:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 		case nct6793:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) 		case nct6795:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) 		case nct6796:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) 		case nct6797:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) 		case nct6798:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) 			nct6775_write_value(data, data->REG_CRITICAL_PWM[nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) 					    val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) 			reg = nct6775_read_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 					data->REG_CRITICAL_PWM_ENABLE[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) 			if (val == 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) 				reg &= ~data->CRITICAL_PWM_ENABLE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) 				reg |= data->CRITICAL_PWM_ENABLE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) 			nct6775_write_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) 					    data->REG_CRITICAL_PWM_ENABLE[nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) 					    reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) show_auto_temp(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 	int nr = sattr->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) 	int point = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) 	 * We don't know for sure if the temperature is signed or unsigned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) 	 * Assume it is unsigned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) 	return sprintf(buf, "%d\n", data->auto_temp[nr][point] * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) store_auto_temp(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) 		const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) 	struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) 	int nr = sattr->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) 	int point = sattr->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) 	err = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) 	if (val > 255000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) 	data->auto_temp[nr][point] = DIV_ROUND_CLOSEST(val, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) 	if (point < data->auto_pwm_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) 		nct6775_write_value(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) 				    NCT6775_AUTO_TEMP(data, nr, point),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) 				    data->auto_temp[nr][point]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) 		nct6775_write_value(data, data->REG_CRITICAL_TEMP[nr],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) 				    data->auto_temp[nr][point]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) static umode_t nct6775_pwm_is_visible(struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) 				      struct attribute *attr, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) 	struct device *dev = kobj_to_dev(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) 	int pwm = index / 36;	/* pwm index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) 	int nr = index % 36;	/* attribute index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) 	if (!(data->has_pwm & BIT(pwm)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) 	if ((nr >= 14 && nr <= 18) || nr == 21)   /* weight */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) 		if (!data->REG_WEIGHT_TEMP_SEL[pwm])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) 	if (nr == 19 && data->REG_PWM[3] == NULL) /* pwm_max */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) 	if (nr == 20 && data->REG_PWM[4] == NULL) /* pwm_step */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) 	if (nr == 21 && data->REG_PWM[6] == NULL) /* weight_duty_base */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) 	if (nr >= 22 && nr <= 35) {		/* auto point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) 		int api = (nr - 22) / 2;	/* auto point index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) 		if (api > data->auto_pwm_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) 	return attr->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) SENSOR_TEMPLATE_2(pwm_stop_time, "pwm%d_stop_time", S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) 		  show_fan_time, store_fan_time, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) SENSOR_TEMPLATE_2(pwm_step_up_time, "pwm%d_step_up_time", S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) 		  show_fan_time, store_fan_time, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) SENSOR_TEMPLATE_2(pwm_step_down_time, "pwm%d_step_down_time", S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) 		  show_fan_time, store_fan_time, 0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) SENSOR_TEMPLATE_2(pwm_start, "pwm%d_start", S_IWUSR | S_IRUGO, show_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) 		  store_pwm, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) SENSOR_TEMPLATE_2(pwm_floor, "pwm%d_floor", S_IWUSR | S_IRUGO, show_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) 		  store_pwm, 0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) SENSOR_TEMPLATE_2(pwm_temp_tolerance, "pwm%d_temp_tolerance", S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) 		  show_temp_tolerance, store_temp_tolerance, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) SENSOR_TEMPLATE_2(pwm_crit_temp_tolerance, "pwm%d_crit_temp_tolerance",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) 		  S_IWUSR | S_IRUGO, show_temp_tolerance, store_temp_tolerance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 		  0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) SENSOR_TEMPLATE_2(pwm_max, "pwm%d_max", S_IWUSR | S_IRUGO, show_pwm, store_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) 		  0, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) SENSOR_TEMPLATE_2(pwm_step, "pwm%d_step", S_IWUSR | S_IRUGO, show_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) 		  store_pwm, 0, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) SENSOR_TEMPLATE_2(pwm_auto_point1_pwm, "pwm%d_auto_point1_pwm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) 		  S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) SENSOR_TEMPLATE_2(pwm_auto_point1_temp, "pwm%d_auto_point1_temp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) 		  S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) SENSOR_TEMPLATE_2(pwm_auto_point2_pwm, "pwm%d_auto_point2_pwm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) 		  S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) SENSOR_TEMPLATE_2(pwm_auto_point2_temp, "pwm%d_auto_point2_temp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) 		  S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) SENSOR_TEMPLATE_2(pwm_auto_point3_pwm, "pwm%d_auto_point3_pwm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) 		  S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) SENSOR_TEMPLATE_2(pwm_auto_point3_temp, "pwm%d_auto_point3_temp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) 		  S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) SENSOR_TEMPLATE_2(pwm_auto_point4_pwm, "pwm%d_auto_point4_pwm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) 		  S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) SENSOR_TEMPLATE_2(pwm_auto_point4_temp, "pwm%d_auto_point4_temp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) 		  S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) SENSOR_TEMPLATE_2(pwm_auto_point5_pwm, "pwm%d_auto_point5_pwm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) 		  S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) SENSOR_TEMPLATE_2(pwm_auto_point5_temp, "pwm%d_auto_point5_temp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) 		  S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) SENSOR_TEMPLATE_2(pwm_auto_point6_pwm, "pwm%d_auto_point6_pwm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) 		  S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) SENSOR_TEMPLATE_2(pwm_auto_point6_temp, "pwm%d_auto_point6_temp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) 		  S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) SENSOR_TEMPLATE_2(pwm_auto_point7_pwm, "pwm%d_auto_point7_pwm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) 		  S_IWUSR | S_IRUGO, show_auto_pwm, store_auto_pwm, 0, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) SENSOR_TEMPLATE_2(pwm_auto_point7_temp, "pwm%d_auto_point7_temp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) 		  S_IWUSR | S_IRUGO, show_auto_temp, store_auto_temp, 0, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345)  * nct6775_pwm_is_visible uses the index into the following array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346)  * to determine if attributes should be created or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347)  * Any change in order or content must be matched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) static struct sensor_device_template *nct6775_attributes_pwm_template[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) 	&sensor_dev_template_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) 	&sensor_dev_template_pwm_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) 	&sensor_dev_template_pwm_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) 	&sensor_dev_template_pwm_temp_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) 	&sensor_dev_template_pwm_temp_tolerance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) 	&sensor_dev_template_pwm_crit_temp_tolerance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) 	&sensor_dev_template_pwm_target_temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) 	&sensor_dev_template_fan_target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) 	&sensor_dev_template_fan_tolerance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) 	&sensor_dev_template_pwm_stop_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) 	&sensor_dev_template_pwm_step_up_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) 	&sensor_dev_template_pwm_step_down_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) 	&sensor_dev_template_pwm_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) 	&sensor_dev_template_pwm_floor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) 	&sensor_dev_template_pwm_weight_temp_sel,	/* 14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) 	&sensor_dev_template_pwm_weight_temp_step,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) 	&sensor_dev_template_pwm_weight_temp_step_tol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) 	&sensor_dev_template_pwm_weight_temp_step_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) 	&sensor_dev_template_pwm_weight_duty_step,	/* 18 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) 	&sensor_dev_template_pwm_max,			/* 19 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) 	&sensor_dev_template_pwm_step,			/* 20 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) 	&sensor_dev_template_pwm_weight_duty_base,	/* 21 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) 	&sensor_dev_template_pwm_auto_point1_pwm,	/* 22 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) 	&sensor_dev_template_pwm_auto_point1_temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) 	&sensor_dev_template_pwm_auto_point2_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) 	&sensor_dev_template_pwm_auto_point2_temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) 	&sensor_dev_template_pwm_auto_point3_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) 	&sensor_dev_template_pwm_auto_point3_temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) 	&sensor_dev_template_pwm_auto_point4_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) 	&sensor_dev_template_pwm_auto_point4_temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) 	&sensor_dev_template_pwm_auto_point5_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) 	&sensor_dev_template_pwm_auto_point5_temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) 	&sensor_dev_template_pwm_auto_point6_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) 	&sensor_dev_template_pwm_auto_point6_temp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) 	&sensor_dev_template_pwm_auto_point7_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) 	&sensor_dev_template_pwm_auto_point7_temp,	/* 35 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) 	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) static const struct sensor_template_group nct6775_pwm_template_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) 	.templates = nct6775_attributes_pwm_template,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) 	.is_visible = nct6775_pwm_is_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) 	.base = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) cpu0_vid_show(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) 	return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) static DEVICE_ATTR_RO(cpu0_vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) /* Case open detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) clear_caseopen(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) 	       const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) 	int nr = to_sensor_dev_attr(attr)->index - INTRUSION_ALARM_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) 	if (kstrtoul(buf, 10, &val) || val != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) 	 * Use CR registers to clear caseopen status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) 	 * The CR registers are the same for all chips, and not all chips
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) 	 * support clearing the caseopen status through "regular" registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) 	ret = superio_enter(data->sioreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) 		count = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) 	superio_select(data->sioreg, NCT6775_LD_ACPI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) 	reg = superio_inb(data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) 	reg |= NCT6775_CR_CASEOPEN_CLR_MASK[nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) 	superio_outb(data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) 	reg &= ~NCT6775_CR_CASEOPEN_CLR_MASK[nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) 	superio_outb(data->sioreg, NCT6775_REG_CR_CASEOPEN_CLR[nr], reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) 	superio_exit(data->sioreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) 	data->valid = false;	/* Force cache refresh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) static SENSOR_DEVICE_ATTR(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) 			  clear_caseopen, INTRUSION_ALARM_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) static SENSOR_DEVICE_ATTR(intrusion1_alarm, S_IWUSR | S_IRUGO, show_alarm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) 			  clear_caseopen, INTRUSION_ALARM_BASE + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) static SENSOR_DEVICE_ATTR(intrusion0_beep, S_IWUSR | S_IRUGO, show_beep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) 			  store_beep, INTRUSION_ALARM_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) static SENSOR_DEVICE_ATTR(intrusion1_beep, S_IWUSR | S_IRUGO, show_beep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) 			  store_beep, INTRUSION_ALARM_BASE + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) static SENSOR_DEVICE_ATTR(beep_enable, S_IWUSR | S_IRUGO, show_beep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) 			  store_beep, BEEP_ENABLE_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) static umode_t nct6775_other_is_visible(struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) 					struct attribute *attr, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) 	struct device *dev = kobj_to_dev(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) 	if (index == 0 && !data->have_vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) 	if (index == 1 || index == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) 		if (data->ALARM_BITS[INTRUSION_ALARM_BASE + index - 1] < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) 	if (index == 3 || index == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) 		if (data->BEEP_BITS[INTRUSION_ALARM_BASE + index - 3] < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) 	return attr->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482)  * nct6775_other_is_visible uses the index into the following array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483)  * to determine if attributes should be created or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484)  * Any change in order or content must be matched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) static struct attribute *nct6775_attributes_other[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) 	&dev_attr_cpu0_vid.attr,				/* 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) 	&sensor_dev_attr_intrusion0_alarm.dev_attr.attr,	/* 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) 	&sensor_dev_attr_intrusion1_alarm.dev_attr.attr,	/* 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) 	&sensor_dev_attr_intrusion0_beep.dev_attr.attr,		/* 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) 	&sensor_dev_attr_intrusion1_beep.dev_attr.attr,		/* 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) 	&sensor_dev_attr_beep_enable.dev_attr.attr,		/* 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) 	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) static const struct attribute_group nct6775_group_other = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) 	.attrs = nct6775_attributes_other,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) 	.is_visible = nct6775_other_is_visible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) static inline void nct6775_init_device(struct nct6775_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) 	u8 tmp, diode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) 	/* Start monitoring if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) 	if (data->REG_CONFIG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) 		tmp = nct6775_read_value(data, data->REG_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) 		if (!(tmp & 0x01))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) 			nct6775_write_value(data, data->REG_CONFIG, tmp | 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) 	/* Enable temperature sensors if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) 	for (i = 0; i < NUM_TEMP; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) 		if (!(data->have_temp & BIT(i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) 		if (!data->reg_temp_config[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) 		tmp = nct6775_read_value(data, data->reg_temp_config[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) 		if (tmp & 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) 			nct6775_write_value(data, data->reg_temp_config[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) 					    tmp & 0xfe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) 	/* Enable VBAT monitoring if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) 	tmp = nct6775_read_value(data, data->REG_VBAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) 	if (!(tmp & 0x01))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) 		nct6775_write_value(data, data->REG_VBAT, tmp | 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) 	diode = nct6775_read_value(data, data->REG_DIODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) 	for (i = 0; i < data->temp_fixed_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) 		if (!(data->have_temp_fixed & BIT(i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) 		if ((tmp & (data->DIODE_MASK << i)))	/* diode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) 			data->temp_type[i]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) 			  = 3 - ((diode >> i) & data->DIODE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) 		else				/* thermistor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) 			data->temp_type[i] = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) nct6775_check_fan_inputs(struct nct6775_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) 	bool fan3pin = false, fan4pin = false, fan4min = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) 	bool fan5pin = false, fan6pin = false, fan7pin = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) 	bool pwm3pin = false, pwm4pin = false, pwm5pin = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) 	bool pwm6pin = false, pwm7pin = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) 	int sioreg = data->sioreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) 	/* Store SIO_REG_ENABLE for use during resume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) 	superio_select(sioreg, NCT6775_LD_HWM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) 	data->sio_reg_enable = superio_inb(sioreg, SIO_REG_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) 	/* fan4 and fan5 share some pins with the GPIO and serial flash */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) 	if (data->kind == nct6775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) 		int cr2c = superio_inb(sioreg, 0x2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) 		fan3pin = cr2c & BIT(6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) 		pwm3pin = cr2c & BIT(7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) 		/* On NCT6775, fan4 shares pins with the fdc interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) 		fan4pin = !(superio_inb(sioreg, 0x2A) & 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) 	} else if (data->kind == nct6776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) 		bool gpok = superio_inb(sioreg, 0x27) & 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) 		const char *board_vendor, *board_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) 		board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) 		board_name = dmi_get_system_info(DMI_BOARD_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) 		if (board_name && board_vendor &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) 		    !strcmp(board_vendor, "ASRock")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) 			 * Auxiliary fan monitoring is not enabled on ASRock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) 			 * Z77 Pro4-M if booted in UEFI Ultra-FastBoot mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) 			 * Observed with BIOS version 2.00.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) 			if (!strcmp(board_name, "Z77 Pro4-M")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) 				if ((data->sio_reg_enable & 0xe0) != 0xe0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) 					data->sio_reg_enable |= 0xe0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) 					superio_outb(sioreg, SIO_REG_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) 						     data->sio_reg_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) 		if (data->sio_reg_enable & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) 			fan3pin = gpok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) 			fan3pin = !(superio_inb(sioreg, 0x24) & 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) 		if (data->sio_reg_enable & 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) 			fan4pin = gpok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) 			fan4pin = superio_inb(sioreg, 0x1C) & 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) 		if (data->sio_reg_enable & 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) 			fan5pin = gpok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) 			fan5pin = superio_inb(sioreg, 0x1C) & 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) 		fan4min = fan4pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) 		pwm3pin = fan3pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) 	} else if (data->kind == nct6106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) 		int cr24 = superio_inb(sioreg, 0x24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) 		fan3pin = !(cr24 & 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) 		pwm3pin = cr24 & 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) 	} else if (data->kind == nct6116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) 		int cr1a = superio_inb(sioreg, 0x1a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) 		int cr1b = superio_inb(sioreg, 0x1b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) 		int cr24 = superio_inb(sioreg, 0x24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) 		int cr2a = superio_inb(sioreg, 0x2a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) 		int cr2b = superio_inb(sioreg, 0x2b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) 		int cr2f = superio_inb(sioreg, 0x2f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) 		fan3pin = !(cr2b & 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) 		fan4pin = (cr2b & 0x80) ||			// pin 1(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) 			(!(cr2f & 0x10) && (cr1a & 0x04));	// pin 65(66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) 		fan5pin = (cr2b & 0x80) ||			// pin 126(127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) 			(!(cr1b & 0x03) && (cr2a & 0x02));	// pin 94(96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) 		pwm3pin = fan3pin && (cr24 & 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) 		pwm4pin = fan4pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) 		pwm5pin = fan5pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) 		 * NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D, NCT6796D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) 		 * NCT6797D, NCT6798D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) 		int cr1a = superio_inb(sioreg, 0x1a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) 		int cr1b = superio_inb(sioreg, 0x1b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) 		int cr1c = superio_inb(sioreg, 0x1c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) 		int cr1d = superio_inb(sioreg, 0x1d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) 		int cr2a = superio_inb(sioreg, 0x2a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) 		int cr2b = superio_inb(sioreg, 0x2b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) 		int cr2d = superio_inb(sioreg, 0x2d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) 		int cr2f = superio_inb(sioreg, 0x2f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) 		bool dsw_en = cr2f & BIT(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) 		bool ddr4_en = cr2f & BIT(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) 		int cre0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) 		int creb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) 		int cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) 		superio_select(sioreg, NCT6775_LD_12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) 		cre0 = superio_inb(sioreg, 0xe0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) 		creb = superio_inb(sioreg, 0xeb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) 		cred = superio_inb(sioreg, 0xed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) 		fan3pin = !(cr1c & BIT(5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) 		fan4pin = !(cr1c & BIT(6));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) 		fan5pin = !(cr1c & BIT(7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) 		pwm3pin = !(cr1c & BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) 		pwm4pin = !(cr1c & BIT(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) 		pwm5pin = !(cr1c & BIT(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) 		switch (data->kind) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) 		case nct6791:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) 			fan6pin = cr2d & BIT(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) 			pwm6pin = cr2d & BIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) 		case nct6792:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) 			fan6pin = !dsw_en && (cr2d & BIT(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) 			pwm6pin = !dsw_en && (cr2d & BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) 		case nct6793:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) 			fan5pin |= cr1b & BIT(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) 			fan5pin |= creb & BIT(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) 			fan6pin = !dsw_en && (cr2d & BIT(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) 			fan6pin |= creb & BIT(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) 			pwm5pin |= cr2d & BIT(7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) 			pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) 			pwm6pin = !dsw_en && (cr2d & BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) 			pwm6pin |= creb & BIT(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) 		case nct6795:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) 			fan5pin |= cr1b & BIT(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) 			fan5pin |= creb & BIT(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) 			fan6pin = (cr2a & BIT(4)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) 					(!dsw_en || (cred & BIT(4)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) 			fan6pin |= creb & BIT(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) 			pwm5pin |= cr2d & BIT(7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) 			pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) 			pwm6pin = (cr2a & BIT(3)) && (cred & BIT(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) 			pwm6pin |= creb & BIT(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) 		case nct6796:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) 			fan5pin |= cr1b & BIT(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) 			fan5pin |= (cre0 & BIT(3)) && !(cr1b & BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) 			fan5pin |= creb & BIT(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) 			fan6pin = (cr2a & BIT(4)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) 					(!dsw_en || (cred & BIT(4)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) 			fan6pin |= creb & BIT(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) 			fan7pin = !(cr2b & BIT(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) 			pwm5pin |= cr2d & BIT(7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) 			pwm5pin |= (cre0 & BIT(4)) && !(cr1b & BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) 			pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) 			pwm6pin = (cr2a & BIT(3)) && (cred & BIT(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) 			pwm6pin |= creb & BIT(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) 			pwm7pin = !(cr1d & (BIT(2) | BIT(3)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) 		case nct6797:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) 			fan5pin |= !ddr4_en && (cr1b & BIT(5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) 			fan5pin |= creb & BIT(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) 			fan6pin = cr2a & BIT(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) 			fan6pin |= creb & BIT(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) 			fan7pin = cr1a & BIT(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) 			pwm5pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) 			pwm5pin |= !ddr4_en && (cr2d & BIT(7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) 			pwm6pin = creb & BIT(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) 			pwm6pin |= cred & BIT(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) 			pwm7pin = cr1d & BIT(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) 		case nct6798:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) 			fan6pin = !(cr1b & BIT(0)) && (cre0 & BIT(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) 			fan6pin |= cr2a & BIT(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) 			fan6pin |= creb & BIT(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) 			fan7pin = cr1b & BIT(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) 			fan7pin |= !(cr2b & BIT(2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) 			fan7pin |= creb & BIT(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) 			pwm6pin = !(cr1b & BIT(0)) && (cre0 & BIT(4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) 			pwm6pin |= !(cred & BIT(2)) && (cr2a & BIT(3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) 			pwm6pin |= (creb & BIT(4)) && !(cr2a & BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) 			pwm7pin = !(cr1d & (BIT(2) | BIT(3)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) 			pwm7pin |= cr2d & BIT(7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) 			pwm7pin |= creb & BIT(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) 		default:	/* NCT6779D */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) 		fan4min = fan4pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) 	/* fan 1 and 2 (0x03) are always present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) 	data->has_fan = 0x03 | (fan3pin << 2) | (fan4pin << 3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) 		(fan5pin << 4) | (fan6pin << 5) | (fan7pin << 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) 	data->has_fan_min = 0x03 | (fan3pin << 2) | (fan4min << 3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) 		(fan5pin << 4) | (fan6pin << 5) | (fan7pin << 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) 	data->has_pwm = 0x03 | (pwm3pin << 2) | (pwm4pin << 3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) 		(pwm5pin << 4) | (pwm6pin << 5) | (pwm7pin << 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) static void add_temp_sensors(struct nct6775_data *data, const u16 *regp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) 			     int *available, int *mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) 	u8 src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) 	for (i = 0; i < data->pwm_num && *available; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) 		int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) 		if (!regp[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) 		src = nct6775_read_value(data, regp[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) 		src &= 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) 		if (!src || (*mask & BIT(src)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) 		if (!(data->temp_mask & BIT(src)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) 		index = __ffs(*available);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) 		nct6775_write_value(data, data->REG_TEMP_SOURCE[index], src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) 		*available &= ~BIT(index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) 		*mask |= BIT(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) static int nct6775_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) 	struct nct6775_sio_data *sio_data = dev_get_platdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) 	struct nct6775_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) 	struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) 	int i, s, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) 	int src, mask, available;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) 	const u16 *reg_temp, *reg_temp_over, *reg_temp_hyst, *reg_temp_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) 	const u16 *reg_temp_mon, *reg_temp_alternate, *reg_temp_crit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) 	const u16 *reg_temp_crit_l = NULL, *reg_temp_crit_h = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) 	int num_reg_temp, num_reg_temp_mon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) 	u8 cr2a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) 	struct attribute_group *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) 	struct device *hwmon_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) 	int num_attr_groups = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) 	if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) 				 DRVNAME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) 	data = devm_kzalloc(&pdev->dev, sizeof(struct nct6775_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) 			    GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) 	if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) 	data->kind = sio_data->kind;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) 	data->sioreg = sio_data->sioreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) 	data->addr = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) 	mutex_init(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) 	data->name = nct6775_device_names[data->kind];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) 	data->bank = 0xff;		/* Force initial bank selection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) 	platform_set_drvdata(pdev, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) 	switch (data->kind) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) 	case nct6106:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) 		data->in_num = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) 		data->pwm_num = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) 		data->auto_pwm_num = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) 		data->temp_fixed_num = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) 		data->num_temp_alarms = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) 		data->num_temp_beeps = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) 		data->fan_from_reg = fan_from_reg13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) 		data->fan_from_reg_min = fan_from_reg13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) 		data->temp_label = nct6776_temp_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) 		data->temp_mask = NCT6776_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) 		data->virt_temp_mask = NCT6776_VIRT_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) 		data->REG_VBAT = NCT6106_REG_VBAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) 		data->REG_DIODE = NCT6106_REG_DIODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) 		data->DIODE_MASK = NCT6106_DIODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) 		data->REG_VIN = NCT6106_REG_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) 		data->REG_IN_MINMAX[0] = NCT6106_REG_IN_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) 		data->REG_IN_MINMAX[1] = NCT6106_REG_IN_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) 		data->REG_TARGET = NCT6106_REG_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) 		data->REG_FAN = NCT6106_REG_FAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) 		data->REG_FAN_MODE = NCT6106_REG_FAN_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) 		data->REG_FAN_MIN = NCT6106_REG_FAN_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) 		data->REG_FAN_PULSES = NCT6106_REG_FAN_PULSES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) 		data->FAN_PULSE_SHIFT = NCT6106_FAN_PULSE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) 		data->REG_FAN_TIME[0] = NCT6106_REG_FAN_STOP_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) 		data->REG_FAN_TIME[1] = NCT6106_REG_FAN_STEP_UP_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) 		data->REG_FAN_TIME[2] = NCT6106_REG_FAN_STEP_DOWN_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) 		data->REG_TOLERANCE_H = NCT6106_REG_TOLERANCE_H;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) 		data->REG_PWM[0] = NCT6116_REG_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) 		data->REG_PWM[1] = NCT6106_REG_FAN_START_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) 		data->REG_PWM[2] = NCT6106_REG_FAN_STOP_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) 		data->REG_PWM[5] = NCT6106_REG_WEIGHT_DUTY_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) 		data->REG_PWM[6] = NCT6106_REG_WEIGHT_DUTY_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) 		data->REG_PWM_READ = NCT6106_REG_PWM_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) 		data->REG_PWM_MODE = NCT6106_REG_PWM_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) 		data->PWM_MODE_MASK = NCT6106_PWM_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) 		data->REG_AUTO_TEMP = NCT6106_REG_AUTO_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) 		data->REG_AUTO_PWM = NCT6106_REG_AUTO_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) 		data->REG_CRITICAL_TEMP = NCT6106_REG_CRITICAL_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) 		data->REG_CRITICAL_TEMP_TOLERANCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) 		  = NCT6106_REG_CRITICAL_TEMP_TOLERANCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) 		data->REG_CRITICAL_PWM_ENABLE = NCT6106_REG_CRITICAL_PWM_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) 		data->CRITICAL_PWM_ENABLE_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) 		  = NCT6106_CRITICAL_PWM_ENABLE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) 		data->REG_CRITICAL_PWM = NCT6106_REG_CRITICAL_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) 		data->REG_TEMP_OFFSET = NCT6106_REG_TEMP_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) 		data->REG_TEMP_SOURCE = NCT6106_REG_TEMP_SOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) 		data->REG_TEMP_SEL = NCT6116_REG_TEMP_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) 		data->REG_WEIGHT_TEMP_SEL = NCT6106_REG_WEIGHT_TEMP_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) 		data->REG_WEIGHT_TEMP[0] = NCT6106_REG_WEIGHT_TEMP_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) 		data->REG_WEIGHT_TEMP[1] = NCT6106_REG_WEIGHT_TEMP_STEP_TOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) 		data->REG_WEIGHT_TEMP[2] = NCT6106_REG_WEIGHT_TEMP_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) 		data->REG_ALARM = NCT6106_REG_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) 		data->ALARM_BITS = NCT6106_ALARM_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) 		data->REG_BEEP = NCT6106_REG_BEEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) 		data->BEEP_BITS = NCT6106_BEEP_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) 		reg_temp = NCT6106_REG_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) 		reg_temp_mon = NCT6106_REG_TEMP_MON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) 		num_reg_temp = ARRAY_SIZE(NCT6106_REG_TEMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) 		num_reg_temp_mon = ARRAY_SIZE(NCT6106_REG_TEMP_MON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) 		reg_temp_over = NCT6106_REG_TEMP_OVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) 		reg_temp_hyst = NCT6106_REG_TEMP_HYST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) 		reg_temp_config = NCT6106_REG_TEMP_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) 		reg_temp_alternate = NCT6106_REG_TEMP_ALTERNATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) 		reg_temp_crit = NCT6106_REG_TEMP_CRIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) 		reg_temp_crit_l = NCT6106_REG_TEMP_CRIT_L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) 		reg_temp_crit_h = NCT6106_REG_TEMP_CRIT_H;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) 	case nct6116:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) 		data->in_num = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) 		data->pwm_num = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) 		data->auto_pwm_num = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) 		data->temp_fixed_num = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) 		data->num_temp_alarms = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) 		data->num_temp_beeps = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) 		data->fan_from_reg = fan_from_reg13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) 		data->fan_from_reg_min = fan_from_reg13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) 		data->temp_label = nct6776_temp_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) 		data->temp_mask = NCT6776_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) 		data->virt_temp_mask = NCT6776_VIRT_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) 		data->REG_VBAT = NCT6106_REG_VBAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) 		data->REG_DIODE = NCT6106_REG_DIODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) 		data->DIODE_MASK = NCT6106_DIODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) 		data->REG_VIN = NCT6106_REG_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) 		data->REG_IN_MINMAX[0] = NCT6106_REG_IN_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) 		data->REG_IN_MINMAX[1] = NCT6106_REG_IN_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) 		data->REG_TARGET = NCT6116_REG_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) 		data->REG_FAN = NCT6116_REG_FAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) 		data->REG_FAN_MODE = NCT6116_REG_FAN_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) 		data->REG_FAN_MIN = NCT6116_REG_FAN_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) 		data->REG_FAN_PULSES = NCT6116_REG_FAN_PULSES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) 		data->FAN_PULSE_SHIFT = NCT6116_FAN_PULSE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) 		data->REG_FAN_TIME[0] = NCT6116_REG_FAN_STOP_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) 		data->REG_FAN_TIME[1] = NCT6116_REG_FAN_STEP_UP_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) 		data->REG_FAN_TIME[2] = NCT6116_REG_FAN_STEP_DOWN_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) 		data->REG_TOLERANCE_H = NCT6116_REG_TOLERANCE_H;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) 		data->REG_PWM[0] = NCT6116_REG_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) 		data->REG_PWM[1] = NCT6116_REG_FAN_START_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) 		data->REG_PWM[2] = NCT6116_REG_FAN_STOP_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) 		data->REG_PWM[5] = NCT6106_REG_WEIGHT_DUTY_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) 		data->REG_PWM[6] = NCT6106_REG_WEIGHT_DUTY_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) 		data->REG_PWM_READ = NCT6106_REG_PWM_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) 		data->REG_PWM_MODE = NCT6106_REG_PWM_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) 		data->PWM_MODE_MASK = NCT6106_PWM_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) 		data->REG_AUTO_TEMP = NCT6116_REG_AUTO_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) 		data->REG_AUTO_PWM = NCT6116_REG_AUTO_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) 		data->REG_CRITICAL_TEMP = NCT6116_REG_CRITICAL_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) 		data->REG_CRITICAL_TEMP_TOLERANCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) 		  = NCT6116_REG_CRITICAL_TEMP_TOLERANCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) 		data->REG_CRITICAL_PWM_ENABLE = NCT6116_REG_CRITICAL_PWM_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) 		data->CRITICAL_PWM_ENABLE_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) 		  = NCT6106_CRITICAL_PWM_ENABLE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) 		data->REG_CRITICAL_PWM = NCT6116_REG_CRITICAL_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) 		data->REG_TEMP_OFFSET = NCT6106_REG_TEMP_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) 		data->REG_TEMP_SOURCE = NCT6116_REG_TEMP_SOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) 		data->REG_TEMP_SEL = NCT6116_REG_TEMP_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) 		data->REG_WEIGHT_TEMP_SEL = NCT6106_REG_WEIGHT_TEMP_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) 		data->REG_WEIGHT_TEMP[0] = NCT6106_REG_WEIGHT_TEMP_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) 		data->REG_WEIGHT_TEMP[1] = NCT6106_REG_WEIGHT_TEMP_STEP_TOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) 		data->REG_WEIGHT_TEMP[2] = NCT6106_REG_WEIGHT_TEMP_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) 		data->REG_ALARM = NCT6106_REG_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) 		data->ALARM_BITS = NCT6116_ALARM_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) 		data->REG_BEEP = NCT6106_REG_BEEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) 		data->BEEP_BITS = NCT6116_BEEP_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) 		reg_temp = NCT6106_REG_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) 		reg_temp_mon = NCT6106_REG_TEMP_MON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) 		num_reg_temp = ARRAY_SIZE(NCT6106_REG_TEMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) 		num_reg_temp_mon = ARRAY_SIZE(NCT6106_REG_TEMP_MON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) 		reg_temp_over = NCT6106_REG_TEMP_OVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) 		reg_temp_hyst = NCT6106_REG_TEMP_HYST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) 		reg_temp_config = NCT6106_REG_TEMP_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) 		reg_temp_alternate = NCT6106_REG_TEMP_ALTERNATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) 		reg_temp_crit = NCT6106_REG_TEMP_CRIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) 		reg_temp_crit_l = NCT6106_REG_TEMP_CRIT_L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) 		reg_temp_crit_h = NCT6106_REG_TEMP_CRIT_H;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) 	case nct6775:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) 		data->in_num = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) 		data->pwm_num = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) 		data->auto_pwm_num = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) 		data->has_fan_div = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) 		data->temp_fixed_num = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) 		data->num_temp_alarms = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) 		data->num_temp_beeps = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) 		data->ALARM_BITS = NCT6775_ALARM_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) 		data->BEEP_BITS = NCT6775_BEEP_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) 		data->fan_from_reg = fan_from_reg16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) 		data->fan_from_reg_min = fan_from_reg8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) 		data->target_temp_mask = 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) 		data->tolerance_mask = 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) 		data->speed_tolerance_limit = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) 		data->temp_label = nct6775_temp_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) 		data->temp_mask = NCT6775_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) 		data->virt_temp_mask = NCT6775_VIRT_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) 		data->REG_CONFIG = NCT6775_REG_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) 		data->REG_VBAT = NCT6775_REG_VBAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) 		data->REG_DIODE = NCT6775_REG_DIODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) 		data->DIODE_MASK = NCT6775_DIODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) 		data->REG_VIN = NCT6775_REG_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) 		data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) 		data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) 		data->REG_TARGET = NCT6775_REG_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) 		data->REG_FAN = NCT6775_REG_FAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) 		data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) 		data->REG_FAN_MIN = NCT6775_REG_FAN_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) 		data->REG_FAN_PULSES = NCT6775_REG_FAN_PULSES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) 		data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) 		data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) 		data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) 		data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) 		data->REG_PWM[0] = NCT6775_REG_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) 		data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) 		data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) 		data->REG_PWM[3] = NCT6775_REG_FAN_MAX_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) 		data->REG_PWM[4] = NCT6775_REG_FAN_STEP_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) 		data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) 		data->REG_PWM_READ = NCT6775_REG_PWM_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) 		data->REG_PWM_MODE = NCT6775_REG_PWM_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) 		data->PWM_MODE_MASK = NCT6775_PWM_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) 		data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) 		data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) 		data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) 		data->REG_CRITICAL_TEMP_TOLERANCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) 		  = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) 		data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) 		data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) 		data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) 		data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) 		data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) 		data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) 		data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) 		data->REG_ALARM = NCT6775_REG_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) 		data->REG_BEEP = NCT6775_REG_BEEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) 		reg_temp = NCT6775_REG_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) 		reg_temp_mon = NCT6775_REG_TEMP_MON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) 		num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) 		num_reg_temp_mon = ARRAY_SIZE(NCT6775_REG_TEMP_MON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) 		reg_temp_over = NCT6775_REG_TEMP_OVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) 		reg_temp_hyst = NCT6775_REG_TEMP_HYST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) 		reg_temp_config = NCT6775_REG_TEMP_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) 		reg_temp_alternate = NCT6775_REG_TEMP_ALTERNATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) 		reg_temp_crit = NCT6775_REG_TEMP_CRIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) 	case nct6776:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) 		data->in_num = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) 		data->pwm_num = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) 		data->auto_pwm_num = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) 		data->has_fan_div = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) 		data->temp_fixed_num = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) 		data->num_temp_alarms = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) 		data->num_temp_beeps = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) 		data->ALARM_BITS = NCT6776_ALARM_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) 		data->BEEP_BITS = NCT6776_BEEP_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) 		data->fan_from_reg = fan_from_reg13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) 		data->fan_from_reg_min = fan_from_reg13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) 		data->target_temp_mask = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) 		data->tolerance_mask = 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) 		data->speed_tolerance_limit = 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) 		data->temp_label = nct6776_temp_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) 		data->temp_mask = NCT6776_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) 		data->virt_temp_mask = NCT6776_VIRT_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) 		data->REG_CONFIG = NCT6775_REG_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) 		data->REG_VBAT = NCT6775_REG_VBAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) 		data->REG_DIODE = NCT6775_REG_DIODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) 		data->DIODE_MASK = NCT6775_DIODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) 		data->REG_VIN = NCT6775_REG_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) 		data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) 		data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) 		data->REG_TARGET = NCT6775_REG_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) 		data->REG_FAN = NCT6775_REG_FAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) 		data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) 		data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) 		data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) 		data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) 		data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) 		data->REG_FAN_TIME[1] = NCT6776_REG_FAN_STEP_UP_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) 		data->REG_FAN_TIME[2] = NCT6776_REG_FAN_STEP_DOWN_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) 		data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) 		data->REG_PWM[0] = NCT6775_REG_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) 		data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) 		data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) 		data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) 		data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) 		data->REG_PWM_READ = NCT6775_REG_PWM_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) 		data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) 		data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) 		data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) 		data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) 		data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) 		data->REG_CRITICAL_TEMP_TOLERANCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) 		  = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) 		data->REG_TEMP_OFFSET = NCT6775_REG_TEMP_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) 		data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) 		data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) 		data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) 		data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) 		data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) 		data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) 		data->REG_ALARM = NCT6775_REG_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) 		data->REG_BEEP = NCT6776_REG_BEEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) 		reg_temp = NCT6775_REG_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) 		reg_temp_mon = NCT6775_REG_TEMP_MON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) 		num_reg_temp = ARRAY_SIZE(NCT6775_REG_TEMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) 		num_reg_temp_mon = ARRAY_SIZE(NCT6775_REG_TEMP_MON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) 		reg_temp_over = NCT6775_REG_TEMP_OVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) 		reg_temp_hyst = NCT6775_REG_TEMP_HYST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) 		reg_temp_config = NCT6776_REG_TEMP_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) 		reg_temp_alternate = NCT6776_REG_TEMP_ALTERNATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) 		reg_temp_crit = NCT6776_REG_TEMP_CRIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) 	case nct6779:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) 		data->in_num = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) 		data->pwm_num = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) 		data->auto_pwm_num = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) 		data->has_fan_div = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) 		data->temp_fixed_num = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) 		data->num_temp_alarms = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) 		data->num_temp_beeps = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) 		data->ALARM_BITS = NCT6779_ALARM_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) 		data->BEEP_BITS = NCT6779_BEEP_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) 		data->fan_from_reg = fan_from_reg_rpm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) 		data->fan_from_reg_min = fan_from_reg13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) 		data->target_temp_mask = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) 		data->tolerance_mask = 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) 		data->speed_tolerance_limit = 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) 		data->temp_label = nct6779_temp_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) 		data->temp_mask = NCT6779_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) 		data->virt_temp_mask = NCT6779_VIRT_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) 		data->REG_CONFIG = NCT6775_REG_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) 		data->REG_VBAT = NCT6775_REG_VBAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) 		data->REG_DIODE = NCT6775_REG_DIODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) 		data->DIODE_MASK = NCT6775_DIODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) 		data->REG_VIN = NCT6779_REG_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) 		data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) 		data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) 		data->REG_TARGET = NCT6775_REG_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) 		data->REG_FAN = NCT6779_REG_FAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) 		data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) 		data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) 		data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) 		data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) 		data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) 		data->REG_FAN_TIME[1] = NCT6776_REG_FAN_STEP_UP_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) 		data->REG_FAN_TIME[2] = NCT6776_REG_FAN_STEP_DOWN_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) 		data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) 		data->REG_PWM[0] = NCT6775_REG_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) 		data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) 		data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) 		data->REG_PWM[5] = NCT6775_REG_WEIGHT_DUTY_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) 		data->REG_PWM[6] = NCT6776_REG_WEIGHT_DUTY_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) 		data->REG_PWM_READ = NCT6775_REG_PWM_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) 		data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) 		data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) 		data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) 		data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) 		data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) 		data->REG_CRITICAL_TEMP_TOLERANCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) 		  = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) 		data->REG_CRITICAL_PWM_ENABLE = NCT6779_REG_CRITICAL_PWM_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) 		data->CRITICAL_PWM_ENABLE_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) 		  = NCT6779_CRITICAL_PWM_ENABLE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) 		data->REG_CRITICAL_PWM = NCT6779_REG_CRITICAL_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) 		data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) 		data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) 		data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) 		data->REG_WEIGHT_TEMP_SEL = NCT6775_REG_WEIGHT_TEMP_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) 		data->REG_WEIGHT_TEMP[0] = NCT6775_REG_WEIGHT_TEMP_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) 		data->REG_WEIGHT_TEMP[1] = NCT6775_REG_WEIGHT_TEMP_STEP_TOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) 		data->REG_WEIGHT_TEMP[2] = NCT6775_REG_WEIGHT_TEMP_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) 		data->REG_ALARM = NCT6779_REG_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) 		data->REG_BEEP = NCT6776_REG_BEEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) 		reg_temp = NCT6779_REG_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) 		reg_temp_mon = NCT6779_REG_TEMP_MON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) 		num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) 		num_reg_temp_mon = ARRAY_SIZE(NCT6779_REG_TEMP_MON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) 		reg_temp_over = NCT6779_REG_TEMP_OVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) 		reg_temp_hyst = NCT6779_REG_TEMP_HYST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) 		reg_temp_config = NCT6779_REG_TEMP_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) 		reg_temp_alternate = NCT6779_REG_TEMP_ALTERNATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) 		reg_temp_crit = NCT6779_REG_TEMP_CRIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) 	case nct6791:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) 	case nct6792:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) 	case nct6793:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) 	case nct6795:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) 	case nct6796:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) 	case nct6797:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) 	case nct6798:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) 		data->in_num = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) 		data->pwm_num = (data->kind == nct6796 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) 				 data->kind == nct6797 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) 				 data->kind == nct6798) ? 7 : 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) 		data->auto_pwm_num = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) 		data->has_fan_div = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) 		data->temp_fixed_num = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) 		data->num_temp_alarms = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) 		data->num_temp_beeps = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) 		data->ALARM_BITS = NCT6791_ALARM_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) 		data->BEEP_BITS = NCT6779_BEEP_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) 		data->fan_from_reg = fan_from_reg_rpm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) 		data->fan_from_reg_min = fan_from_reg13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) 		data->target_temp_mask = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) 		data->tolerance_mask = 0x07;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) 		data->speed_tolerance_limit = 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) 		switch (data->kind) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) 		case nct6791:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) 			data->temp_label = nct6779_temp_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) 			data->temp_mask = NCT6791_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) 			data->virt_temp_mask = NCT6791_VIRT_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) 		case nct6792:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) 			data->temp_label = nct6792_temp_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) 			data->temp_mask = NCT6792_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) 			data->virt_temp_mask = NCT6792_VIRT_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) 		case nct6793:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) 			data->temp_label = nct6793_temp_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) 			data->temp_mask = NCT6793_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) 			data->virt_temp_mask = NCT6793_VIRT_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) 		case nct6795:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) 		case nct6797:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) 			data->temp_label = nct6795_temp_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) 			data->temp_mask = NCT6795_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) 			data->virt_temp_mask = NCT6795_VIRT_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) 		case nct6796:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) 			data->temp_label = nct6796_temp_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) 			data->temp_mask = NCT6796_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) 			data->virt_temp_mask = NCT6796_VIRT_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) 		case nct6798:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) 			data->temp_label = nct6798_temp_label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) 			data->temp_mask = NCT6798_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) 			data->virt_temp_mask = NCT6798_VIRT_TEMP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) 		data->REG_CONFIG = NCT6775_REG_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) 		data->REG_VBAT = NCT6775_REG_VBAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) 		data->REG_DIODE = NCT6775_REG_DIODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) 		data->DIODE_MASK = NCT6775_DIODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) 		data->REG_VIN = NCT6779_REG_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) 		data->REG_IN_MINMAX[0] = NCT6775_REG_IN_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) 		data->REG_IN_MINMAX[1] = NCT6775_REG_IN_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) 		data->REG_TARGET = NCT6775_REG_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) 		data->REG_FAN = NCT6779_REG_FAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) 		data->REG_FAN_MODE = NCT6775_REG_FAN_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) 		data->REG_FAN_MIN = NCT6776_REG_FAN_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) 		data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) 		data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) 		data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) 		data->REG_FAN_TIME[1] = NCT6776_REG_FAN_STEP_UP_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) 		data->REG_FAN_TIME[2] = NCT6776_REG_FAN_STEP_DOWN_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) 		data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) 		data->REG_PWM[0] = NCT6775_REG_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) 		data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) 		data->REG_PWM[2] = NCT6775_REG_FAN_STOP_OUTPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) 		data->REG_PWM[5] = NCT6791_REG_WEIGHT_DUTY_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) 		data->REG_PWM[6] = NCT6791_REG_WEIGHT_DUTY_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) 		data->REG_PWM_READ = NCT6775_REG_PWM_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) 		data->REG_PWM_MODE = NCT6776_REG_PWM_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) 		data->PWM_MODE_MASK = NCT6776_PWM_MODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) 		data->REG_AUTO_TEMP = NCT6775_REG_AUTO_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) 		data->REG_AUTO_PWM = NCT6775_REG_AUTO_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) 		data->REG_CRITICAL_TEMP = NCT6775_REG_CRITICAL_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) 		data->REG_CRITICAL_TEMP_TOLERANCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) 		  = NCT6775_REG_CRITICAL_TEMP_TOLERANCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) 		data->REG_CRITICAL_PWM_ENABLE = NCT6779_REG_CRITICAL_PWM_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) 		data->CRITICAL_PWM_ENABLE_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) 		  = NCT6779_CRITICAL_PWM_ENABLE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) 		data->REG_CRITICAL_PWM = NCT6779_REG_CRITICAL_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) 		data->REG_TEMP_OFFSET = NCT6779_REG_TEMP_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) 		data->REG_TEMP_SOURCE = NCT6775_REG_TEMP_SOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) 		data->REG_TEMP_SEL = NCT6775_REG_TEMP_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) 		data->REG_WEIGHT_TEMP_SEL = NCT6791_REG_WEIGHT_TEMP_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) 		data->REG_WEIGHT_TEMP[0] = NCT6791_REG_WEIGHT_TEMP_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) 		data->REG_WEIGHT_TEMP[1] = NCT6791_REG_WEIGHT_TEMP_STEP_TOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) 		data->REG_WEIGHT_TEMP[2] = NCT6791_REG_WEIGHT_TEMP_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) 		data->REG_ALARM = NCT6791_REG_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) 		if (data->kind == nct6791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) 			data->REG_BEEP = NCT6776_REG_BEEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) 			data->REG_BEEP = NCT6792_REG_BEEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) 		reg_temp = NCT6779_REG_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) 		num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) 		if (data->kind == nct6791) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) 			reg_temp_mon = NCT6779_REG_TEMP_MON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) 			num_reg_temp_mon = ARRAY_SIZE(NCT6779_REG_TEMP_MON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) 			reg_temp_mon = NCT6792_REG_TEMP_MON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) 			num_reg_temp_mon = ARRAY_SIZE(NCT6792_REG_TEMP_MON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) 		reg_temp_over = NCT6779_REG_TEMP_OVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) 		reg_temp_hyst = NCT6779_REG_TEMP_HYST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) 		reg_temp_config = NCT6779_REG_TEMP_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) 		reg_temp_alternate = NCT6779_REG_TEMP_ALTERNATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) 		reg_temp_crit = NCT6779_REG_TEMP_CRIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) 	data->have_in = BIT(data->in_num) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) 	data->have_temp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) 	 * On some boards, not all available temperature sources are monitored,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) 	 * even though some of the monitoring registers are unused.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) 	 * Get list of unused monitoring registers, then detect if any fan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) 	 * controls are configured to use unmonitored temperature sources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) 	 * If so, assign the unmonitored temperature sources to available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) 	 * monitoring registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) 	mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) 	available = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) 	for (i = 0; i < num_reg_temp; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) 		if (reg_temp[i] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) 		src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) 		if (!src || (mask & BIT(src)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) 			available |= BIT(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) 		mask |= BIT(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) 	 * Now find unmonitored temperature registers and enable monitoring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) 	 * if additional monitoring registers are available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) 	add_temp_sensors(data, data->REG_TEMP_SEL, &available, &mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) 	add_temp_sensors(data, data->REG_WEIGHT_TEMP_SEL, &available, &mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) 	mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) 	s = NUM_TEMP_FIXED;	/* First dynamic temperature attribute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) 	for (i = 0; i < num_reg_temp; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) 		if (reg_temp[i] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) 		src = nct6775_read_value(data, data->REG_TEMP_SOURCE[i]) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) 		if (!src || (mask & BIT(src)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) 		if (!(data->temp_mask & BIT(src))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) 			dev_info(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) 				 "Invalid temperature source %d at index %d, source register 0x%x, temp register 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) 				 src, i, data->REG_TEMP_SOURCE[i], reg_temp[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) 		mask |= BIT(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) 		/* Use fixed index for SYSTIN(1), CPUTIN(2), AUXTIN(3) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) 		if (src <= data->temp_fixed_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) 			data->have_temp |= BIT(src - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) 			data->have_temp_fixed |= BIT(src - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) 			data->reg_temp[0][src - 1] = reg_temp[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) 			data->reg_temp[1][src - 1] = reg_temp_over[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) 			data->reg_temp[2][src - 1] = reg_temp_hyst[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) 			if (reg_temp_crit_h && reg_temp_crit_h[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) 				data->reg_temp[3][src - 1] = reg_temp_crit_h[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) 			else if (reg_temp_crit[src - 1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) 				data->reg_temp[3][src - 1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) 				  = reg_temp_crit[src - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) 			if (reg_temp_crit_l && reg_temp_crit_l[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) 				data->reg_temp[4][src - 1] = reg_temp_crit_l[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) 			data->reg_temp_config[src - 1] = reg_temp_config[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) 			data->temp_src[src - 1] = src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) 		if (s >= NUM_TEMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) 		/* Use dynamic index for other sources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) 		data->have_temp |= BIT(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) 		data->reg_temp[0][s] = reg_temp[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) 		data->reg_temp[1][s] = reg_temp_over[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) 		data->reg_temp[2][s] = reg_temp_hyst[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) 		data->reg_temp_config[s] = reg_temp_config[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) 		if (reg_temp_crit_h && reg_temp_crit_h[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) 			data->reg_temp[3][s] = reg_temp_crit_h[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) 		else if (reg_temp_crit[src - 1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) 			data->reg_temp[3][s] = reg_temp_crit[src - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) 		if (reg_temp_crit_l && reg_temp_crit_l[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) 			data->reg_temp[4][s] = reg_temp_crit_l[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) 		data->temp_src[s] = src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) 		s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) 	 * Repeat with temperatures used for fan control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) 	 * This set of registers does not support limits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) 	for (i = 0; i < num_reg_temp_mon; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) 		if (reg_temp_mon[i] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) 		src = nct6775_read_value(data, data->REG_TEMP_SEL[i]) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) 		if (!src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) 		if (!(data->temp_mask & BIT(src))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) 			dev_info(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) 				 "Invalid temperature source %d at index %d, source register 0x%x, temp register 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) 				 src, i, data->REG_TEMP_SEL[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) 				 reg_temp_mon[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) 		 * For virtual temperature sources, the 'virtual' temperature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) 		 * for each fan reflects a different temperature, and there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) 		 * are no duplicates.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) 		if (!(data->virt_temp_mask & BIT(src))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) 			if (mask & BIT(src))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) 			mask |= BIT(src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) 		/* Use fixed index for SYSTIN(1), CPUTIN(2), AUXTIN(3) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) 		if (src <= data->temp_fixed_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) 			if (data->have_temp & BIT(src - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) 			data->have_temp |= BIT(src - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) 			data->have_temp_fixed |= BIT(src - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) 			data->reg_temp[0][src - 1] = reg_temp_mon[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) 			data->temp_src[src - 1] = src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) 		if (s >= NUM_TEMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) 		/* Use dynamic index for other sources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) 		data->have_temp |= BIT(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) 		data->reg_temp[0][s] = reg_temp_mon[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) 		data->temp_src[s] = src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) 		s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) #ifdef USE_ALTERNATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) 	 * Go through the list of alternate temp registers and enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) 	 * if possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) 	 * The temperature is already monitored if the respective bit in <mask>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) 	 * is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) 	for (i = 0; i < 31; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) 		if (!(data->temp_mask & BIT(i + 1)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) 		if (!reg_temp_alternate[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) 		if (mask & BIT(i + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) 		if (i < data->temp_fixed_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) 			if (data->have_temp & BIT(i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) 			data->have_temp |= BIT(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) 			data->have_temp_fixed |= BIT(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) 			data->reg_temp[0][i] = reg_temp_alternate[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) 			if (i < num_reg_temp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) 				data->reg_temp[1][i] = reg_temp_over[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) 				data->reg_temp[2][i] = reg_temp_hyst[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) 			data->temp_src[i] = i + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) 		if (s >= NUM_TEMP)	/* Abort if no more space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) 		data->have_temp |= BIT(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) 		data->reg_temp[0][s] = reg_temp_alternate[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) 		data->temp_src[s] = i + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) 		s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) #endif /* USE_ALTERNATE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) 	/* Initialize the chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) 	nct6775_init_device(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) 	err = superio_enter(sio_data->sioreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) 	cr2a = superio_inb(sio_data->sioreg, 0x2a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) 	switch (data->kind) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) 	case nct6775:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) 		data->have_vid = (cr2a & 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) 	case nct6776:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) 		data->have_vid = (cr2a & 0x60) == 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) 	case nct6106:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) 	case nct6116:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) 	case nct6779:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) 	case nct6791:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) 	case nct6792:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) 	case nct6793:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) 	case nct6795:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) 	case nct6796:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) 	case nct6797:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) 	case nct6798:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) 	 * Read VID value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) 	 * We can get the VID input values directly at logical device D 0xe3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) 	if (data->have_vid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) 		superio_select(sio_data->sioreg, NCT6775_LD_VID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) 		data->vid = superio_inb(sio_data->sioreg, 0xe3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) 		data->vrm = vid_which_vrm();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) 	if (fan_debounce) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) 		u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) 		superio_select(sio_data->sioreg, NCT6775_LD_HWM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) 		tmp = superio_inb(sio_data->sioreg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) 				  NCT6775_REG_CR_FAN_DEBOUNCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) 		switch (data->kind) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) 		case nct6106:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) 		case nct6116:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) 			tmp |= 0xe0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) 		case nct6775:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) 			tmp |= 0x1e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) 		case nct6776:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) 		case nct6779:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) 			tmp |= 0x3e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) 		case nct6791:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) 		case nct6792:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) 		case nct6793:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) 		case nct6795:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) 		case nct6796:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) 		case nct6797:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) 		case nct6798:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) 			tmp |= 0x7e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) 		superio_outb(sio_data->sioreg, NCT6775_REG_CR_FAN_DEBOUNCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) 			     tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) 		dev_info(&pdev->dev, "Enabled fan debounce for chip %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) 			 data->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) 	nct6775_check_fan_inputs(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) 	superio_exit(sio_data->sioreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) 	/* Read fan clock dividers immediately */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) 	nct6775_init_fan_common(dev, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) 	/* Register sysfs hooks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) 	group = nct6775_create_attr_group(dev, &nct6775_pwm_template_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) 					  data->pwm_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) 	if (IS_ERR(group))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) 		return PTR_ERR(group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) 	data->groups[num_attr_groups++] = group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) 	group = nct6775_create_attr_group(dev, &nct6775_in_template_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) 					  fls(data->have_in));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) 	if (IS_ERR(group))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) 		return PTR_ERR(group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) 	data->groups[num_attr_groups++] = group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) 	group = nct6775_create_attr_group(dev, &nct6775_fan_template_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) 					  fls(data->has_fan));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) 	if (IS_ERR(group))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) 		return PTR_ERR(group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) 	data->groups[num_attr_groups++] = group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) 	group = nct6775_create_attr_group(dev, &nct6775_temp_template_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) 					  fls(data->have_temp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) 	if (IS_ERR(group))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) 		return PTR_ERR(group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) 	data->groups[num_attr_groups++] = group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) 	data->groups[num_attr_groups++] = &nct6775_group_other;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) 	hwmon_dev = devm_hwmon_device_register_with_groups(dev, data->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) 							   data, data->groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) 	return PTR_ERR_OR_ZERO(hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) static void nct6791_enable_io_mapping(int sioaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) 	int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) 	val = superio_inb(sioaddr, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) 	if (val & 0x10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) 		pr_info("Enabling hardware monitor logical device mappings.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) 		superio_outb(sioaddr, NCT6791_REG_HM_IO_SPACE_LOCK_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) 			     val & ~0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) static int __maybe_unused nct6775_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) 	struct nct6775_data *data = nct6775_update_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) 	data->vbat = nct6775_read_value(data, data->REG_VBAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) 	if (data->kind == nct6775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) 		data->fandiv1 = nct6775_read_value(data, NCT6775_REG_FANDIV1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) 		data->fandiv2 = nct6775_read_value(data, NCT6775_REG_FANDIV2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) static int __maybe_unused nct6775_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) 	struct nct6775_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) 	int sioreg = data->sioreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) 	int i, j, err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) 	mutex_lock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) 	data->bank = 0xff;		/* Force initial bank selection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) 	err = superio_enter(sioreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) 		goto abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) 	superio_select(sioreg, NCT6775_LD_HWM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) 	reg = superio_inb(sioreg, SIO_REG_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) 	if (reg != data->sio_reg_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) 		superio_outb(sioreg, SIO_REG_ENABLE, data->sio_reg_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) 	if (data->kind == nct6791 || data->kind == nct6792 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) 	    data->kind == nct6793 || data->kind == nct6795 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) 	    data->kind == nct6796 || data->kind == nct6797 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) 	    data->kind == nct6798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) 		nct6791_enable_io_mapping(sioreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) 	superio_exit(sioreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) 	/* Restore limits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) 	for (i = 0; i < data->in_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) 		if (!(data->have_in & BIT(i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) 		nct6775_write_value(data, data->REG_IN_MINMAX[0][i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676) 				    data->in[i][1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) 		nct6775_write_value(data, data->REG_IN_MINMAX[1][i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) 				    data->in[i][2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) 	for (i = 0; i < ARRAY_SIZE(data->fan_min); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) 		if (!(data->has_fan_min & BIT(i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) 		nct6775_write_value(data, data->REG_FAN_MIN[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) 				    data->fan_min[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) 	for (i = 0; i < NUM_TEMP; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) 		if (!(data->have_temp & BIT(i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) 		for (j = 1; j < ARRAY_SIZE(data->reg_temp); j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694) 			if (data->reg_temp[j][i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) 				nct6775_write_temp(data, data->reg_temp[j][i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) 						   data->temp[j][i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) 	/* Restore other settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) 	nct6775_write_value(data, data->REG_VBAT, data->vbat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701) 	if (data->kind == nct6775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) 		nct6775_write_value(data, NCT6775_REG_FANDIV1, data->fandiv1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) 		nct6775_write_value(data, NCT6775_REG_FANDIV2, data->fandiv2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) abort:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) 	/* Force re-reading all values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) 	data->valid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) 	mutex_unlock(&data->update_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) static SIMPLE_DEV_PM_OPS(nct6775_dev_pm_ops, nct6775_suspend, nct6775_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) static struct platform_driver nct6775_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) 		.name	= DRVNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) 		.pm	= &nct6775_dev_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) 	.probe		= nct6775_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) /* nct6775_find() looks for a '627 in the Super-I/O config space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) 	u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) 	int addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) 	err = superio_enter(sioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) 	val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) 		superio_inb(sioaddr, SIO_REG_DEVID + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) 	if (force_id && val != 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) 		val = force_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) 	switch (val & SIO_ID_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) 	case SIO_NCT6106_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) 		sio_data->kind = nct6106;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) 	case SIO_NCT6116_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) 		sio_data->kind = nct6116;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) 	case SIO_NCT6775_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) 		sio_data->kind = nct6775;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) 	case SIO_NCT6776_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) 		sio_data->kind = nct6776;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) 	case SIO_NCT6779_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) 		sio_data->kind = nct6779;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) 	case SIO_NCT6791_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) 		sio_data->kind = nct6791;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) 	case SIO_NCT6792_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) 		sio_data->kind = nct6792;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) 	case SIO_NCT6793_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) 		sio_data->kind = nct6793;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) 	case SIO_NCT6795_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) 		sio_data->kind = nct6795;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) 	case SIO_NCT6796_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) 		sio_data->kind = nct6796;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) 	case SIO_NCT6797_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) 		sio_data->kind = nct6797;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774) 	case SIO_NCT6798_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) 		sio_data->kind = nct6798;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) 		if (val != 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) 			pr_debug("unsupported chip ID: 0x%04x\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) 		superio_exit(sioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) 	/* We have a known chip, find the HWM I/O address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785) 	superio_select(sioaddr, NCT6775_LD_HWM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) 	val = (superio_inb(sioaddr, SIO_REG_ADDR) << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) 	    | superio_inb(sioaddr, SIO_REG_ADDR + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) 	addr = val & IOREGION_ALIGNMENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) 	if (addr == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) 		pr_err("Refusing to enable a Super-I/O device with a base I/O port 0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) 		superio_exit(sioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) 	/* Activate logical device if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) 	val = superio_inb(sioaddr, SIO_REG_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) 	if (!(val & 0x01)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) 		pr_warn("Forcibly enabling Super-I/O. Sensor is probably unusable.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) 		superio_outb(sioaddr, SIO_REG_ENABLE, val | 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) 	if (sio_data->kind == nct6791 || sio_data->kind == nct6792 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) 	    sio_data->kind == nct6793 || sio_data->kind == nct6795 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) 	    sio_data->kind == nct6796 || sio_data->kind == nct6797 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) 	    sio_data->kind == nct6798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) 		nct6791_enable_io_mapping(sioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) 	superio_exit(sioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) 	pr_info("Found %s or compatible chip at %#x:%#x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) 		nct6775_sio_names[sio_data->kind], sioaddr, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) 	sio_data->sioreg = sioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) 	return addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817)  * when Super-I/O functions move to a separate file, the Super-I/O
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818)  * bus will manage the lifetime of the device and this module will only keep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819)  * track of the nct6775 driver. But since we use platform_device_alloc(), we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820)  * must keep track of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) static struct platform_device *pdev[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) static int __init sensors_nct6775_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) 	int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) 	bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) 	int address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) 	struct resource res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) 	struct nct6775_sio_data sio_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) 	int sioaddr[2] = { 0x2e, 0x4e };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) 	err = platform_driver_register(&nct6775_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) 	 * initialize sio_data->kind and sio_data->sioreg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) 	 * when Super-I/O functions move to a separate file, the Super-I/O
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) 	 * driver will probe 0x2e and 0x4e and auto-detect the presence of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) 	 * nct6775 hardware monitor, and call probe()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) 	for (i = 0; i < ARRAY_SIZE(pdev); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) 		address = nct6775_find(sioaddr[i], &sio_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) 		if (address <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) 		found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) 		pdev[i] = platform_device_alloc(DRVNAME, address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) 		if (!pdev[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) 			err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854) 			goto exit_device_unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) 		err = platform_device_add_data(pdev[i], &sio_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) 					       sizeof(struct nct6775_sio_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) 			goto exit_device_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) 		memset(&res, 0, sizeof(res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) 		res.name = DRVNAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) 		res.start = address + IOREGION_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) 		res.end = address + IOREGION_OFFSET + IOREGION_LENGTH - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) 		res.flags = IORESOURCE_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) 		err = acpi_check_resource_conflict(&res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) 			platform_device_put(pdev[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) 			pdev[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) 		err = platform_device_add_resources(pdev[i], &res, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) 			goto exit_device_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) 		/* platform_device_add calls probe() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) 		err = platform_device_add(pdev[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) 			goto exit_device_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) 	if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) 		err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) 		goto exit_unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) exit_device_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) 	platform_device_put(pdev[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) exit_device_unregister:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) 	while (--i >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) 		if (pdev[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) 			platform_device_unregister(pdev[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) exit_unregister:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) 	platform_driver_unregister(&nct6775_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) static void __exit sensors_nct6775_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) 	for (i = 0; i < ARRAY_SIZE(pdev); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) 		if (pdev[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) 			platform_device_unregister(pdev[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) 	platform_driver_unregister(&nct6775_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) MODULE_DESCRIPTION("Driver for NCT6775F and compatible chips");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) module_init(sensors_nct6775_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) module_exit(sensors_nct6775_exit);