linux/drivers/hwmon/w83791d.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * w83791d.c - Part of lm_sensors, Linux kernel modules for hardware
 *	       monitoring
 *
 * Copyright (C) 2006-2007 Charles Spirakis <[email protected]>
 */

/*
 * Supports following chips:
 *
 * Chip		#vin	#fanin	#pwm	#temp	wchipid	vendid	i2c	ISA
 * w83791d	10	5	5	3	0x71	0x5ca3	yes	no
 *
 * The w83791d chip appears to be part way between the 83781d and the
 * 83792d. Thus, this file is derived from both the w83792d.c and
 * w83781d.c files.
 *
 * The w83791g chip is the same as the w83791d but lead-free.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-vid.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/jiffies.h>

#define NUMBER_OF_VIN
#define NUMBER_OF_FANIN
#define NUMBER_OF_TEMPIN
#define NUMBER_OF_PWM

/* Addresses to scan */
static const unsigned short normal_i2c[] =;

/* Insmod parameters */

static unsigned short force_subclients[4];
module_param_array();
MODULE_PARM_DESC();

static bool reset;
module_param(reset, bool, 0);
MODULE_PARM_DESC();

static bool init;
module_param(init, bool, 0);
MODULE_PARM_DESC();

/* The W83791D registers */
static const u8 W83791D_REG_IN[NUMBER_OF_VIN] =;

static const u8 W83791D_REG_IN_MAX[NUMBER_OF_VIN] =;
static const u8 W83791D_REG_IN_MIN[NUMBER_OF_VIN] =;
static const u8 W83791D_REG_FAN[NUMBER_OF_FANIN] =;
static const u8 W83791D_REG_FAN_MIN[NUMBER_OF_FANIN] =;

static const u8 W83791D_REG_PWM[NUMBER_OF_PWM] =;

static const u8 W83791D_REG_TEMP_TARGET[3] =;

static const u8 W83791D_REG_TEMP_TOL[2] =;

static const u8 W83791D_REG_FAN_CFG[2] =;

static const u8 W83791D_REG_FAN_DIV[3] =;

#define W83791D_REG_BANK
#define W83791D_REG_TEMP2_CONFIG
#define W83791D_REG_TEMP3_CONFIG

static const u8 W83791D_REG_TEMP1[3] =;

static const u8 W83791D_REG_TEMP_ADD[2][6] =;

#define W83791D_REG_BEEP_CONFIG

static const u8 W83791D_REG_BEEP_CTRL[3] =;

#define W83791D_REG_GPIO
#define W83791D_REG_CONFIG
#define W83791D_REG_VID_FANDIV
#define W83791D_REG_DID_VID4
#define W83791D_REG_WCHIPID
#define W83791D_REG_CHIPMAN
#define W83791D_REG_PIN
#define W83791D_REG_I2C_SUBADDR

#define W83791D_REG_ALARM1
#define W83791D_REG_ALARM2
#define W83791D_REG_ALARM3

#define W83791D_REG_VBAT
#define W83791D_REG_I2C_ADDR

/*
 * The SMBus locks itself. The Winbond W83791D has a bank select register
 * (index 0x4e), but the driver only accesses registers in bank 0. Since
 * we don't switch banks, we don't need any special code to handle
 * locking access between bank switches
 */
static inline int w83791d_read(struct i2c_client *client, u8 reg)
{}

static inline int w83791d_write(struct i2c_client *client, u8 reg, u8 value)
{}

/*
 * The analog voltage inputs have 16mV LSB. Since the sysfs output is
 * in mV as would be measured on the chip input pin, need to just
 * multiply/divide by 16 to translate from/to register values.
 */
#define IN_TO_REG(val)
#define IN_FROM_REG(val)

static u8 fan_to_reg(long rpm, int div)
{}

#define FAN_FROM_REG(val, div)

/* for temp1 which is 8-bit resolution, LSB = 1 degree Celsius */
#define TEMP1_FROM_REG(val)
#define TEMP1_TO_REG(val)

/*
 * for temp2 and temp3 which are 9-bit resolution, LSB = 0.5 degree Celsius
 * Assumes the top 8 bits are the integral amount and the bottom 8 bits
 * are the fractional amount. Since we only have 0.5 degree resolution,
 * the bottom 7 bits will always be zero
 */
#define TEMP23_FROM_REG(val)
#define TEMP23_TO_REG(val)

/* for thermal cruise target temp, 7-bits, LSB = 1 degree Celsius */
#define TARGET_TEMP_TO_REG(val)

/* for thermal cruise temp tolerance, 4-bits, LSB = 1 degree Celsius */
#define TOL_TEMP_TO_REG(val)

#define BEEP_MASK_TO_REG(val)
#define BEEP_MASK_FROM_REG(val)

#define DIV_FROM_REG(val)

static u8 div_to_reg(int nr, long val)
{}

struct w83791d_data {};

static int w83791d_probe(struct i2c_client *client);
static int w83791d_detect(struct i2c_client *client,
			  struct i2c_board_info *info);
