linux/drivers/hwmon/emc2103.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * emc2103.c - Support for SMSC EMC2103
 * Copyright (c) 2010 SMSC
 */

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

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

static const u8 REG_TEMP[4] =;
static const u8 REG_TEMP_MIN[4] =;
static const u8 REG_TEMP_MAX[4] =;

#define REG_CONF1
#define REG_TEMP_MAX_ALARM
#define REG_TEMP_MIN_ALARM
#define REG_FAN_CONF1
#define REG_FAN_TARGET_LO
#define REG_FAN_TARGET_HI
#define REG_FAN_TACH_HI
#define REG_FAN_TACH_LO
#define REG_PRODUCT_ID
#define REG_MFG_ID

/* equation 4 from datasheet: rpm = (3932160 * multipler) / count */
#define FAN_RPM_FACTOR

/*
 * 2103-2 and 2103-4's 3rd temperature sensor can be connected to two diodes
 * in anti-parallel mode, and in this configuration both can be read
 * independently (so we have 4 temperature inputs).  The device can't
 * detect if it's connected in this mode, so we have to manually enable
 * it.  Default is to leave the device in the state it's already in (-1).
 * This parameter allows APD mode to be optionally forced on or off
 */
static int apd =;
module_param(apd, bint, 0);
MODULE_PARM_DESC();

struct temperature {};

struct emc2103_data {};

static int read_u8_from_i2c(struct i2c_client *client, u8 i2c_reg, u8 *output)
{}

static void read_temp_from_i2c(struct i2c_client *client, u8 i2c_reg,
			       struct temperature *temp)
{}

static void read_fan_from_i2c(struct i2c_client *client, u16 *output,
			      u8 hi_addr, u8 lo_addr)
{}

static void write_fan_target_to_i2c(struct i2c_client *client, u16 new_target)
{}

static void read_fan_config_from_i2c(struct i2c_client *client)

{}

static struct emc2103_data *emc2103_update_device(struct device *dev)
{}

static ssize_t
temp_show(struct device *dev, struct device_attribute *da, char *buf)
{}

static ssize_t
temp_min_show(struct device *dev, struct device_attribute *da, char *buf)
{}

static ssize_t
temp_max_show(struct device *dev, struct device_attribute *da, char *buf)
{}

static ssize_t
temp_fault_show(struct device *dev, struct device_attribute *da, char *buf)
{}

static ssize_t
temp_min_alarm_show(struct device *dev, struct device_attribute *da,
		    char *buf)
{}

static ssize_t
temp_max_alarm_show(struct device *dev, struct device_attribute *da,
		    char *buf)
{}

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

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

static ssize_t
fan1_input_show(struct device *dev, struct device_attribute *da, char *buf)
{}

static ssize_t
fan1_div_show(struct device *dev, struct device_attribute *da, char *buf)
{}

/*
 * Note: we also update the fan target here, because its value is
 * determined in part by the fan clock divider.  This follows the principle
 * of least surprise; the user doesn't expect the fan target to change just
 * because the divider changed.
 */
static ssize_t fan1_div_store(struct device *dev, struct device_attribute *da,
			      const char *buf, size_t count)
{}

static ssize_t
fan1_target_show(struct device *dev, struct device_attribute *da, char *buf)
{}

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

static ssize_t
fan1_fault_show(struct device *dev, struct device_attribute *da, char *buf)
{}

static ssize_t
pwm1_enable_show(struct device *dev, struct device_attribute *da, char *buf)
{}

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

static SENSOR_DEVICE_ATTR_RO(temp1_input, temp, 0);
static SENSOR_DEVICE_ATTR_RW(temp1_min, temp_min, 0);
static SENSOR_DEVICE_ATTR_RW(temp1_max, temp_max, 0);
static SENSOR_DEVICE_ATTR_RO(temp1_fault, temp_fault, 0);
static SENSOR_DEVICE_ATTR_RO(temp1_min_alarm, temp_min_alarm, 0);
static SENSOR_DEVICE_ATTR_RO(temp1_max_alarm, temp_max_alarm, 0);

static SENSOR_DEVICE_ATTR_RO(temp2_input, temp, 1);
static SENSOR_DEVICE_ATTR_RW(temp2_min, temp_min, 1);
static SENSOR_DEVICE_ATTR_RW(temp2_max, temp_max, 1);
static SENSOR_DEVICE_ATTR_RO(temp2_fault, temp_fault, 1);
static SENSOR_DEVICE_ATTR_RO(temp2_min_alarm, temp_min_alarm, 1);
static SENSOR_DEVICE_ATTR_RO(temp2_max_alarm, temp_max_alarm, 1);

static SENSOR_DEVICE_ATTR_RO(temp3_input, temp, 2);
static SENSOR_DEVICE_ATTR_RW(temp3_min, temp_min, 2);
static SENSOR_DEVICE_ATTR_RW(temp3_max, temp_max, 2);
static SENSOR_DEVICE_ATTR_RO(temp3_fault, temp_fault, 2);
static SENSOR_DEVICE_ATTR_RO(temp3_min_alarm, temp_min_alarm, 2);
static SENSOR_DEVICE_ATTR_RO(temp3_max_alarm, temp_max_alarm, 2);

static SENSOR_DEVICE_ATTR_RO(temp4_input, temp, 3);
static SENSOR_DEVICE_ATTR_RW(temp4_min, temp_min, 3);
static SENSOR_DEVICE_ATTR_RW(temp4_max, temp_max, 3);
static SENSOR_DEVICE_ATTR_RO(temp4_fault, temp_fault, 3);
static SENSOR_DEVICE_ATTR_RO(temp4_min_alarm, temp_min_alarm, 3);
static SENSOR_DEVICE_ATTR_RO(temp4_max_alarm, temp_max_alarm, 3);

static DEVICE_ATTR_RO(fan1_input);
static DEVICE_ATTR_RW(fan1_div);
static DEVICE_ATTR_RW(fan1_target);
static DEVICE_ATTR_RO(fan1_fault);

static DEVICE_ATTR_RW(pwm1_enable);

/* sensors present on all models */
static struct attribute *emc2103_attributes[] =;

/* extra temperature sensors only present on 2103-2 and 2103-4 */
static struct attribute *emc2103_attributes_temp3[] =;

/* extra temperature sensors only present on 2103-2 and 2103-4 in APD mode */
static struct attribute *emc2103_attributes_temp4[] =;

static const struct attribute_group emc2103_group =;

static const struct attribute_group emc2103_temp3_group =;

static const struct attribute_group emc2103_temp4_group =;

static int
emc2103_probe(struct i2c_client *client)
{}

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

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

static struct i2c_driver emc2103_driver =;

module_i2c_driver();

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