linux/drivers/hwmon/it87.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  it87.c - Part of lm_sensors, Linux kernel modules for hardware
 *           monitoring.
 *
 *  The IT8705F is an LPC-based Super I/O part that contains UARTs, a
 *  parallel port, an IR port, a MIDI port, a floppy controller, etc., in
 *  addition to an Environment Controller (Enhanced Hardware Monitor and
 *  Fan Controller)
 *
 *  This driver supports only the Environment Controller in the IT8705F and
 *  similar parts.  The other devices are supported by different drivers.
 *
 *  Supports: IT8603E  Super I/O chip w/LPC interface
 *            IT8620E  Super I/O chip w/LPC interface
 *            IT8622E  Super I/O chip w/LPC interface
 *            IT8623E  Super I/O chip w/LPC interface
 *            IT8628E  Super I/O chip w/LPC interface
 *            IT8705F  Super I/O chip w/LPC interface
 *            IT8712F  Super I/O chip w/LPC interface
 *            IT8716F  Super I/O chip w/LPC interface
 *            IT8718F  Super I/O chip w/LPC interface
 *            IT8720F  Super I/O chip w/LPC interface
 *            IT8721F  Super I/O chip w/LPC interface
 *            IT8726F  Super I/O chip w/LPC interface
 *            IT8728F  Super I/O chip w/LPC interface
 *            IT8732F  Super I/O chip w/LPC interface
 *            IT8758E  Super I/O chip w/LPC interface
 *            IT8771E  Super I/O chip w/LPC interface
 *            IT8772E  Super I/O chip w/LPC interface
 *            IT8781F  Super I/O chip w/LPC interface
 *            IT8782F  Super I/O chip w/LPC interface
 *            IT8783E/F Super I/O chip w/LPC interface
 *            IT8786E  Super I/O chip w/LPC interface
 *            IT8790E  Super I/O chip w/LPC interface
 *            IT8792E  Super I/O chip w/LPC interface
 *            IT87952E  Super I/O chip w/LPC interface
 *            Sis950   A clone of the IT8705F
 *
 *  Copyright (C) 2001 Chris Gauthron
 *  Copyright (C) 2005-2010 Jean Delvare <[email protected]>
 */

#define pr_fmt(fmt)

#include <linux/bitops.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/platform_device.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
#include <linux/string.h>
#include <linux/dmi.h>
#include <linux/acpi.h>
#include <linux/io.h>

#define DRVNAME

enum chips {};

static struct platform_device *it87_pdev[2];

#define REG_2E
#define REG_4E

#define DEV
#define PME

/* The device with the IT8718F/IT8720F VID value in it */
#define GPIO

#define DEVID
#define DEVREV

static inline void __superio_enter(int ioreg)
{}

static inline int superio_inb(int ioreg, int reg)
{}

static inline void superio_outb(int ioreg, int reg, int val)
{}

static int superio_inw(int ioreg, int reg)
{}

static inline void superio_select(int ioreg, int ldn)
{}

static inline int superio_enter(int ioreg, bool noentry)
{}

static inline void superio_exit(int ioreg, bool noexit)
{}

/* Logical device 4 registers */
#define IT8712F_DEVID
#define IT8705F_DEVID
#define IT8716F_DEVID
#define IT8718F_DEVID
#define IT8720F_DEVID
#define IT8721F_DEVID
#define IT8726F_DEVID
#define IT8728F_DEVID
#define IT8732F_DEVID
#define IT8792E_DEVID
#define IT8771E_DEVID
#define IT8772E_DEVID
#define IT8781F_DEVID
#define IT8782F_DEVID
#define IT8783E_DEVID
#define IT8786E_DEVID
#define IT8790E_DEVID
#define IT8603E_DEVID
#define IT8620E_DEVID
#define IT8622E_DEVID
#define IT8623E_DEVID
#define IT8628E_DEVID
#define IT87952E_DEVID

/* Logical device 4 (Environmental Monitor) registers */
#define IT87_ACT_REG
#define IT87_BASE_REG
#define IT87_SPECIAL_CFG_REG

/* Logical device 7 registers (IT8712F and later) */
#define IT87_SIO_GPIO1_REG
#define IT87_SIO_GPIO2_REG
#define IT87_SIO_GPIO3_REG
#define IT87_SIO_GPIO4_REG
#define IT87_SIO_GPIO5_REG
#define IT87_SIO_PINX1_REG
#define IT87_SIO_PINX2_REG
#define IT87_SIO_SPI_REG
#define IT87_SIO_VID_REG
#define IT87_SIO_BEEP_PIN_REG

/* Force chip IDs to specified values. Should only be used for testing */
static unsigned short force_id[2];
static unsigned int force_id_cnt;

