linux/drivers/hwmon/nct6775-core.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * nct6775 - Driver for the hardware monitoring functionality of
 *	       Nuvoton NCT677x Super-I/O chips
 *
 * Copyright (C) 2012  Guenter Roeck <[email protected]>
 *
 * Derived from w83627ehf driver
 * Copyright (C) 2005-2012  Jean Delvare <[email protected]>
 * Copyright (C) 2006  Yuan Mu (Winbond),
 *		       Rudolf Marek <[email protected]>
 *		       David Hubbard <[email protected]>
 *		       Daniel J Blueman <[email protected]>
 * Copyright (C) 2010  Sheng-Yuan Huang (Nuvoton) (PS00)
 *
 * Shamelessly ripped from the w83627hf driver
 * Copyright (C) 2003  Mark Studebaker
 *
 * Supports the following chips:
 *
 * Chip        #vin    #fan    #pwm    #temp  chip IDs       man ID
 * nct6106d     9      3       3       6+3    0xc450 0xc1    0x5ca3
 * nct6116d     9      5       5       3+3    0xd280 0xc1    0x5ca3
 * nct6775f     9      4       3       6+3    0xb470 0xc1    0x5ca3
 * nct6776f     9      5       3       6+3    0xc330 0xc1    0x5ca3
 * nct6779d    15      5       5       2+6    0xc560 0xc1    0x5ca3
 * nct6791d    15      6       6       2+6    0xc800 0xc1    0x5ca3
 * nct6792d    15      6       6       2+6    0xc910 0xc1    0x5ca3
 * nct6793d    15      6       6       2+6    0xd120 0xc1    0x5ca3
 * nct6795d    14      6       6       2+6    0xd350 0xc1    0x5ca3
 * nct6796d    14      7       7       2+6    0xd420 0xc1    0x5ca3
 * nct6797d    14      7       7       2+6    0xd450 0xc1    0x5ca3
 *                                           (0xd451)
 * nct6798d    14      7       7       2+6    0xd428 0xc1    0x5ca3
 *                                           (0xd429)
 * nct6796d-s  18      7       7       6+2    0xd801 0xc1    0x5ca3
 * nct6799d-r  18      7       7       6+2    0xd802 0xc1    0x5ca3
 *
 * #temp lists the number of monitored temperature sources (first value) plus
 * the number of directly connectable temperature sensors (second value).
 */

#define pr_fmt(fmt)

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/bitops.h>
#include <linux/nospec.h>
#include <linux/regmap.h>
#include "lm75.h"
#include "nct6775.h"

#undef DEFAULT_SYMBOL_NAMESPACE
#define DEFAULT_SYMBOL_NAMESPACE

#define USE_ALTERNATE

/* used to set data->name = nct6775_device_names[data->sio_kind] */
static const char * const nct6775_device_names[] =;

/* Common and NCT6775 specific data */

/*
 * Voltage min/max registers for nr=7..14 are in bank 5
 * min/max: 15-17 for NCT6799 only
 */

static const u16 NCT6775_REG_IN_MAX[] =;
static const u16 NCT6775_REG_IN_MIN[] =;
static const u16 NCT6775_REG_IN[] =;

#define NCT6775_REG_VBAT
#define NCT6775_REG_DIODE
#define NCT6775_DIODE_MASK

static const u16 NCT6775_REG_ALARM[NUM_REG_ALARM] =;

static const s8 NCT6775_ALARM_BITS[NUM_ALARM_BITS] =;

static const u16 NCT6775_REG_BEEP[NUM_REG_BEEP] =;

static const s8 NCT6775_BEEP_BITS[NUM_BEEP_BITS] =;

/* DC or PWM output fan configuration */
static const u8 NCT6775_REG_PWM_MODE[] =;
static const u8 NCT6775_PWM_MODE_MASK[] =;

/* Advanced Fan control, some values are common for all fans */

static const u16 NCT6775_REG_TARGET[] =;
static const u16 NCT6775_REG_FAN_MODE[] =;
static const u16 NCT6775_REG_FAN_STEP_DOWN_TIME[] =;
static const u16 NCT6775_REG_FAN_STEP_UP_TIME[] =;
static const u16 NCT6775_REG_FAN_STOP_OUTPUT[] =;
static const u16 NCT6775_REG_FAN_START_OUTPUT[] =;
static const u16 NCT6775_REG_FAN_MAX_OUTPUT[] =;
static const u16 NCT6775_REG_FAN_STEP_OUTPUT[] =;

