Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drivers: w1: add hwmon temp support for w1_therm

This change adds hwmon temp support for w1_therm.

Signed-off-by: Jaghathiswari Rankappagounder Natarajan <jaghu@google.com>
Acked-by: Evgeniy Polyakov <zbr@ioremap.net>
Acked-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

+86
+86
drivers/w1/slaves/w1_therm.c
··· 29 29 #include <linux/types.h> 30 30 #include <linux/slab.h> 31 31 #include <linux/delay.h> 32 + #include <linux/hwmon.h> 32 33 33 34 #include <linux/w1.h> 34 35 ··· 114 113 &dev_attr_w1_seq.attr, 115 114 NULL, 116 115 }; 116 + 117 117 ATTRIBUTE_GROUPS(w1_therm); 118 118 ATTRIBUTE_GROUPS(w1_ds28ea00); 119 + 120 + #if IS_REACHABLE(CONFIG_HWMON) 121 + static int w1_read_temp(struct device *dev, u32 attr, int channel, 122 + long *val); 123 + 124 + static umode_t w1_is_visible(const void *_data, enum hwmon_sensor_types type, 125 + u32 attr, int channel) 126 + { 127 + return attr == hwmon_temp_input ? 0444 : 0; 128 + } 129 + 130 + static int w1_read(struct device *dev, enum hwmon_sensor_types type, 131 + u32 attr, int channel, long *val) 132 + { 133 + switch (type) { 134 + case hwmon_temp: 135 + return w1_read_temp(dev, attr, channel, val); 136 + default: 137 + return -EOPNOTSUPP; 138 + } 139 + } 140 + 141 + static const u32 w1_temp_config[] = { 142 + HWMON_T_INPUT, 143 + 0 144 + }; 145 + 146 + static const struct hwmon_channel_info w1_temp = { 147 + .type = hwmon_temp, 148 + .config = w1_temp_config, 149 + }; 150 + 151 + static const struct hwmon_channel_info *w1_info[] = { 152 + &w1_temp, 153 + NULL 154 + }; 155 + 156 + static const struct hwmon_ops w1_hwmon_ops = { 157 + .is_visible = w1_is_visible, 158 + .read = w1_read, 159 + }; 160 + 161 + static const struct hwmon_chip_info w1_chip_info = { 162 + .ops = &w1_hwmon_ops, 163 + .info = w1_info, 164 + }; 165 + #define W1_CHIPINFO (&w1_chip_info) 166 + #else 167 + #define W1_CHIPINFO NULL 168 + #endif 119 169 120 170 static struct w1_family_ops w1_therm_fops = { 121 171 .add_slave = w1_therm_add_slave, 122 172 .remove_slave = w1_therm_remove_slave, 123 173 .groups = w1_therm_groups, 174 + .chip_info = W1_CHIPINFO, 124 175 }; 125 176 126 177 static struct w1_family_ops w1_ds28ea00_fops = { 127 178 .add_slave = w1_therm_add_slave, 128 179 .remove_slave = w1_therm_remove_slave, 129 180 .groups = w1_ds28ea00_groups, 181 + .chip_info = W1_CHIPINFO, 130 182 }; 131 183 132 184 static struct w1_family w1_therm_family_DS18S20 = { ··· 607 553 ret = PAGE_SIZE - c; 608 554 return ret; 609 555 } 556 + 557 + #if IS_REACHABLE(CONFIG_HWMON) 558 + static int w1_read_temp(struct device *device, u32 attr, int channel, 559 + long *val) 560 + { 561 + struct w1_slave *sl = dev_get_drvdata(device); 562 + struct therm_info info; 563 + u8 fid = sl->family->fid; 564 + int ret; 565 + 566 + switch (attr) { 567 + case hwmon_temp_input: 568 + ret = read_therm(device, sl, &info); 569 + if (ret) 570 + return ret; 571 + 572 + if (!info.verdict) { 573 + ret = -EIO; 574 + return ret; 575 + } 576 + 577 + *val = w1_convert_temp(info.rom, fid); 578 + ret = 0; 579 + break; 580 + default: 581 + ret = -EOPNOTSUPP; 582 + break; 583 + } 584 + 585 + return ret; 586 + } 587 + #endif 610 588 611 589 #define W1_42_CHAIN 0x99 612 590 #define W1_42_CHAIN_OFF 0x3C