提交 a584287c 编写于 作者: G Guenter Roeck

hwmon: (ltc4245) Convert to use new hwmon registration API

Simplify code and reduce code size by using the new hwmon
registration API.
Signed-off-by: NGuenter Roeck <linux@roeck-us.net>
上级 bb43cc45
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/bitops.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/i2c.h> #include <linux/i2c.h>
...@@ -53,8 +54,6 @@ enum ltc4245_cmd { ...@@ -53,8 +54,6 @@ enum ltc4245_cmd {
struct ltc4245_data { struct ltc4245_data {
struct i2c_client *client; struct i2c_client *client;
const struct attribute_group *groups[3];
struct mutex update_lock; struct mutex update_lock;
bool valid; bool valid;
unsigned long last_updated; /* in jiffies */ unsigned long last_updated; /* in jiffies */
...@@ -162,7 +161,7 @@ static struct ltc4245_data *ltc4245_update_device(struct device *dev) ...@@ -162,7 +161,7 @@ static struct ltc4245_data *ltc4245_update_device(struct device *dev)
ltc4245_update_gpios(dev); ltc4245_update_gpios(dev);
data->last_updated = jiffies; data->last_updated = jiffies;
data->valid = 1; data->valid = true;
} }
mutex_unlock(&data->update_lock); mutex_unlock(&data->update_lock);
...@@ -256,213 +255,204 @@ static unsigned int ltc4245_get_current(struct device *dev, u8 reg) ...@@ -256,213 +255,204 @@ static unsigned int ltc4245_get_current(struct device *dev, u8 reg)
return curr; return curr;
} }
static ssize_t ltc4245_show_voltage(struct device *dev, /* Map from voltage channel index to voltage register */
struct device_attribute *da,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
const int voltage = ltc4245_get_voltage(dev, attr->index);
return snprintf(buf, PAGE_SIZE, "%d\n", voltage); static const s8 ltc4245_in_regs[] = {
} LTC4245_12VIN, LTC4245_5VIN, LTC4245_3VIN, LTC4245_VEEIN,
LTC4245_12VOUT, LTC4245_5VOUT, LTC4245_3VOUT, LTC4245_VEEOUT,
};
/* Map from current channel index to current register */
static ssize_t ltc4245_show_current(struct device *dev, static const s8 ltc4245_curr_regs[] = {
struct device_attribute *da, LTC4245_12VSENSE, LTC4245_5VSENSE, LTC4245_3VSENSE, LTC4245_VEESENSE,
char *buf) };
static int ltc4245_read_curr(struct device *dev, u32 attr, int channel,
long *val)
{ {
struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct ltc4245_data *data = ltc4245_update_device(dev);
const unsigned int curr = ltc4245_get_current(dev, attr->index);
return snprintf(buf, PAGE_SIZE, "%u\n", curr); switch (attr) {
case hwmon_curr_input:
*val = ltc4245_get_current(dev, ltc4245_curr_regs[channel]);
return 0;
case hwmon_curr_max_alarm:
*val = !!(data->cregs[LTC4245_FAULT1] & BIT(channel + 4));
return 0;
default:
return -EOPNOTSUPP;
}
} }
static ssize_t ltc4245_show_power(struct device *dev, static int ltc4245_read_in(struct device *dev, u32 attr, int channel, long *val)
struct device_attribute *da,
char *buf)
{ {
struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct ltc4245_data *data = ltc4245_update_device(dev);
const unsigned int curr = ltc4245_get_current(dev, attr->index);
const int output_voltage = ltc4245_get_voltage(dev, attr->index+1);
/* current in mA * voltage in mV == power in uW */ switch (attr) {
const unsigned int power = abs(output_voltage * curr); case hwmon_in_input:
if (channel < 8) {
*val = ltc4245_get_voltage(dev,
ltc4245_in_regs[channel]);
} else {
int regval = data->gpios[channel - 8];
if (regval < 0)
return regval;
*val = regval * 10;
}
return 0;
case hwmon_in_min_alarm:
if (channel < 4)
*val = !!(data->cregs[LTC4245_FAULT1] & BIT(channel));
else
*val = !!(data->cregs[LTC4245_FAULT2] &
BIT(channel - 4));
return 0;
default:
return -EOPNOTSUPP;
}
}
return snprintf(buf, PAGE_SIZE, "%u\n", power); static int ltc4245_read_power(struct device *dev, u32 attr, int channel,
long *val)
{
unsigned long curr;
long voltage;
switch (attr) {
case hwmon_power_input:
(void)ltc4245_update_device(dev);
curr = ltc4245_get_current(dev, ltc4245_curr_regs[channel]);
voltage = ltc4245_get_voltage(dev, ltc4245_in_regs[channel]);
*val = abs(curr * voltage);
return 0;
default:
return -EOPNOTSUPP;
}
} }
static ssize_t ltc4245_show_alarm(struct device *dev, static int ltc4245_read(struct device *dev, enum hwmon_sensor_types type,
struct device_attribute *da, u32 attr, int channel, long *val)
char *buf)
{ {
struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(da);
struct ltc4245_data *data = ltc4245_update_device(dev);
const u8 reg = data->cregs[attr->index];
const u32 mask = attr->nr;
return snprintf(buf, PAGE_SIZE, "%u\n", (reg & mask) ? 1 : 0); switch (type) {
case hwmon_curr:
return ltc4245_read_curr(dev, attr, channel, val);
case hwmon_power:
return ltc4245_read_power(dev, attr, channel, val);
case hwmon_in:
return ltc4245_read_in(dev, attr, channel - 1, val);
default:
return -EOPNOTSUPP;
}
} }
static ssize_t ltc4245_show_gpio(struct device *dev, static umode_t ltc4245_is_visible(const void *_data,
struct device_attribute *da, enum hwmon_sensor_types type,
char *buf) u32 attr, int channel)
{ {
struct sensor_device_attribute *attr = to_sensor_dev_attr(da); const struct ltc4245_data *data = _data;
struct ltc4245_data *data = ltc4245_update_device(dev);
int val = data->gpios[attr->index]; switch (type) {
case hwmon_in:
if (channel == 0)
return 0;
switch (attr) {
case hwmon_in_input:
if (channel > 9 && !data->use_extra_gpios)
return 0;
return S_IRUGO;
case hwmon_in_min_alarm:
if (channel > 8)
return 0;
return S_IRUGO;
default:
return 0;
}
case hwmon_curr:
switch (attr) {
case hwmon_curr_input:
case hwmon_curr_max_alarm:
return S_IRUGO;
default:
return 0;
}
case hwmon_power:
switch (attr) {
case hwmon_power_input:
return S_IRUGO;
default:
return 0;
}
default:
return 0;
}
}
/* handle stale GPIO's */ static const u32 ltc4245_in_config[] = {
if (val < 0) HWMON_I_INPUT, /* dummy, skipped in is_visible */
return val; HWMON_I_INPUT | HWMON_I_MIN_ALARM,
HWMON_I_INPUT | HWMON_I_MIN_ALARM,
HWMON_I_INPUT | HWMON_I_MIN_ALARM,
HWMON_I_INPUT | HWMON_I_MIN_ALARM,
HWMON_I_INPUT | HWMON_I_MIN_ALARM,
HWMON_I_INPUT | HWMON_I_MIN_ALARM,
HWMON_I_INPUT | HWMON_I_MIN_ALARM,
HWMON_I_INPUT | HWMON_I_MIN_ALARM,
HWMON_I_INPUT,
HWMON_I_INPUT,
HWMON_I_INPUT,
0
};
/* Convert to millivolts and print */ static const struct hwmon_channel_info ltc4245_in = {
return snprintf(buf, PAGE_SIZE, "%u\n", val * 10); .type = hwmon_in,
} .config = ltc4245_in_config,
};
/* Construct a sensor_device_attribute structure for each register */ static const u32 ltc4245_curr_config[] = {
HWMON_C_INPUT | HWMON_C_MAX_ALARM,
/* Input voltages */ HWMON_C_INPUT | HWMON_C_MAX_ALARM,
static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ltc4245_show_voltage, NULL, HWMON_C_INPUT | HWMON_C_MAX_ALARM,
LTC4245_12VIN); HWMON_C_INPUT | HWMON_C_MAX_ALARM,
static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, ltc4245_show_voltage, NULL, 0
LTC4245_5VIN); };
static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, ltc4245_show_voltage, NULL,
LTC4245_3VIN);
static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, ltc4245_show_voltage, NULL,
LTC4245_VEEIN);
/* Input undervoltage alarms */
static SENSOR_DEVICE_ATTR_2(in1_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL,
1 << 0, LTC4245_FAULT1);
static SENSOR_DEVICE_ATTR_2(in2_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL,
1 << 1, LTC4245_FAULT1);
static SENSOR_DEVICE_ATTR_2(in3_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL,
1 << 2, LTC4245_FAULT1);
static SENSOR_DEVICE_ATTR_2(in4_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL,
1 << 3, LTC4245_FAULT1);
/* Currents (via sense resistor) */
static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc4245_show_current, NULL,
LTC4245_12VSENSE);
static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, ltc4245_show_current, NULL,
LTC4245_5VSENSE);
static SENSOR_DEVICE_ATTR(curr3_input, S_IRUGO, ltc4245_show_current, NULL,
LTC4245_3VSENSE);
static SENSOR_DEVICE_ATTR(curr4_input, S_IRUGO, ltc4245_show_current, NULL,
LTC4245_VEESENSE);
/* Overcurrent alarms */
static SENSOR_DEVICE_ATTR_2(curr1_max_alarm, S_IRUGO, ltc4245_show_alarm, NULL,
1 << 4, LTC4245_FAULT1);
static SENSOR_DEVICE_ATTR_2(curr2_max_alarm, S_IRUGO, ltc4245_show_alarm, NULL,
1 << 5, LTC4245_FAULT1);
static SENSOR_DEVICE_ATTR_2(curr3_max_alarm, S_IRUGO, ltc4245_show_alarm, NULL,
1 << 6, LTC4245_FAULT1);
static SENSOR_DEVICE_ATTR_2(curr4_max_alarm, S_IRUGO, ltc4245_show_alarm, NULL,
1 << 7, LTC4245_FAULT1);
/* Output voltages */
static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, ltc4245_show_voltage, NULL,
LTC4245_12VOUT);
static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, ltc4245_show_voltage, NULL,
LTC4245_5VOUT);
static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, ltc4245_show_voltage, NULL,
LTC4245_3VOUT);
static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, ltc4245_show_voltage, NULL,
LTC4245_VEEOUT);
/* Power Bad alarms */
static SENSOR_DEVICE_ATTR_2(in5_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL,
1 << 0, LTC4245_FAULT2);
static SENSOR_DEVICE_ATTR_2(in6_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL,
1 << 1, LTC4245_FAULT2);
static SENSOR_DEVICE_ATTR_2(in7_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL,
1 << 2, LTC4245_FAULT2);
static SENSOR_DEVICE_ATTR_2(in8_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL,
1 << 3, LTC4245_FAULT2);
/* GPIO voltages */
static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, ltc4245_show_gpio, NULL, 0);
static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, ltc4245_show_gpio, NULL, 1);
static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, ltc4245_show_gpio, NULL, 2);
/* Power Consumption (virtual) */
static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ltc4245_show_power, NULL,
LTC4245_12VSENSE);
static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, ltc4245_show_power, NULL,
LTC4245_5VSENSE);
static SENSOR_DEVICE_ATTR(power3_input, S_IRUGO, ltc4245_show_power, NULL,
LTC4245_3VSENSE);
static SENSOR_DEVICE_ATTR(power4_input, S_IRUGO, ltc4245_show_power, NULL,
LTC4245_VEESENSE);
/* static const struct hwmon_channel_info ltc4245_curr = {
* Finally, construct an array of pointers to members of the above objects, .type = hwmon_curr,
* as required for sysfs_create_group() .config = ltc4245_curr_config,
*/
static struct attribute *ltc4245_std_attributes[] = {
&sensor_dev_attr_in1_input.dev_attr.attr,
&sensor_dev_attr_in2_input.dev_attr.attr,
&sensor_dev_attr_in3_input.dev_attr.attr,
&sensor_dev_attr_in4_input.dev_attr.attr,
&sensor_dev_attr_in1_min_alarm.dev_attr.attr,
&sensor_dev_attr_in2_min_alarm.dev_attr.attr,
&sensor_dev_attr_in3_min_alarm.dev_attr.attr,
&sensor_dev_attr_in4_min_alarm.dev_attr.attr,
&sensor_dev_attr_curr1_input.dev_attr.attr,
&sensor_dev_attr_curr2_input.dev_attr.attr,
&sensor_dev_attr_curr3_input.dev_attr.attr,
&sensor_dev_attr_curr4_input.dev_attr.attr,
&sensor_dev_attr_curr1_max_alarm.dev_attr.attr,
&sensor_dev_attr_curr2_max_alarm.dev_attr.attr,
&sensor_dev_attr_curr3_max_alarm.dev_attr.attr,
&sensor_dev_attr_curr4_max_alarm.dev_attr.attr,
&sensor_dev_attr_in5_input.dev_attr.attr,
&sensor_dev_attr_in6_input.dev_attr.attr,
&sensor_dev_attr_in7_input.dev_attr.attr,
&sensor_dev_attr_in8_input.dev_attr.attr,
&sensor_dev_attr_in5_min_alarm.dev_attr.attr,
&sensor_dev_attr_in6_min_alarm.dev_attr.attr,
&sensor_dev_attr_in7_min_alarm.dev_attr.attr,
&sensor_dev_attr_in8_min_alarm.dev_attr.attr,
&sensor_dev_attr_in9_input.dev_attr.attr,
&sensor_dev_attr_power1_input.dev_attr.attr,
&sensor_dev_attr_power2_input.dev_attr.attr,
&sensor_dev_attr_power3_input.dev_attr.attr,
&sensor_dev_attr_power4_input.dev_attr.attr,
NULL,
}; };
static struct attribute *ltc4245_gpio_attributes[] = { static const u32 ltc4245_power_config[] = {
&sensor_dev_attr_in10_input.dev_attr.attr, HWMON_P_INPUT,
&sensor_dev_attr_in11_input.dev_attr.attr, HWMON_P_INPUT,
NULL, HWMON_P_INPUT,
HWMON_P_INPUT,
0
}; };
static const struct attribute_group ltc4245_std_group = { static const struct hwmon_channel_info ltc4245_power = {
.attrs = ltc4245_std_attributes, .type = hwmon_power,
.config = ltc4245_power_config,
}; };
static const struct attribute_group ltc4245_gpio_group = { static const struct hwmon_channel_info *ltc4245_info[] = {
.attrs = ltc4245_gpio_attributes, &ltc4245_in,
&ltc4245_curr,
&ltc4245_power,
NULL
}; };
static void ltc4245_sysfs_add_groups(struct ltc4245_data *data) static const struct hwmon_ops ltc4245_hwmon_ops = {
{ .is_visible = ltc4245_is_visible,
/* standard sysfs attributes */ .read = ltc4245_read,
data->groups[0] = &ltc4245_std_group; };
/* if we're using the extra gpio support, register it's attributes */ static const struct hwmon_chip_info ltc4245_chip_info = {
if (data->use_extra_gpios) .ops = &ltc4245_hwmon_ops,
data->groups[1] = &ltc4245_gpio_group; .info = ltc4245_info,
} };
static bool ltc4245_use_extra_gpios(struct i2c_client *client) static bool ltc4245_use_extra_gpios(struct i2c_client *client)
{ {
...@@ -502,12 +492,10 @@ static int ltc4245_probe(struct i2c_client *client, ...@@ -502,12 +492,10 @@ static int ltc4245_probe(struct i2c_client *client,
i2c_smbus_write_byte_data(client, LTC4245_FAULT1, 0x00); i2c_smbus_write_byte_data(client, LTC4245_FAULT1, 0x00);
i2c_smbus_write_byte_data(client, LTC4245_FAULT2, 0x00); i2c_smbus_write_byte_data(client, LTC4245_FAULT2, 0x00);
/* Add sysfs hooks */ hwmon_dev = devm_hwmon_device_register_with_info(&client->dev,
ltc4245_sysfs_add_groups(data); client->name, data,
&ltc4245_chip_info,
hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, NULL);
client->name, data,
data->groups);
return PTR_ERR_OR_ZERO(hwmon_dev); return PTR_ERR_OR_ZERO(hwmon_dev);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部