/* ACPI resource conflicts are ignored if this parameter is set to 1 */
static bool ignore_resource_conflict;

/* Update battery voltage after every reading if true */
static bool update_vbat;

/* Not all BIOSes properly configure the PWM registers */
static bool fix_pwm_polarity;

/* Many IT87 constants specified below */

/* Length of ISA address segment */
#define IT87_EXTENT

/* Length of ISA address segment for Environmental Controller */
#define IT87_EC_EXTENT

/* Offset of EC registers from ISA base address */
#define IT87_EC_OFFSET

/* Where are the ISA address/data registers relative to the EC base address */
#define IT87_ADDR_REG_OFFSET
#define IT87_DATA_REG_OFFSET

/*----- The IT87 registers -----*/

#define IT87_REG_CONFIG

#define IT87_REG_ALARM1
#define IT87_REG_ALARM2
#define IT87_REG_ALARM3

/*
 * The IT8718F and IT8720F have the VID value in a different register, in
 * Super-I/O configuration space.
 */
#define IT87_REG_VID

/* Interface Selection register on other chips */
#define IT87_REG_IFSEL

/*
 * The IT8705F and IT8712F earlier than revision 0x08 use register 0x0b
 * for fan divisors. Later IT8712F revisions must use 16-bit tachometer
 * mode.
 */
#define IT87_REG_FAN_DIV
#define IT87_REG_FAN_16BIT

/*
 * Monitors:
 * - up to 13 voltage (0 to 7, battery, avcc, 10 to 12)
 * - up to 6 temp (1 to 6)
 * - up to 6 fan (1 to 6)
 */

static const u8 IT87_REG_FAN[]         =;
static const u8 IT87_REG_FAN_MIN[]     =;
static const u8 IT87_REG_FANX[]        =;
static const u8 IT87_REG_FANX_MIN[]    =;
static const u8 IT87_REG_TEMP_OFFSET[] =;

#define IT87_REG_FAN_MAIN_CTRL
#define IT87_REG_FAN_CTL
static const u8 IT87_REG_PWM[]         =;
static const u8 IT87_REG_PWM_DUTY[]    =;

static const u8 IT87_REG_VIN[]	=;

#define IT87_REG_TEMP(nr)

#define IT87_REG_VIN_MAX(nr)
#define IT87_REG_VIN_MIN(nr)
#define IT87_REG_TEMP_HIGH(nr)
#define IT87_REG_TEMP_LOW(nr)

#define IT87_REG_VIN_ENABLE
#define IT87_REG_TEMP_ENABLE
#define IT87_REG_TEMP_EXTRA
#define IT87_REG_BEEP_ENABLE

#define IT87_REG_CHIPID

static const u8 IT87_REG_AUTO_BASE[] =;

#define IT87_REG_AUTO_TEMP(nr, i)
#define IT87_REG_AUTO_PWM(nr, i)

#define IT87_REG_TEMP456_ENABLE

#define NUM_VIN
#define NUM_VIN_LIMIT
#define NUM_TEMP
#define NUM_TEMP_OFFSET
#define NUM_TEMP_LIMIT
#define NUM_FAN
#define NUM_FAN_DIV
#define NUM_PWM
#define NUM_AUTO_PWM

struct it87_devices {};

#define FEAT_12MV_ADC
#define FEAT_NEWER_AUTOPWM
#define FEAT_OLD_AUTOPWM
#define FEAT_16BIT_FANS
#define FEAT_TEMP_OFFSET
#define FEAT_TEMP_PECI
#define FEAT_TEMP_OLD_PECI
#define FEAT_FAN16_CONFIG
#define FEAT_FIVE_FANS
#define FEAT_VID
#define FEAT_IN7_INTERNAL
#define FEAT_SIX_FANS
#define FEAT_10_9MV_ADC
#define FEAT_AVCC3
#define FEAT_FIVE_PWM
#define FEAT_SIX_PWM
#define FEAT_PWM_FREQ2
#define FEAT_SIX_TEMP
#define FEAT_VIN3_5V
/*
 * Disabling configuration mode on some chips can result in system
 * hang-ups and access failures to the Super-IO chip at the
 * second SIO address. Never exit configuration mode on these
 * chips to avoid the problem.
 */
#define FEAT_NOCONF
#define FEAT_FOUR_FANS
#define FEAT_FOUR_PWM
#define FEAT_FOUR_TEMP
#define FEAT_FANCTL_ONOFF

static const struct it87_devices it87_devices[] =;