static void w83791d_remove(struct i2c_client *client);

static int w83791d_read(struct i2c_client *client, u8 reg);
static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
static struct w83791d_data *w83791d_update_device(struct device *dev);

#ifdef DEBUG
static void w83791d_print_debug(struct w83791d_data *data, struct device *dev);
#endif

static void w83791d_init_client(struct i2c_client *client);

static const struct i2c_device_id w83791d_id[] =;
MODULE_DEVICE_TABLE(i2c, w83791d_id);

static struct i2c_driver w83791d_driver =;

/* following are the sysfs callback functions */
#define show_in_reg(reg)

show_in_reg(in);
show_in_reg(in_min);
show_in_reg(in_max);

#define store_in_reg(REG, reg)
store_in_reg(MIN, min);
store_in_reg(MAX, max);

static struct sensor_device_attribute sda_in_input[] =;

static struct sensor_device_attribute sda_in_min[] =;

static struct sensor_device_attribute sda_in_max[] =;


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

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

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

/*
 * Note: The bitmask for the beep enable/disable is different than
 * the bitmask for the alarm.
 */
static struct sensor_device_attribute sda_in_beep[] =;

static struct sensor_device_attribute sda_in_alarm[] =;

#define show_fan_reg(reg)

show_fan_reg(fan);
show_fan_reg(fan_min);

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

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

/*
 * Note: we save and restore the fan minimum here, because its value is
 * determined in part by the fan divisor.  This follows the principle of
 * least surprise; the user doesn't expect the fan minimum to change just
 * because the divisor changed.
 */
static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr,
				const char *buf, size_t count)
{}

static struct sensor_device_attribute sda_fan_input[] =;

static struct sensor_device_attribute sda_fan_min[] =;

static struct sensor_device_attribute sda_fan_div[] =;

static struct sensor_device_attribute sda_fan_beep[] =;

static struct sensor_device_attribute sda_fan_alarm[] =;

/* read/write PWMs */
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)
{}

static struct sensor_device_attribute sda_pwm[] =;

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

static ssize_t store_pwmenable(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{}
static struct sensor_device_attribute sda_pwmenable[] =;

/* For Smart Fan I / Thermal Cruise */
static ssize_t show_temp_target(struct device *dev,
			struct device_attribute *attr, char *buf)
{}

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

static struct sensor_device_attribute sda_temp_target[] =;

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)
{}

static struct sensor_device_attribute sda_temp_tolerance[] =;

/* read/write the temperature1, includes measured value and limits */
static ssize_t show_temp1(struct device *dev, struct device_attribute *devattr,
				char *buf)
{}

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

/* read/write temperature2-3, includes measured value and limits */
static ssize_t show_temp23(struct device *dev, struct device_attribute *devattr,
				char *buf)
{}

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

static struct sensor_device_attribute_2 sda_temp_input[] =;

static struct sensor_device_attribute_2 sda_temp_max[] =;

static struct sensor_device_attribute_2 sda_temp_max_hyst[] =;

/*
 * Note: The bitmask for the beep enable/disable is different than
 * the bitmask for the alarm.
 */
static struct sensor_device_attribute sda_temp_beep[] =;

static struct sensor_device_attribute sda_temp_alarm[] =;

/* get realtime status of all sensors items: voltage, temp, fan */
static ssize_t alarms_show(struct device *dev, struct device_attribute *attr,
			   char *buf)
{}

static DEVICE_ATTR_RO(alarms);

/* Beep control */

#define GLOBAL_BEEP_ENABLE_SHIFT
#define GLOBAL_BEEP_ENABLE_MASK

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

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


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

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

static struct sensor_device_attribute sda_beep_ctrl[] =;

/* cpu voltage regulation information */
static ssize_t cpu0_vid_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
{}

static DEVICE_ATTR_RO(cpu0_vid);

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);

#define IN_UNIT_ATTRS(X)

#define FAN_UNIT_ATTRS(X)

#define TEMP_UNIT_ATTRS(X)

static struct attribute *w83791d_attributes[] =;

static const struct attribute_group w83791d_group =;

/*
 * Separate group of attributes for fan/pwm 4-5. Their pins can also be
 * in use for GPIO in which case their sysfs-interface should not be made
 * available
 */
static struct attribute *w83791d_attributes_fanpwm45[] =;

static const struct attribute_group w83791d_group_fanpwm45 =;

static int w83791d_detect_subclients(struct i2c_client *client)
{}


/* Return 0 if detection is successful, -ENODEV otherwise */
static int w83791d_detect(struct i2c_client *client,
			  struct i2c_board_info *info)
{}

static int w83791d_probe(struct i2c_client *client)
{}

static void w83791d_remove(struct i2c_client *client)
{}

static void w83791d_init_client(struct i2c_client *client)
{}

static struct w83791d_data *w83791d_update_device(struct device *dev)
{}

#ifdef DEBUG
static void w83791d_print_debug(struct w83791d_data *data, struct device *dev)
{}
#endif

module_i2c_driver();

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