static const u16 NCT6775_REG_FAN_STOP_TIME[] =;
static const u16 NCT6775_REG_PWM[] =;
static const u16 NCT6775_REG_PWM_READ[] =;

static const u16 NCT6775_REG_FAN[] =;
static const u16 NCT6775_REG_FAN_MIN[] =;
static const u16 NCT6775_REG_FAN_PULSES[NUM_FAN] =;
static const u16 NCT6775_FAN_PULSE_SHIFT[NUM_FAN] =;

static const u16 NCT6775_REG_TEMP[] =;

static const u16 NCT6775_REG_TEMP_MON[] =;

static const u16 NCT6775_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] =;
static const u16 NCT6775_REG_TEMP_HYST[ARRAY_SIZE(NCT6775_REG_TEMP)] =;
static const u16 NCT6775_REG_TEMP_OVER[ARRAY_SIZE(NCT6775_REG_TEMP)] =;

static const u16 NCT6775_REG_TEMP_SOURCE[ARRAY_SIZE(NCT6775_REG_TEMP)] =;

static const u16 NCT6775_REG_TEMP_SEL[] =;

static const u16 NCT6775_REG_WEIGHT_TEMP_SEL[] =;
static const u16 NCT6775_REG_WEIGHT_TEMP_STEP[] =;
static const u16 NCT6775_REG_WEIGHT_TEMP_STEP_TOL[] =;
static const u16 NCT6775_REG_WEIGHT_DUTY_STEP[] =;
static const u16 NCT6775_REG_WEIGHT_TEMP_BASE[] =;

static const u16 NCT6775_REG_TEMP_OFFSET[] =;

static const u16 NCT6775_REG_AUTO_TEMP[] =;
static const u16 NCT6775_REG_AUTO_PWM[] =;

#define NCT6775_AUTO_TEMP(data, nr, p)
#define NCT6775_AUTO_PWM(data, nr, p)

static const u16 NCT6775_REG_CRITICAL_ENAB[] =;

static const u16 NCT6775_REG_CRITICAL_TEMP[] =;
static const u16 NCT6775_REG_CRITICAL_TEMP_TOLERANCE[] =;

static const char *const nct6775_temp_label[] =;

#define NCT6775_TEMP_MASK
#define NCT6775_VIRT_TEMP_MASK

static const u16 NCT6775_REG_TEMP_ALTERNATE[32] =;

static const u16 NCT6775_REG_TEMP_CRIT[32] =;

static const u16 NCT6775_REG_TSI_TEMP[] =;

/* NCT6776 specific data */

/* STEP_UP_TIME and STEP_DOWN_TIME regs are swapped for all chips but NCT6775 */
#define NCT6776_REG_FAN_STEP_UP_TIME
#define NCT6776_REG_FAN_STEP_DOWN_TIME

static const s8 NCT6776_ALARM_BITS[NUM_ALARM_BITS] =;

/* 0xbf: nct6799 only */
static const u16 NCT6776_REG_BEEP[NUM_REG_BEEP] =;

static const s8 NCT6776_BEEP_BITS[NUM_BEEP_BITS] =;

static const u16 NCT6776_REG_TOLERANCE_H[] =;

static const u8 NCT6776_REG_PWM_MODE[] =;
static const u8 NCT6776_PWM_MODE_MASK[] =;

static const u16 NCT6776_REG_FAN_MIN[] =;
static const u16 NCT6776_REG_FAN_PULSES[NUM_FAN] =;

static const u16 NCT6776_REG_WEIGHT_DUTY_BASE[] =;

static const u16 NCT6776_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6775_REG_TEMP)] =;

static const char *const nct6776_temp_label[] =;

#define NCT6776_TEMP_MASK
#define NCT6776_VIRT_TEMP_MASK

static const u16 NCT6776_REG_TEMP_ALTERNATE[32] =;

static const u16 NCT6776_REG_TEMP_CRIT[32] =;

static const u16 NCT6776_REG_TSI_TEMP[] =;

/* NCT6779 specific data */

/*
 * 15-17 for NCT6799 only, register labels are:
 *      CPUVC,  VIN1,  AVSB,  3VCC,  VIN0,  VIN8,  VIN4, 3VSB
 *       VBAT,   VTT,  VIN5,  VIN6,  VIN2,  VIN3,  VIN7, VIN9
 *       VHIF, VIN10
 */
