#include <linux/err.h>
#include <linux/hwmon.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/platform_data/emc2305.h>
#include <linux/thermal.h>
#define EMC2305_REG_DRIVE_FAIL_STATUS …
#define EMC2305_REG_VENDOR …
#define EMC2305_FAN_MAX …
#define EMC2305_FAN_MIN …
#define EMC2305_FAN_MAX_STATE …
#define EMC2305_DEVICE …
#define EMC2305_VENDOR …
#define EMC2305_REG_PRODUCT_ID …
#define EMC2305_TACH_REGS_UNUSE_BITS …
#define EMC2305_TACH_CNT_MULTIPLIER …
#define EMC2305_TACH_RANGE_MIN …
#define EMC2305_PWM_DUTY2STATE(duty, max_state, pwm_max) …
#define EMC2305_PWM_STATE2DUTY(state, max_state, pwm_max) …
#define EMC2305_RPM_FACTOR …
#define EMC2305_REG_FAN_DRIVE(n) …
#define EMC2305_REG_FAN_MIN_DRIVE(n) …
#define EMC2305_REG_FAN_TACH(n) …
enum emc230x_product_id { … };
static const struct i2c_device_id emc2305_ids[] = …;
MODULE_DEVICE_TABLE(i2c, emc2305_ids);
struct emc2305_cdev_data { … };
struct emc2305_data { … };
static char *emc2305_fan_name[] = …;
static void emc2305_unset_tz(struct device *dev);
static int emc2305_get_max_channel(const struct emc2305_data *data)
{ … }
static int emc2305_get_cdev_idx(struct thermal_cooling_device *cdev)
{ … }
static int emc2305_get_cur_state(struct thermal_cooling_device *cdev, unsigned long *state)
{ … }
static int emc2305_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state)
{ … }
static int __emc2305_set_cur_state(struct emc2305_data *data, int cdev_idx, unsigned long state)
{ … }
static int emc2305_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
{ … }
static const struct thermal_cooling_device_ops emc2305_cooling_ops = …;
static int emc2305_show_fault(struct device *dev, int channel)
{ … }
static int emc2305_show_fan(struct device *dev, int channel)
{ … }
static int emc2305_show_pwm(struct device *dev, int channel)
{ … }
static int emc2305_set_pwm(struct device *dev, long val, int channel)
{ … }
static int emc2305_set_single_tz(struct device *dev, int idx)
{ … }
static int emc2305_set_tz(struct device *dev)
{ … }
static void emc2305_unset_tz(struct device *dev)
{ … }
static umode_t
emc2305_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr, int channel)
{
int max_channel = emc2305_get_max_channel(data);
if (channel >= max_channel)
return 0;
switch (type) {
case hwmon_fan:
switch (attr) {
case hwmon_fan_input:
return 0444;
case hwmon_fan_fault:
return 0444;
default:
break;
}
break;
case hwmon_pwm:
switch (attr) {
case hwmon_pwm_input:
return 0644;
default:
break;
}
break;
default:
break;
}
return 0;
};
static int
emc2305_write(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long val)
{
struct emc2305_data *data = dev_get_drvdata(dev);
int cdev_idx;
switch (type) {
case hwmon_pwm:
switch (attr) {
case hwmon_pwm_input:
if (IS_REACHABLE(CONFIG_THERMAL)) {
if (data->pwm_separate)
cdev_idx = channel;
else
cdev_idx = 0;
data->cdev_data[cdev_idx].last_hwmon_state =
EMC2305_PWM_DUTY2STATE(val, data->max_state,
EMC2305_FAN_MAX);
if (data->cdev_data[cdev_idx].last_hwmon_state >=
data->cdev_data[cdev_idx].last_thermal_state)
return __emc2305_set_cur_state(data, cdev_idx,
data->cdev_data[cdev_idx].last_hwmon_state);
return 0;
}
return emc2305_set_pwm(dev, val, channel);
default:
break;
}
break;
default:
break;
}
return -EOPNOTSUPP;
};
static int
emc2305_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long *val)
{
int ret;
switch (type) {
case hwmon_fan:
switch (attr) {
case hwmon_fan_input:
ret = emc2305_show_fan(dev, channel);
if (ret < 0)
return ret;
*val = ret;
return 0;
case hwmon_fan_fault:
ret = emc2305_show_fault(dev, channel);
if (ret < 0)
return ret;
*val = ret;
return 0;
default:
break;
}
break;
case hwmon_pwm:
switch (attr) {
case hwmon_pwm_input:
ret = emc2305_show_pwm(dev, channel);
if (ret < 0)
return ret;
*val = ret;
return 0;
default:
break;
}
break;
default:
break;
}
return -EOPNOTSUPP;
};
static const struct hwmon_ops emc2305_ops = …;
static const struct hwmon_channel_info * const emc2305_info[] = …;
static const struct hwmon_chip_info emc2305_chip_info = …;
static int emc2305_identify(struct device *dev)
{ … }
static int emc2305_probe(struct i2c_client *client)
{ … }
static void emc2305_remove(struct i2c_client *client)
{ … }
static struct i2c_driver emc2305_driver = …;
module_i2c_driver(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;