#define has_16bit_fans(data)
#define has_12mv_adc(data)
#define has_10_9mv_adc(data)
#define has_newer_autopwm(data)
#define has_old_autopwm(data)
#define has_temp_offset(data)
#define has_temp_peci(data, nr)
#define has_temp_old_peci(data, nr)
#define has_fan16_config(data)
#define has_four_fans(data)
#define has_five_fans(data)
#define has_six_fans(data)
#define has_vid(data)
#define has_in7_internal(data)
#define has_avcc3(data)
#define has_four_pwm(data)
#define has_five_pwm(data)
#define has_six_pwm(data)
#define has_pwm_freq2(data)
#define has_four_temp(data)
#define has_six_temp(data)
#define has_vin3_5v(data)
#define has_noconf(data)
#define has_scaling(data)
#define has_fanctl_onoff(data)

struct it87_sio_data {};

/*
 * For each registered chip, we need to keep some data in memory.
 * The structure is dynamically allocated.
 */
struct it87_data {};

/* Board specific settings from DMI matching */
struct it87_dmi_data {};

/* Global for results from DMI matching, if needed */
static struct it87_dmi_data *dmi_data;

static int adc_lsb(const struct it87_data *data, int nr)
{}

static u8 in_to_reg(const struct it87_data *data, int nr, long val)
{}

static int in_from_reg(const struct it87_data *data, int nr, int val)
{}

static inline u8 FAN_TO_REG(long rpm, int div)
{}

static inline u16 FAN16_TO_REG(long rpm)
{}

#define FAN_FROM_REG(val, div)
/* The divider is fixed to 2 in 16-bit mode */
#define FAN16_FROM_REG(val)

#define TEMP_TO_REG(val)
#define TEMP_FROM_REG(val)

static u8 pwm_to_reg(const struct it87_data *data, long val)
{}

static int pwm_from_reg(const struct it87_data *data, u8 reg)
{}

static int DIV_TO_REG(int val)
{}

#define DIV_FROM_REG(val)

/*
 * PWM base frequencies. The frequency has to be divided by either 128 or 256,
 * depending on the chip type, to calculate the actual PWM frequency.
 *
 * Some of the chip datasheets suggest a base frequency of 51 kHz instead
 * of 750 kHz for the slowest base frequency, resulting in a PWM frequency
 * of 200 Hz. Sometimes both PWM frequency select registers are affected,
 * sometimes just one. It is unknown if this is a datasheet error or real,
 * so this is ignored for now.
 */
static const unsigned int pwm_freq[8] =;

static int smbus_disable(struct it87_data *data)
{}

static int smbus_enable(struct it87_data *data)
{}

/*
 * Must be called with data->update_lock held, except during initialization.
 * Must be called with SMBus accesses disabled.
 * We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
 * would slow down the IT87 access and should not be necessary.
 */
static int it87_read_value(struct it87_data *data, u8 reg)
{}

/*
 * Must be called with data->update_lock held, except during initialization.
 * Must be called with SMBus accesses disabled.
 * We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks,
 * would slow down the IT87 access and should not be necessary.
 */
static void it87_write_value(struct it87_data *data, u8 reg, u8 value)
{}

static void it87_update_pwm_ctrl(struct it87_data *data, int nr)
{}

static int it87_lock(struct it87_data *data)
{}

static void it87_unlock(struct it87_data *data)
{}

static struct it87_data *it87_update_device(struct device *dev)
{}

static ssize_t show_in(struct device *dev, struct device_attribute *attr,
		       char *buf)
{}

static ssize_t set_in(struct device *dev, struct device_attribute *attr,
		      const char *buf, size_t count)
{}

static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0);
static SENSOR_DEVICE_ATTR_2(in0_min, S_IRUGO | S_IWUSR, show_in, set_in,
			    0, 1);
static SENSOR_DEVICE_ATTR_2(in0_max, S_IRUGO | S_IWUSR, show_in, set_in,
			    0, 2);

static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 1, 0);
static SENSOR_DEVICE_ATTR_2(in1_min, S_IRUGO | S_IWUSR, show_in, set_in,
			    1, 1);
static SENSOR_DEVICE_ATTR_2(in1_max, S_IRUGO | S_IWUSR, show_in, set_in,
			    1, 2);

static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 2, 0);
static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_in, set_in,
			    2, 1);
static SENSOR_DEVICE_ATTR_2(in2_max, S_IRUGO | S_IWUSR, show_in, set_in,
			    2, 2);

static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 3, 0);
static SENSOR_DEVICE_ATTR_2(in3_min, S_IRUGO | S_IWUSR, show_in, set_in,
			    3, 1);
static SENSOR_DEVICE_ATTR_2(in3_max, S_IRUGO | S_IWUSR, show_in, set_in,
			    3, 2);

static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 4, 0);
static SENSOR_DEVICE_ATTR_2(in4_min, S_IRUGO | S_IWUSR, show_in, set_in,
			    4, 1);
static SENSOR_DEVICE_ATTR_2(in4_max, S_IRUGO | S_IWUSR, show_in, set_in,
			    4, 2);