static const u16 NCT6779_REG_IN[] =;

static const u16 NCT6779_REG_ALARM[NUM_REG_ALARM] =;

static const s8 NCT6779_ALARM_BITS[NUM_ALARM_BITS] =;

static const s8 NCT6779_BEEP_BITS[NUM_BEEP_BITS] =;

static const u16 NCT6779_REG_FAN[] =;
static const u16 NCT6779_REG_FAN_PULSES[NUM_FAN] =;

static const u16 NCT6779_REG_CRITICAL_PWM_ENABLE[] =;
#define NCT6779_CRITICAL_PWM_ENABLE_MASK
static const u16 NCT6779_REG_CRITICAL_PWM[] =;

static const u16 NCT6779_REG_TEMP[] =;
static const u16 NCT6779_REG_TEMP_MON[] =;
static const u16 NCT6779_REG_TEMP_CONFIG[ARRAY_SIZE(NCT6779_REG_TEMP)] =;
static const u16 NCT6779_REG_TEMP_HYST[ARRAY_SIZE(NCT6779_REG_TEMP)] =;
static const u16 NCT6779_REG_TEMP_OVER[ARRAY_SIZE(NCT6779_REG_TEMP)] =;

static const u16 NCT6779_REG_TEMP_OFFSET[] =;

static const char *const nct6779_temp_label[] =;

#define NCT6779_TEMP_MASK
#define NCT6779_VIRT_TEMP_MASK
#define NCT6791_TEMP_MASK
#define NCT6791_VIRT_TEMP_MASK

static const u16 NCT6779_REG_TEMP_ALTERNATE[32]
	=;

static const u16 NCT6779_REG_TEMP_CRIT[32] =;

/* NCT6791 specific data */

static const u16 NCT6791_REG_WEIGHT_TEMP_SEL[NUM_FAN] =;
static const u16 NCT6791_REG_WEIGHT_TEMP_STEP[NUM_FAN] =;
static const u16 NCT6791_REG_WEIGHT_TEMP_STEP_TOL[NUM_FAN] =;
static const u16 NCT6791_REG_WEIGHT_DUTY_STEP[NUM_FAN] =;
static const u16 NCT6791_REG_WEIGHT_TEMP_BASE[NUM_FAN] =;
static const u16 NCT6791_REG_WEIGHT_DUTY_BASE[NUM_FAN] =;

static const u16 NCT6791_REG_ALARM[NUM_REG_ALARM] =;

static const s8 NCT6791_ALARM_BITS[NUM_ALARM_BITS] =;

/* NCT6792/NCT6793 specific data */

static const u16 NCT6792_REG_TEMP_MON[] =;
static const u16 NCT6792_REG_BEEP[NUM_REG_BEEP] =;

static const char *const nct6792_temp_label[] =;

#define NCT6792_TEMP_MASK
#define NCT6792_VIRT_TEMP_MASK

static const char *const nct6793_temp_label[] =;

#define NCT6793_TEMP_MASK
#define NCT6793_VIRT_TEMP_MASK

static const char *const nct6795_temp_label[] =;

#define NCT6795_TEMP_MASK
#define NCT6795_VIRT_TEMP_MASK

static const char *const nct6796_temp_label[] =;

#define NCT6796_TEMP_MASK
#define NCT6796_VIRT_TEMP_MASK

static const u16 NCT6796_REG_TSI_TEMP[] =;

static const u16 NCT6798_REG_TEMP[] =;

static const u16 NCT6798_REG_TEMP_SOURCE[] =;

static const u16 NCT6798_REG_TEMP_MON[] =;
static const u16 NCT6798_REG_TEMP_OVER[] =;
static const u16 NCT6798_REG_TEMP_HYST[] =;

static const u16 NCT6798_REG_TEMP_CRIT[32] =;

static const u16 NCT6798_REG_TEMP_ALTERNATE[32] =;

static const char *const nct6798_temp_label[] =;

#define NCT6798_TEMP_MASK
#define NCT6798_VIRT_TEMP_MASK

static const u16 NCT6799_REG_ALARM[NUM_REG_ALARM] =;

static const s8 NCT6799_ALARM_BITS[NUM_ALARM_BITS] =;

static const s8 NCT6799_BEEP_BITS[NUM_BEEP_BITS] =;

/* PECI Calibration only for NCT6799D, not NCT6796D-S */
static const char *const nct6799_temp_label[] =;

#define NCT6799_TEMP_MASK
#define NCT6799_VIRT_TEMP_MASK