static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 5, 0);
static SENSOR_DEVICE_ATTR_2(in5_min, S_IRUGO | S_IWUSR, show_in, set_in,
			    5, 1);
static SENSOR_DEVICE_ATTR_2(in5_max, S_IRUGO | S_IWUSR, show_in, set_in,
			    5, 2);

static SENSOR_DEVICE_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 6, 0);
static SENSOR_DEVICE_ATTR_2(in6_min, S_IRUGO | S_IWUSR, show_in, set_in,
			    6, 1);
static SENSOR_DEVICE_ATTR_2(in6_max, S_IRUGO | S_IWUSR, show_in, set_in,
			    6, 2);

static SENSOR_DEVICE_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 7, 0);
static SENSOR_DEVICE_ATTR_2(in7_min, S_IRUGO | S_IWUSR, show_in, set_in,
			    7, 1);
static SENSOR_DEVICE_ATTR_2(in7_max, S_IRUGO | S_IWUSR, show_in, set_in,
			    7, 2);

static SENSOR_DEVICE_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 8, 0);
static SENSOR_DEVICE_ATTR_2(in9_input, S_IRUGO, show_in, NULL, 9, 0);
static SENSOR_DEVICE_ATTR_2(in10_input, S_IRUGO, show_in, NULL, 10, 0);
static SENSOR_DEVICE_ATTR_2(in11_input, S_IRUGO, show_in, NULL, 11, 0);
static SENSOR_DEVICE_ATTR_2(in12_input, S_IRUGO, show_in, NULL, 12, 0);

/* Up to 6 temperatures */
static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
			 char *buf)
{}

static ssize_t set_temp(struct device *dev, struct device_attribute *attr,
			const char *buf, size_t count)
{}

static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0);
static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
			    0, 1);
static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
			    0, 2);
static SENSOR_DEVICE_ATTR_2(temp1_offset, S_IRUGO | S_IWUSR, show_temp,
			    set_temp, 0, 3);
static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, 0);
static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
			    1, 1);
static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
			    1, 2);
static SENSOR_DEVICE_ATTR_2(temp2_offset, S_IRUGO | S_IWUSR, show_temp,
			    set_temp, 1, 3);
static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 2, 0);
static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
			    2, 1);
static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
			    2, 2);
static SENSOR_DEVICE_ATTR_2(temp3_offset, S_IRUGO | S_IWUSR, show_temp,
			    set_temp, 2, 3);
static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 3, 0);
static SENSOR_DEVICE_ATTR_2(temp5_input, S_IRUGO, show_temp, NULL, 4, 0);
static SENSOR_DEVICE_ATTR_2(temp6_input, S_IRUGO, show_temp, NULL, 5, 0);

static int get_temp_type(struct it87_data *data, int index)
{}

static ssize_t show_temp_type(struct device *dev, struct device_attribute *attr,
			      char *buf)
{}

static ssize_t set_temp_type(struct device *dev, struct device_attribute *attr,
			     const char *buf, size_t count)
{}

static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO | S_IWUSR, show_temp_type,
			  set_temp_type, 0);
static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR, show_temp_type,
			  set_temp_type, 1);
static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, show_temp_type,
			  set_temp_type, 2);

/* 6 Fans */

static int pwm_mode(const struct it87_data *data, int nr)
{}

static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
			char *buf)
{}

static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,
			    char *buf)
{}

static ssize_t show_pwm_enable(struct device *dev,
			       struct device_attribute *attr, char *buf)
{}

static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
			char *buf)
{}

static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr,
			     char *buf)
{}

static ssize_t set_fan(struct device *dev, struct device_attribute *attr,
		       const char *buf, size_t count)
{}

static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
			   const char *buf, size_t count)
{}

/* Returns 0 if OK, -EINVAL otherwise */
static int check_trip_points(struct device *dev, int nr)
{}

static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
			      const char *buf, size_t count)
{}

static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
		       const char *buf, size_t count)
{}

static ssize_t set_pwm_freq(struct device *dev, struct device_attribute *attr,
			    const char *buf, size_t count)
{}

static ssize_t show_pwm_temp_map(struct device *dev,
				 struct device_attribute *attr, char *buf)
{}

static ssize_t set_pwm_temp_map(struct device *dev,
				struct device_attribute *attr, const char *buf,
				size_t count)
{}

static ssize_t show_auto_pwm(struct device *dev, struct device_attribute *attr,
			     char *buf)
{}

static ssize_t set_auto_pwm(struct device *dev, struct device_attribute *attr,
			    const char *buf, size_t count)
{}

static ssize_t show_auto_pwm_slope(struct device *dev,
				   struct device_attribute *attr, char *buf)
{}

static ssize_t set_auto_pwm_slope(struct device *dev,
				  struct device_attribute *attr,
				  const char *buf, size_t count)
{}

static ssize_t show_auto_temp(struct device *dev, struct device_attribute *attr,
			      char *buf)
{}

static ssize_t set_auto_temp(struct device *dev, struct device_attribute *attr,
			     const char *buf, size_t count)
{}

static SENSOR_DEVICE_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, 0);
static SENSOR_DEVICE_ATTR_2(fan1_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
			    0, 1);
static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR, show_fan_div,
			  set_fan_div, 0);

static SENSOR_DEVICE_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 1, 0);
static SENSOR_DEVICE_ATTR_2(fan2_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
			    1, 1);
static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR, show_fan_div,
			  set_fan_div, 1);

static SENSOR_DEVICE_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 2, 0);
static SENSOR_DEVICE_ATTR_2(fan3_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
			    2, 1);
static SENSOR_DEVICE_ATTR(fan3_div, S_IRUGO | S_IWUSR, show_fan_div,
			  set_fan_div, 2);

static SENSOR_DEVICE_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 3, 0);
static SENSOR_DEVICE_ATTR_2(fan4_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
			    3, 1);

static SENSOR_DEVICE_ATTR_2(fan5_input, S_IRUGO, show_fan, NULL, 4, 0);
static SENSOR_DEVICE_ATTR_2(fan5_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
			    4, 1);

static SENSOR_DEVICE_ATTR_2(fan6_input, S_IRUGO, show_fan, NULL, 5, 0);
static SENSOR_DEVICE_ATTR_2(fan6_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
			    5, 1);

static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
			  show_pwm_enable, set_pwm_enable, 0);
static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 0);
static SENSOR_DEVICE_ATTR(pwm1_freq, S_IRUGO | S_IWUSR, show_pwm_freq,
			  set_pwm_freq, 0);
static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IRUGO,
			  show_pwm_temp_map, set_pwm_temp_map, 0);
static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR,
			    show_auto_pwm, set_auto_pwm, 0, 0);
static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_pwm, S_IRUGO | S_IWUSR,
			    show_auto_pwm, set_auto_pwm, 0, 1);
static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_pwm, S_IRUGO | S_IWUSR,
			    show_auto_pwm, set_auto_pwm, 0, 2);
static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_pwm, S_IRUGO,
			    show_auto_pwm, NULL, 0, 3);
static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 0, 1);
static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 0, 0);
static SENSOR_DEVICE_ATTR_2(pwm1_auto_point2_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 0, 2);
static SENSOR_DEVICE_ATTR_2(pwm1_auto_point3_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 0, 3);
static SENSOR_DEVICE_ATTR_2(pwm1_auto_point4_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 0, 4);
static SENSOR_DEVICE_ATTR_2(pwm1_auto_start, S_IRUGO | S_IWUSR,
			    show_auto_pwm, set_auto_pwm, 0, 0);
static SENSOR_DEVICE_ATTR(pwm1_auto_slope, S_IRUGO | S_IWUSR,
			  show_auto_pwm_slope, set_auto_pwm_slope, 0);

static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR,
			  show_pwm_enable, set_pwm_enable, 1);
static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 1);
static SENSOR_DEVICE_ATTR(pwm2_freq, S_IRUGO, show_pwm_freq, set_pwm_freq, 1);
static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IRUGO,
			  show_pwm_temp_map, set_pwm_temp_map, 1);
static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO | S_IWUSR,
			    show_auto_pwm, set_auto_pwm, 1, 0);
static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_pwm, S_IRUGO | S_IWUSR,
			    show_auto_pwm, set_auto_pwm, 1, 1);
static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_pwm, S_IRUGO | S_IWUSR,
			    show_auto_pwm, set_auto_pwm, 1, 2);
static SENSOR_DEVICE_ATTR_2(pwm2_auto_point4_pwm, S_IRUGO,
			    show_auto_pwm, NULL, 1, 3);
static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 1, 1);
static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 1, 0);
static SENSOR_DEVICE_ATTR_2(pwm2_auto_point2_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 1, 2);
static SENSOR_DEVICE_ATTR_2(pwm2_auto_point3_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 1, 3);
static SENSOR_DEVICE_ATTR_2(pwm2_auto_point4_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 1, 4);
static SENSOR_DEVICE_ATTR_2(pwm2_auto_start, S_IRUGO | S_IWUSR,
			    show_auto_pwm, set_auto_pwm, 1, 0);
static SENSOR_DEVICE_ATTR(pwm2_auto_slope, S_IRUGO | S_IWUSR,
			  show_auto_pwm_slope, set_auto_pwm_slope, 1);

static SENSOR_DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR,
			  show_pwm_enable, set_pwm_enable, 2);