/* NCT6102D/NCT6106D specific data */

#define NCT6106_REG_VBAT
#define NCT6106_REG_DIODE
#define NCT6106_DIODE_MASK

static const u16 NCT6106_REG_IN_MAX[] =;
static const u16 NCT6106_REG_IN_MIN[] =;
static const u16 NCT6106_REG_IN[] =;

static const u16 NCT6106_REG_TEMP[] =;
static const u16 NCT6106_REG_TEMP_MON[] =;
static const u16 NCT6106_REG_TEMP_HYST[] =;
static const u16 NCT6106_REG_TEMP_OVER[] =;
static const u16 NCT6106_REG_TEMP_CRIT_L[] =;
static const u16 NCT6106_REG_TEMP_CRIT_H[] =;
static const u16 NCT6106_REG_TEMP_OFFSET[] =;
static const u16 NCT6106_REG_TEMP_CONFIG[] =;

static const u16 NCT6106_REG_FAN[] =;
static const u16 NCT6106_REG_FAN_MIN[] =;
static const u16 NCT6106_REG_FAN_PULSES[] =;
static const u16 NCT6106_FAN_PULSE_SHIFT[] =;

static const u8 NCT6106_REG_PWM_MODE[] =;
static const u8 NCT6106_PWM_MODE_MASK[] =;
static const u16 NCT6106_REG_PWM_READ[] =;
static const u16 NCT6106_REG_FAN_MODE[] =;
static const u16 NCT6106_REG_TEMP_SOURCE[] =;

static const u16 NCT6106_REG_CRITICAL_TEMP[] =;
static const u16 NCT6106_REG_CRITICAL_TEMP_TOLERANCE[] =;

static const u16 NCT6106_REG_CRITICAL_PWM_ENABLE[] =;
#define NCT6106_CRITICAL_PWM_ENABLE_MASK
static const u16 NCT6106_REG_CRITICAL_PWM[] =;

static const u16 NCT6106_REG_FAN_STEP_UP_TIME[] =;
static const u16 NCT6106_REG_FAN_STEP_DOWN_TIME[] =;
static const u16 NCT6106_REG_FAN_STOP_OUTPUT[] =;
static const u16 NCT6106_REG_FAN_START_OUTPUT[] =;
static const u16 NCT6106_REG_FAN_STOP_TIME[] =;
static const u16 NCT6106_REG_TOLERANCE_H[] =;

static const u16 NCT6106_REG_TARGET[] =;

static const u16 NCT6106_REG_WEIGHT_TEMP_SEL[] =;
static const u16 NCT6106_REG_WEIGHT_TEMP_STEP[] =;
static const u16 NCT6106_REG_WEIGHT_TEMP_STEP_TOL[] =;
static const u16 NCT6106_REG_WEIGHT_DUTY_STEP[] =;
static const u16 NCT6106_REG_WEIGHT_TEMP_BASE[] =;
static const u16 NCT6106_REG_WEIGHT_DUTY_BASE[] =;

static const u16 NCT6106_REG_AUTO_TEMP[] =;
static const u16 NCT6106_REG_AUTO_PWM[] =;

static const u16 NCT6106_REG_ALARM[NUM_REG_ALARM] =;

static const s8 NCT6106_ALARM_BITS[NUM_ALARM_BITS] =;

static const u16 NCT6106_REG_BEEP[NUM_REG_BEEP] =;

static const s8 NCT6106_BEEP_BITS[NUM_BEEP_BITS] =;

static const u16 NCT6106_REG_TEMP_ALTERNATE[32] =;

static const u16 NCT6106_REG_TEMP_CRIT[32] =;

static const u16 NCT6106_REG_TSI_TEMP[] =;

/* NCT6112D/NCT6114D/NCT6116D specific data */

static const u16 NCT6116_REG_FAN[] =;
static const u16 NCT6116_REG_FAN_MIN[] =;
static const u16 NCT6116_REG_FAN_PULSES[] =;
static const u16 NCT6116_FAN_PULSE_SHIFT[] =;

static const u16 NCT6116_REG_PWM[] =;
static const u16 NCT6116_REG_FAN_MODE[] =;
static const u16 NCT6116_REG_TEMP_SEL[] =;
static const u16 NCT6116_REG_TEMP_SOURCE[] =;

static const u16 NCT6116_REG_CRITICAL_TEMP[] =;
static const u16 NCT6116_REG_CRITICAL_TEMP_TOLERANCE[] =;