static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 2);
static SENSOR_DEVICE_ATTR(pwm3_freq, S_IRUGO, show_pwm_freq, NULL, 2);
static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IRUGO,
			  show_pwm_temp_map, set_pwm_temp_map, 2);
static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO | S_IWUSR,
			    show_auto_pwm, set_auto_pwm, 2, 0);
static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_pwm, S_IRUGO | S_IWUSR,
			    show_auto_pwm, set_auto_pwm, 2, 1);
static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_pwm, S_IRUGO | S_IWUSR,
			    show_auto_pwm, set_auto_pwm, 2, 2);
static SENSOR_DEVICE_ATTR_2(pwm3_auto_point4_pwm, S_IRUGO,
			    show_auto_pwm, NULL, 2, 3);
static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 2, 1);
static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 2, 0);
static SENSOR_DEVICE_ATTR_2(pwm3_auto_point2_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 2, 2);
static SENSOR_DEVICE_ATTR_2(pwm3_auto_point3_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 2, 3);
static SENSOR_DEVICE_ATTR_2(pwm3_auto_point4_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 2, 4);
static SENSOR_DEVICE_ATTR_2(pwm3_auto_start, S_IRUGO | S_IWUSR,
			    show_auto_pwm, set_auto_pwm, 2, 0);
static SENSOR_DEVICE_ATTR(pwm3_auto_slope, S_IRUGO | S_IWUSR,
			  show_auto_pwm_slope, set_auto_pwm_slope, 2);

static SENSOR_DEVICE_ATTR(pwm4_enable, S_IRUGO | S_IWUSR,
			  show_pwm_enable, set_pwm_enable, 3);
static SENSOR_DEVICE_ATTR(pwm4, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 3);
static SENSOR_DEVICE_ATTR(pwm4_freq, S_IRUGO, show_pwm_freq, NULL, 3);
static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IRUGO,
			  show_pwm_temp_map, set_pwm_temp_map, 3);
static SENSOR_DEVICE_ATTR_2(pwm4_auto_point1_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 2, 1);
static SENSOR_DEVICE_ATTR_2(pwm4_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 2, 0);
static SENSOR_DEVICE_ATTR_2(pwm4_auto_point2_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 2, 2);
static SENSOR_DEVICE_ATTR_2(pwm4_auto_point3_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 2, 3);
static SENSOR_DEVICE_ATTR_2(pwm4_auto_start, S_IRUGO | S_IWUSR,
			    show_auto_pwm, set_auto_pwm, 3, 0);
static SENSOR_DEVICE_ATTR(pwm4_auto_slope, S_IRUGO | S_IWUSR,
			  show_auto_pwm_slope, set_auto_pwm_slope, 3);

static SENSOR_DEVICE_ATTR(pwm5_enable, S_IRUGO | S_IWUSR,
			  show_pwm_enable, set_pwm_enable, 4);
static SENSOR_DEVICE_ATTR(pwm5, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 4);
static SENSOR_DEVICE_ATTR(pwm5_freq, S_IRUGO, show_pwm_freq, NULL, 4);
static SENSOR_DEVICE_ATTR(pwm5_auto_channels_temp, S_IRUGO,
			  show_pwm_temp_map, set_pwm_temp_map, 4);
static SENSOR_DEVICE_ATTR_2(pwm5_auto_point1_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 2, 1);
static SENSOR_DEVICE_ATTR_2(pwm5_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 2, 0);
static SENSOR_DEVICE_ATTR_2(pwm5_auto_point2_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 2, 2);
static SENSOR_DEVICE_ATTR_2(pwm5_auto_point3_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 2, 3);
static SENSOR_DEVICE_ATTR_2(pwm5_auto_start, S_IRUGO | S_IWUSR,
			    show_auto_pwm, set_auto_pwm, 4, 0);
static SENSOR_DEVICE_ATTR(pwm5_auto_slope, S_IRUGO | S_IWUSR,
			  show_auto_pwm_slope, set_auto_pwm_slope, 4);

static SENSOR_DEVICE_ATTR(pwm6_enable, S_IRUGO | S_IWUSR,
			  show_pwm_enable, set_pwm_enable, 5);
static SENSOR_DEVICE_ATTR(pwm6, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 5);
static SENSOR_DEVICE_ATTR(pwm6_freq, S_IRUGO, show_pwm_freq, NULL, 5);
static SENSOR_DEVICE_ATTR(pwm6_auto_channels_temp, S_IRUGO,
			  show_pwm_temp_map, set_pwm_temp_map, 5);