static const u16 NCT6116_REG_CRITICAL_PWM_ENABLE[] =;
static const u16 NCT6116_REG_CRITICAL_PWM[] =;

static const u16 NCT6116_REG_FAN_STEP_UP_TIME[] =;
static const u16 NCT6116_REG_FAN_STEP_DOWN_TIME[] =;
static const u16 NCT6116_REG_FAN_STOP_OUTPUT[] =;
static const u16 NCT6116_REG_FAN_START_OUTPUT[] =;
static const u16 NCT6116_REG_FAN_STOP_TIME[] =;
static const u16 NCT6116_REG_TOLERANCE_H[] =;

static const u16 NCT6116_REG_TARGET[] =;

static const u16 NCT6116_REG_AUTO_TEMP[] =;
static const u16 NCT6116_REG_AUTO_PWM[] =;

static const s8 NCT6116_ALARM_BITS[NUM_ALARM_BITS] =;

static const s8 NCT6116_BEEP_BITS[NUM_BEEP_BITS] =;

static const u16 NCT6116_REG_TSI_TEMP[] =;

static enum pwm_enable reg_to_pwm_enable(int pwm, int mode)
{}

static int pwm_enable_to_reg(enum pwm_enable mode)
{}

/*
 * Conversions
 */

/* 1 is DC mode, output in ms */
static unsigned int step_time_from_reg(u8 reg, u8 mode)
{}

static u8 step_time_to_reg(unsigned int msec, u8 mode)
{}

static unsigned int fan_from_reg8(u16 reg, unsigned int divreg)
{}

static unsigned int fan_from_reg13(u16 reg, unsigned int divreg)
{}

static unsigned int fan_from_reg16(u16 reg, unsigned int divreg)
{}

static unsigned int fan_from_reg_rpm(u16 reg, unsigned int divreg)
{}

static u16 fan_to_reg(u32 fan, unsigned int divreg)
{}

static inline unsigned int
div_from_reg(u8 reg)
{}

/*
 * Some of the voltage inputs have internal scaling, the tables below
 * contain 8 (the ADC LSB in mV) * scaling factor * 100
 */
static const u16 scale_in[15] =;

/*
 * NCT6798 scaling:
 *    CPUVC, IN1, AVSB, 3VCC, IN0, IN8, IN4, 3VSB, VBAT,  VTT,  IN5,  IN6, IN2,
 *      IN3, IN7,  IN9, VHIF, IN10
 * 15-17 for NCT6799 only
 */
static const u16 scale_in_6798[NUM_IN] =;

static inline long in_from_reg(u8 reg, u8 nr, const u16 *scales)
{}

static inline u8 in_to_reg(u32 val, u8 nr, const u16 *scales)
{}

/* TSI temperatures are in 8.3 format */
static inline unsigned int tsi_temp_from_reg(unsigned int reg)
{}

/*
 * Data structures and manipulation thereof
 */

struct sensor_device_template {};

struct sensor_device_attr_u {};

#define __TEMPLATE_ATTR(_template, _mode, _show, _store)

#define SENSOR_DEVICE_TEMPLATE(_template, _mode, _show, _store, _index)

#define SENSOR_DEVICE_TEMPLATE_2(_template, _mode, _show, _store,	\
				 _nr, _index)

#define SENSOR_TEMPLATE(_name, _template, _mode, _show, _store, _index)

#define SENSOR_TEMPLATE_2(_name, _template, _mode, _show, _store,	\
			  _nr, _index)

struct sensor_template_group {};

static int nct6775_add_template_attr_group(struct device *dev, struct nct6775_data *data,
					   const struct sensor_template_group *tg, int repeat)
{}

bool nct6775_reg_is_word_sized(struct nct6775_data *data, u16 reg)
{}
EXPORT_SYMBOL_GPL();

/* We left-align 8-bit temperature values to make the code simpler */
static int nct6775_read_temp(struct nct6775_data *data, u16 reg, u16 *val)
{}

/* This function assumes that the caller holds data->update_lock */
static int nct6775_write_fan_div(struct nct6775_data *data, int nr)
{}

static int nct6775_write_fan_div_common(struct nct6775_data *data, int nr)
{}

static int nct6775_update_fan_div(struct nct6775_data *data)
{}

static int nct6775_update_fan_div_common(struct nct6775_data *data)
{}

static int nct6775_init_fan_div(struct nct6775_data *data)
{}