static SENSOR_DEVICE_ATTR_2(pwm6_auto_point1_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 2, 1);
static SENSOR_DEVICE_ATTR_2(pwm6_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 2, 0);
static SENSOR_DEVICE_ATTR_2(pwm6_auto_point2_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 2, 2);
static SENSOR_DEVICE_ATTR_2(pwm6_auto_point3_temp, S_IRUGO | S_IWUSR,
			    show_auto_temp, set_auto_temp, 2, 3);
static SENSOR_DEVICE_ATTR_2(pwm6_auto_start, S_IRUGO | S_IWUSR,
			    show_auto_pwm, set_auto_pwm, 5, 0);
static SENSOR_DEVICE_ATTR(pwm6_auto_slope, S_IRUGO | S_IWUSR,
			  show_auto_pwm_slope, set_auto_pwm_slope, 5);

/* Alarms */
static ssize_t alarms_show(struct device *dev, struct device_attribute *attr,
			   char *buf)
{}
static DEVICE_ATTR_RO(alarms);

static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
			  char *buf)
{}

static ssize_t clear_intrusion(struct device *dev,
			       struct device_attribute *attr, const char *buf,
			       size_t count)
{}

static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 8);
static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 9);
static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 10);
static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 11);
static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 12);
static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 13);
static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 14);
static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 15);
static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 0);
static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 1);
static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 2);
static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 3);
static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 6);
static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_alarm, NULL, 7);
static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 16);
static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 17);
static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 18);
static SENSOR_DEVICE_ATTR(intrusion0_alarm, S_IRUGO | S_IWUSR,
			  show_alarm, clear_intrusion, 4);

static ssize_t show_beep(struct device *dev, struct device_attribute *attr,
			 char *buf)
{}

static ssize_t set_beep(struct device *dev, struct device_attribute *attr,
			const char *buf, size_t count)
{}

static SENSOR_DEVICE_ATTR(in0_beep, S_IRUGO | S_IWUSR,
			  show_beep, set_beep, 1);
static SENSOR_DEVICE_ATTR(in1_beep, S_IRUGO, show_beep, NULL, 1);
static SENSOR_DEVICE_ATTR(in2_beep, S_IRUGO, show_beep, NULL, 1);
static SENSOR_DEVICE_ATTR(in3_beep, S_IRUGO, show_beep, NULL, 1);
static SENSOR_DEVICE_ATTR(in4_beep, S_IRUGO, show_beep, NULL, 1);
static SENSOR_DEVICE_ATTR(in5_beep, S_IRUGO, show_beep, NULL, 1);
static SENSOR_DEVICE_ATTR(in6_beep, S_IRUGO, show_beep, NULL, 1);
static SENSOR_DEVICE_ATTR(in7_beep, S_IRUGO, show_beep, NULL, 1);
/* fanX_beep writability is set later */
static SENSOR_DEVICE_ATTR(fan1_beep, S_IRUGO, show_beep, set_beep, 0);
static SENSOR_DEVICE_ATTR(fan2_beep, S_IRUGO, show_beep, set_beep, 0);
static SENSOR_DEVICE_ATTR(fan3_beep, S_IRUGO, show_beep, set_beep, 0);
static SENSOR_DEVICE_ATTR(fan4_beep, S_IRUGO, show_beep, set_beep, 0);
static SENSOR_DEVICE_ATTR(fan5_beep, S_IRUGO, show_beep, set_beep, 0);
static SENSOR_DEVICE_ATTR(fan6_beep, S_IRUGO, show_beep, set_beep, 0);
static SENSOR_DEVICE_ATTR(temp1_beep, S_IRUGO | S_IWUSR,
			  show_beep, set_beep, 2);
static SENSOR_DEVICE_ATTR(temp2_beep, S_IRUGO, show_beep, NULL, 2);
static SENSOR_DEVICE_ATTR(temp3_beep, S_IRUGO, show_beep, NULL, 2);

static ssize_t vrm_show(struct device *dev, struct device_attribute *attr,
			char *buf)
{}

static ssize_t vrm_store(struct device *dev, struct device_attribute *attr,
			 const char *buf, size_t count)
{}
static DEVICE_ATTR_RW(vrm);

static ssize_t cpu0_vid_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
{}
static DEVICE_ATTR_RO(cpu0_vid);

static ssize_t show_label(struct device *dev, struct device_attribute *attr,
			  char *buf)
{}
static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0);
static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1);
static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_label, NULL, 2);
/* AVCC3 */
static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_label, NULL, 3);

static umode_t it87_in_is_visible(struct kobject *kobj,
				  struct attribute *attr, int index)
{}

static struct attribute *it87_attributes_in[] =;

static const struct attribute_group it87_group_in =;

static umode_t it87_temp_is_visible(struct kobject *kobj,
				    struct attribute *attr, int index)
{}

static struct attribute *it87_attributes_temp[] =;

static const struct attribute_group it87_group_temp =;

static umode_t it87_is_visible(struct kobject *kobj,
			       struct attribute *attr, int index)
{}

static struct attribute *it87_attributes[] =;

static const struct attribute_group it87_group =;

static umode_t it87_fan_is_visible(struct kobject *kobj,
				   struct attribute *attr, int index)
{}

static struct attribute *it87_attributes_fan[] =;

static const struct attribute_group it87_group_fan =;

static umode_t it87_pwm_is_visible(struct kobject *kobj,
				   struct attribute *attr, int index)
{}

static struct attribute *it87_attributes_pwm[] =;

static const struct attribute_group it87_group_pwm =;

static umode_t it87_auto_pwm_is_visible(struct kobject *kobj,
					struct attribute *attr, int index)
{}

static struct attribute *it87_attributes_auto_pwm[] =;

static const struct attribute_group it87_group_auto_pwm =;

/*
 * Original explanation:
 * On various Gigabyte AM4 boards (AB350, AX370), the second Super-IO chip
 * (IT8792E) needs to be in configuration mode before accessing the first
 * due to a bug in IT8792E which otherwise results in LPC bus access errors.
 * This needs to be done before accessing the first Super-IO chip since
 * the second chip may have been accessed prior to loading this driver.
 *
 * The problem is also reported to affect IT8795E, which is used on X299 boards
 * and has the same chip ID as IT8792E (0x8733). It also appears to affect
 * systems with IT8790E, which is used on some Z97X-Gaming boards as well as
 * Z87X-OC.
 *
 * From other information supplied:
 * ChipIDs 0x8733, 0x8695 (early ID for IT87952E) and 0x8790 are initialized
 * and left in configuration mode, and entering and/or exiting configuration
 * mode is what causes the crash.
 *
 * The recommendation is to look up the chipID before doing any mode swap
 * and then act accordingly.
 */
/* SuperIO detection - will change isa_address if a chip is found */
static int __init it87_find(int sioaddr, unsigned short *address,
			    struct it87_sio_data *sio_data, int chip_cnt)
{}

/*
 * Some chips seem to have default value 0xff for all limit
 * registers. For low voltage limits it makes no sense and triggers
 * alarms, so change to 0 instead. For high temperature limits, it
 * means -1 degree C, which surprisingly doesn't trigger an alarm,
 * but is still confusing, so change to 127 degrees C.
 */
static void it87_check_limit_regs(struct it87_data *data)
{}

/* Check if voltage monitors are reset manually or by some reason */
static void it87_check_voltage_monitors_reset(struct it87_data *data)
{}

/* Check if tachometers are reset manually or by some reason */
static void it87_check_tachometers_reset(struct platform_device *pdev)
{}

/* Set tachometers to 16-bit mode if needed */
static void it87_check_tachometers_16bit_mode(struct platform_device *pdev)
{}

static void it87_start_monitoring(struct it87_data *data)
{}

/* Called when we have found a new IT87. */
static void it87_init_device(struct platform_device *pdev)
{}

/* Return 1 if and only if the PWM interface is safe to use */
static int it87_check_pwm(struct device *dev)
{}

static int it87_probe(struct platform_device *pdev)
{}

static void it87_resume_sio(struct platform_device *pdev)
{}

static int it87_resume(struct device *dev)
{}

static DEFINE_SIMPLE_DEV_PM_OPS(it87_dev_pm_ops, NULL, it87_resume);

static struct platform_driver it87_driver =;

static int __init it87_device_add(int index, unsigned short address,
				  const struct it87_sio_data *sio_data)
{}

/* callback function for DMI */
static int it87_dmi_cb(const struct dmi_system_id *dmi_entry)
{}

/*
 * On the Shuttle SN68PT, FAN_CTL2 is apparently not
 * connected to a fan, but to something else. One user
 * has reported instant system power-off when changing
 * the PWM2 duty cycle, so we disable it.
 * I use the board name string as the trigger in case
 * the same board is ever used in other systems.
 */
static struct it87_dmi_data nvidia_fn68pt =;

#define IT87_DMI_MATCH_VND(vendor, name, cb, data)

static const struct dmi_system_id it87_dmi_table[] __initconst =;
MODULE_DEVICE_TABLE(dmi, it87_dmi_table);

static int __init sm_it87_init(void)
{}

static void __exit sm_it87_exit(void)
{}

MODULE_AUTHOR();
MODULE_DESCRIPTION();

module_param_array();
MODULE_PARM_DESC();

module_param(ignore_resource_conflict, bool, 0);
MODULE_PARM_DESC();

module_param(update_vbat, bool, 0);
MODULE_PARM_DESC();

module_param(fix_pwm_polarity, bool, 0);
MODULE_PARM_DESC();

MODULE_LICENSE();

module_init();
module_exit(sm_it87_exit);