static int nct6775_init_fan_common(struct device *dev,
				   struct nct6775_data *data)
{}

static int nct6775_select_fan_div(struct device *dev,
				  struct nct6775_data *data, int nr, u16 reg)
{}

static int nct6775_update_pwm(struct device *dev)
{}

static int nct6775_update_pwm_limits(struct device *dev)
{}

struct nct6775_data *nct6775_update_device(struct device *dev)
{}
EXPORT_SYMBOL_GPL();

/*
 * Sysfs callback functions
 */
static ssize_t
show_in_reg(struct device *dev, struct device_attribute *attr, char *buf)
{}

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

ssize_t
nct6775_show_alarm(struct device *dev, struct device_attribute *attr, char *buf)
{}
EXPORT_SYMBOL_GPL();

static int find_temp_source(struct nct6775_data *data, int index, int count)
{}

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

ssize_t
nct6775_show_beep(struct device *dev, struct device_attribute *attr, char *buf)
{}
EXPORT_SYMBOL_GPL();

ssize_t
nct6775_store_beep(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{}
EXPORT_SYMBOL_GPL();

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

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

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

SENSOR_TEMPLATE_2(in_input, "in%d_input", 0444, show_in_reg, NULL, 0, 0);
SENSOR_TEMPLATE(in_alarm, "in%d_alarm", 0444, nct6775_show_alarm, NULL, 0);
SENSOR_TEMPLATE(in_beep, "in%d_beep", 0644, nct6775_show_beep, nct6775_store_beep, 0);
SENSOR_TEMPLATE_2(in_min, "in%d_min", 0644, show_in_reg, store_in_reg, 0, 1);
SENSOR_TEMPLATE_2(in_max, "in%d_max", 0644, show_in_reg, store_in_reg, 0, 2);

/*
 * nct6775_in_is_visible uses the index into the following array
 * to determine if attributes should be created or not.
 * Any change in order or content must be matched.
 */
static struct sensor_device_template *nct6775_attributes_in_template[] =;

static const struct sensor_template_group nct6775_in_template_group =;

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

static ssize_t
show_fan_min(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
store_fan_min(struct device *dev, struct device_attribute *attr,
	      const char *buf, size_t count)
{}

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

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

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

SENSOR_TEMPLATE(fan_input, "fan%d_input", 0444, show_fan, NULL, 0);
SENSOR_TEMPLATE(fan_alarm, "fan%d_alarm", 0444, nct6775_show_alarm, NULL, FAN_ALARM_BASE);
SENSOR_TEMPLATE(fan_beep, "fan%d_beep", 0644, nct6775_show_beep,
		nct6775_store_beep, FAN_ALARM_BASE);
SENSOR_TEMPLATE(fan_pulses, "fan%d_pulses", 0644, show_fan_pulses, store_fan_pulses, 0);
SENSOR_TEMPLATE(fan_min, "fan%d_min", 0644, show_fan_min, store_fan_min, 0);
SENSOR_TEMPLATE(fan_div, "fan%d_div", 0444, show_fan_div, NULL, 0);

/*
 * nct6775_fan_is_visible uses the index into the following array
 * to determine if attributes should be created or not.
 * Any change in order or content must be matched.
 */
static struct sensor_device_template *nct6775_attributes_fan_template[] =;

static const struct sensor_template_group nct6775_fan_template_group =;

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

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

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

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

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

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

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

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

SENSOR_TEMPLATE_2(temp_input, "temp%d_input", 0444, show_temp, NULL, 0, 0);
SENSOR_TEMPLATE(temp_label, "temp%d_label", 0444, show_temp_label, NULL, 0);
SENSOR_TEMPLATE_2(temp_max, "temp%d_max", 0644, show_temp, store_temp, 0, 1);
SENSOR_TEMPLATE_2(temp_max_hyst, "temp%d_max_hyst", 0644, show_temp, store_temp, 0, 2);
SENSOR_TEMPLATE_2(temp_crit, "temp%d_crit", 0644, show_temp, store_temp, 0, 3);
SENSOR_TEMPLATE_2(temp_lcrit, "temp%d_lcrit", 0644, show_temp, store_temp, 0, 4);
SENSOR_TEMPLATE(temp_offset, "temp%d_offset", 0644, show_temp_offset, store_temp_offset, 0);
SENSOR_TEMPLATE(temp_type, "temp%d_type", 0644, show_temp_type, store_temp_type, 0);
SENSOR_TEMPLATE(temp_alarm, "temp%d_alarm", 0444, show_temp_alarm, NULL, 0);
SENSOR_TEMPLATE(temp_beep, "temp%d_beep", 0644, show_temp_beep, store_temp_beep, 0);

/*
 * nct6775_temp_is_visible uses the index into the following array
 * to determine if attributes should be created or not.
 * Any change in order or content must be matched.
 */
static struct sensor_device_template *nct6775_attributes_temp_template[] =;

static const struct sensor_template_group nct6775_temp_template_group =;

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

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

SENSOR_TEMPLATE(tsi_temp_input, "temp%d_input", 0444, show_tsi_temp, NULL, 0);
SENSOR_TEMPLATE(tsi_temp_label, "temp%d_label", 0444, show_tsi_temp_label, NULL, 0);

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

/*
 * The index calculation in nct6775_tsi_temp_is_visible() must be kept in
 * sync with the size of this array.
 */
static struct sensor_device_template *nct6775_tsi_temp_template[] =;

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

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

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

static ssize_t
store_pwm(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 nct6775_data *data, int nr)
{}

static int pwm_update_registers(struct nct6775_data *data, int nr)
{}

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

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

static ssize_t
show_pwm_temp_sel_common(struct nct6775_data *data, char *buf, int src)
{}

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

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

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

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

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

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

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

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

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

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

/*
 * Fan speed tolerance is a tricky beast, since the associated register is
 * a tick counter, but the value is reported and configured as rpm.
 * Compute resulting low and high rpm values and report the difference.
 * A fan speed tolerance only makes sense if a fan target speed has been
 * configured, so only display values other than 0 if that is the case.
 */
static ssize_t
show_speed_tolerance(struct device *dev, struct device_attribute *attr,
		     char *buf)
{}

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

SENSOR_TEMPLATE_2(pwm, "pwm%d", 0644, show_pwm, store_pwm, 0, 0);
SENSOR_TEMPLATE(pwm_mode, "pwm%d_mode", 0644, show_pwm_mode, store_pwm_mode, 0);
SENSOR_TEMPLATE(pwm_enable, "pwm%d_enable", 0644, show_pwm_enable, store_pwm_enable, 0);
SENSOR_TEMPLATE(pwm_temp_sel, "pwm%d_temp_sel", 0644, show_pwm_temp_sel, store_pwm_temp_sel, 0);
SENSOR_TEMPLATE(pwm_target_temp, "pwm%d_target_temp", 0644, show_target_temp, store_target_temp, 0);
SENSOR_TEMPLATE(fan_target, "fan%d_target", 0644, show_target_speed, store_target_speed, 0);
SENSOR_TEMPLATE(fan_tolerance, "fan%d_tolerance", 0644, show_speed_tolerance,
		store_speed_tolerance, 0);

/* Smart Fan registers */

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

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

SENSOR_TEMPLATE(pwm_weight_temp_sel, "pwm%d_weight_temp_sel", 0644,
		show_pwm_weight_temp_sel, store_pwm_weight_temp_sel, 0);
SENSOR_TEMPLATE_2(pwm_weight_temp_step, "pwm%d_weight_temp_step",
		  0644, show_weight_temp, store_weight_temp, 0, 0);
SENSOR_TEMPLATE_2(pwm_weight_temp_step_tol, "pwm%d_weight_temp_step_tol",
		  0644, show_weight_temp, store_weight_temp, 0, 1);
SENSOR_TEMPLATE_2(pwm_weight_temp_step_base, "pwm%d_weight_temp_step_base",
		  0644, show_weight_temp, store_weight_temp, 0, 2);
SENSOR_TEMPLATE_2(pwm_weight_duty_step, "pwm%d_weight_duty_step", 0644, show_pwm, store_pwm, 0, 5);
SENSOR_TEMPLATE_2(pwm_weight_duty_base, "pwm%d_weight_duty_base", 0644, show_pwm, store_pwm, 0, 6);

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

static ssize_t
store_fan_time(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
store_auto_pwm(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
store_auto_temp(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{}

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

SENSOR_TEMPLATE_2(pwm_stop_time, "pwm%d_stop_time", 0644, show_fan_time, store_fan_time, 0, 0);
SENSOR_TEMPLATE_2(pwm_step_up_time, "pwm%d_step_up_time", 0644,
		  show_fan_time, store_fan_time, 0, 1);
SENSOR_TEMPLATE_2(pwm_step_down_time, "pwm%d_step_down_time", 0644,
		  show_fan_time, store_fan_time, 0, 2);
SENSOR_TEMPLATE_2(pwm_start, "pwm%d_start", 0644, show_pwm, store_pwm, 0, 1);
SENSOR_TEMPLATE_2(pwm_floor, "pwm%d_floor", 0644, show_pwm, store_pwm, 0, 2);
SENSOR_TEMPLATE_2(pwm_temp_tolerance, "pwm%d_temp_tolerance", 0644,
		  show_temp_tolerance, store_temp_tolerance, 0, 0);
SENSOR_TEMPLATE_2(pwm_crit_temp_tolerance, "pwm%d_crit_temp_tolerance",
		  0644, show_temp_tolerance, store_temp_tolerance, 0, 1);

SENSOR_TEMPLATE_2(pwm_max, "pwm%d_max", 0644, show_pwm, store_pwm, 0, 3);

SENSOR_TEMPLATE_2(pwm_step, "pwm%d_step", 0644, show_pwm, store_pwm, 0, 4);

SENSOR_TEMPLATE_2(pwm_auto_point1_pwm, "pwm%d_auto_point1_pwm",
		  0644, show_auto_pwm, store_auto_pwm, 0, 0);
SENSOR_TEMPLATE_2(pwm_auto_point1_temp, "pwm%d_auto_point1_temp",
		  0644, show_auto_temp, store_auto_temp, 0, 0);

SENSOR_TEMPLATE_2(pwm_auto_point2_pwm, "pwm%d_auto_point2_pwm",
		  0644, show_auto_pwm, store_auto_pwm, 0, 1);
SENSOR_TEMPLATE_2(pwm_auto_point2_temp, "pwm%d_auto_point2_temp",
		  0644, show_auto_temp, store_auto_temp, 0, 1);

SENSOR_TEMPLATE_2(pwm_auto_point3_pwm, "pwm%d_auto_point3_pwm",
		  0644, show_auto_pwm, store_auto_pwm, 0, 2);
SENSOR_TEMPLATE_2(pwm_auto_point3_temp, "pwm%d_auto_point3_temp",
		  0644, show_auto_temp, store_auto_temp, 0, 2);

SENSOR_TEMPLATE_2(pwm_auto_point4_pwm, "pwm%d_auto_point4_pwm",
		  0644, show_auto_pwm, store_auto_pwm, 0, 3);
SENSOR_TEMPLATE_2(pwm_auto_point4_temp, "pwm%d_auto_point4_temp",
		  0644, show_auto_temp, store_auto_temp, 0, 3);

SENSOR_TEMPLATE_2(pwm_auto_point5_pwm, "pwm%d_auto_point5_pwm",
		  0644, show_auto_pwm, store_auto_pwm, 0, 4);
SENSOR_TEMPLATE_2(pwm_auto_point5_temp, "pwm%d_auto_point5_temp",
		  0644, show_auto_temp, store_auto_temp, 0, 4);

SENSOR_TEMPLATE_2(pwm_auto_point6_pwm, "pwm%d_auto_point6_pwm",
		  0644, show_auto_pwm, store_auto_pwm, 0, 5);
SENSOR_TEMPLATE_2(pwm_auto_point6_temp, "pwm%d_auto_point6_temp",
		  0644, show_auto_temp, store_auto_temp, 0, 5);

SENSOR_TEMPLATE_2(pwm_auto_point7_pwm, "pwm%d_auto_point7_pwm",
		  0644, show_auto_pwm, store_auto_pwm, 0, 6);
SENSOR_TEMPLATE_2(pwm_auto_point7_temp, "pwm%d_auto_point7_temp",
		  0644, show_auto_temp, store_auto_temp, 0, 6);

/*
 * nct6775_pwm_is_visible uses the index into the following array
 * to determine if attributes should be created or not.
 * Any change in order or content must be matched.
 */
static struct sensor_device_template *nct6775_attributes_pwm_template[] =;

static const struct sensor_template_group nct6775_pwm_template_group =;

static inline int nct6775_init_device(struct nct6775_data *data)
{}

static int add_temp_sensors(struct nct6775_data *data, const u16 *regp,
			    int *available, int *mask)
{}

int nct6775_probe(struct device *dev, struct nct6775_data *data,
		  const struct regmap_config *regmapcfg)
{}
EXPORT_SYMBOL_GPL();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();