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

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: Guenter Roeck <linux@roeck-us.net>

+190 -202
+190 -202
drivers/hwmon/ltc4245.c
··· 16 16 #include <linux/kernel.h> 17 17 #include <linux/module.h> 18 18 #include <linux/init.h> 19 + #include <linux/bitops.h> 19 20 #include <linux/err.h> 20 21 #include <linux/slab.h> 21 22 #include <linux/i2c.h> ··· 53 52 54 53 struct ltc4245_data { 55 54 struct i2c_client *client; 56 - 57 - const struct attribute_group *groups[3]; 58 55 59 56 struct mutex update_lock; 60 57 bool valid; ··· 161 162 ltc4245_update_gpios(dev); 162 163 163 164 data->last_updated = jiffies; 164 - data->valid = 1; 165 + data->valid = true; 165 166 } 166 167 167 168 mutex_unlock(&data->update_lock); ··· 255 256 return curr; 256 257 } 257 258 258 - static ssize_t ltc4245_show_voltage(struct device *dev, 259 - struct device_attribute *da, 260 - char *buf) 259 + /* Map from voltage channel index to voltage register */ 260 + 261 + static const s8 ltc4245_in_regs[] = { 262 + LTC4245_12VIN, LTC4245_5VIN, LTC4245_3VIN, LTC4245_VEEIN, 263 + LTC4245_12VOUT, LTC4245_5VOUT, LTC4245_3VOUT, LTC4245_VEEOUT, 264 + }; 265 + 266 + /* Map from current channel index to current register */ 267 + 268 + static const s8 ltc4245_curr_regs[] = { 269 + LTC4245_12VSENSE, LTC4245_5VSENSE, LTC4245_3VSENSE, LTC4245_VEESENSE, 270 + }; 271 + 272 + static int ltc4245_read_curr(struct device *dev, u32 attr, int channel, 273 + long *val) 261 274 { 262 - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 263 - const int voltage = ltc4245_get_voltage(dev, attr->index); 264 - 265 - return snprintf(buf, PAGE_SIZE, "%d\n", voltage); 266 - } 267 - 268 - static ssize_t ltc4245_show_current(struct device *dev, 269 - struct device_attribute *da, 270 - char *buf) 271 - { 272 - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 273 - const unsigned int curr = ltc4245_get_current(dev, attr->index); 274 - 275 - return snprintf(buf, PAGE_SIZE, "%u\n", curr); 276 - } 277 - 278 - static ssize_t ltc4245_show_power(struct device *dev, 279 - struct device_attribute *da, 280 - char *buf) 281 - { 282 - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 283 - const unsigned int curr = ltc4245_get_current(dev, attr->index); 284 - const int output_voltage = ltc4245_get_voltage(dev, attr->index+1); 285 - 286 - /* current in mA * voltage in mV == power in uW */ 287 - const unsigned int power = abs(output_voltage * curr); 288 - 289 - return snprintf(buf, PAGE_SIZE, "%u\n", power); 290 - } 291 - 292 - static ssize_t ltc4245_show_alarm(struct device *dev, 293 - struct device_attribute *da, 294 - char *buf) 295 - { 296 - struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(da); 297 275 struct ltc4245_data *data = ltc4245_update_device(dev); 298 - const u8 reg = data->cregs[attr->index]; 299 - const u32 mask = attr->nr; 300 276 301 - return snprintf(buf, PAGE_SIZE, "%u\n", (reg & mask) ? 1 : 0); 277 + switch (attr) { 278 + case hwmon_curr_input: 279 + *val = ltc4245_get_current(dev, ltc4245_curr_regs[channel]); 280 + return 0; 281 + case hwmon_curr_max_alarm: 282 + *val = !!(data->cregs[LTC4245_FAULT1] & BIT(channel + 4)); 283 + return 0; 284 + default: 285 + return -EOPNOTSUPP; 286 + } 302 287 } 303 288 304 - static ssize_t ltc4245_show_gpio(struct device *dev, 305 - struct device_attribute *da, 306 - char *buf) 289 + static int ltc4245_read_in(struct device *dev, u32 attr, int channel, long *val) 307 290 { 308 - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 309 291 struct ltc4245_data *data = ltc4245_update_device(dev); 310 - int val = data->gpios[attr->index]; 311 292 312 - /* handle stale GPIO's */ 313 - if (val < 0) 314 - return val; 293 + switch (attr) { 294 + case hwmon_in_input: 295 + if (channel < 8) { 296 + *val = ltc4245_get_voltage(dev, 297 + ltc4245_in_regs[channel]); 298 + } else { 299 + int regval = data->gpios[channel - 8]; 315 300 316 - /* Convert to millivolts and print */ 317 - return snprintf(buf, PAGE_SIZE, "%u\n", val * 10); 301 + if (regval < 0) 302 + return regval; 303 + *val = regval * 10; 304 + } 305 + return 0; 306 + case hwmon_in_min_alarm: 307 + if (channel < 4) 308 + *val = !!(data->cregs[LTC4245_FAULT1] & BIT(channel)); 309 + else 310 + *val = !!(data->cregs[LTC4245_FAULT2] & 311 + BIT(channel - 4)); 312 + return 0; 313 + default: 314 + return -EOPNOTSUPP; 315 + } 318 316 } 319 317 320 - /* Construct a sensor_device_attribute structure for each register */ 321 - 322 - /* Input voltages */ 323 - static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ltc4245_show_voltage, NULL, 324 - LTC4245_12VIN); 325 - static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, ltc4245_show_voltage, NULL, 326 - LTC4245_5VIN); 327 - static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, ltc4245_show_voltage, NULL, 328 - LTC4245_3VIN); 329 - static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, ltc4245_show_voltage, NULL, 330 - LTC4245_VEEIN); 331 - 332 - /* Input undervoltage alarms */ 333 - static SENSOR_DEVICE_ATTR_2(in1_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, 334 - 1 << 0, LTC4245_FAULT1); 335 - static SENSOR_DEVICE_ATTR_2(in2_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, 336 - 1 << 1, LTC4245_FAULT1); 337 - static SENSOR_DEVICE_ATTR_2(in3_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, 338 - 1 << 2, LTC4245_FAULT1); 339 - static SENSOR_DEVICE_ATTR_2(in4_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, 340 - 1 << 3, LTC4245_FAULT1); 341 - 342 - /* Currents (via sense resistor) */ 343 - static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ltc4245_show_current, NULL, 344 - LTC4245_12VSENSE); 345 - static SENSOR_DEVICE_ATTR(curr2_input, S_IRUGO, ltc4245_show_current, NULL, 346 - LTC4245_5VSENSE); 347 - static SENSOR_DEVICE_ATTR(curr3_input, S_IRUGO, ltc4245_show_current, NULL, 348 - LTC4245_3VSENSE); 349 - static SENSOR_DEVICE_ATTR(curr4_input, S_IRUGO, ltc4245_show_current, NULL, 350 - LTC4245_VEESENSE); 351 - 352 - /* Overcurrent alarms */ 353 - static SENSOR_DEVICE_ATTR_2(curr1_max_alarm, S_IRUGO, ltc4245_show_alarm, NULL, 354 - 1 << 4, LTC4245_FAULT1); 355 - static SENSOR_DEVICE_ATTR_2(curr2_max_alarm, S_IRUGO, ltc4245_show_alarm, NULL, 356 - 1 << 5, LTC4245_FAULT1); 357 - static SENSOR_DEVICE_ATTR_2(curr3_max_alarm, S_IRUGO, ltc4245_show_alarm, NULL, 358 - 1 << 6, LTC4245_FAULT1); 359 - static SENSOR_DEVICE_ATTR_2(curr4_max_alarm, S_IRUGO, ltc4245_show_alarm, NULL, 360 - 1 << 7, LTC4245_FAULT1); 361 - 362 - /* Output voltages */ 363 - static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, ltc4245_show_voltage, NULL, 364 - LTC4245_12VOUT); 365 - static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, ltc4245_show_voltage, NULL, 366 - LTC4245_5VOUT); 367 - static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, ltc4245_show_voltage, NULL, 368 - LTC4245_3VOUT); 369 - static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, ltc4245_show_voltage, NULL, 370 - LTC4245_VEEOUT); 371 - 372 - /* Power Bad alarms */ 373 - static SENSOR_DEVICE_ATTR_2(in5_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, 374 - 1 << 0, LTC4245_FAULT2); 375 - static SENSOR_DEVICE_ATTR_2(in6_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, 376 - 1 << 1, LTC4245_FAULT2); 377 - static SENSOR_DEVICE_ATTR_2(in7_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, 378 - 1 << 2, LTC4245_FAULT2); 379 - static SENSOR_DEVICE_ATTR_2(in8_min_alarm, S_IRUGO, ltc4245_show_alarm, NULL, 380 - 1 << 3, LTC4245_FAULT2); 381 - 382 - /* GPIO voltages */ 383 - static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, ltc4245_show_gpio, NULL, 0); 384 - static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, ltc4245_show_gpio, NULL, 1); 385 - static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, ltc4245_show_gpio, NULL, 2); 386 - 387 - /* Power Consumption (virtual) */ 388 - static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ltc4245_show_power, NULL, 389 - LTC4245_12VSENSE); 390 - static SENSOR_DEVICE_ATTR(power2_input, S_IRUGO, ltc4245_show_power, NULL, 391 - LTC4245_5VSENSE); 392 - static SENSOR_DEVICE_ATTR(power3_input, S_IRUGO, ltc4245_show_power, NULL, 393 - LTC4245_3VSENSE); 394 - static SENSOR_DEVICE_ATTR(power4_input, S_IRUGO, ltc4245_show_power, NULL, 395 - LTC4245_VEESENSE); 396 - 397 - /* 398 - * Finally, construct an array of pointers to members of the above objects, 399 - * as required for sysfs_create_group() 400 - */ 401 - static struct attribute *ltc4245_std_attributes[] = { 402 - &sensor_dev_attr_in1_input.dev_attr.attr, 403 - &sensor_dev_attr_in2_input.dev_attr.attr, 404 - &sensor_dev_attr_in3_input.dev_attr.attr, 405 - &sensor_dev_attr_in4_input.dev_attr.attr, 406 - 407 - &sensor_dev_attr_in1_min_alarm.dev_attr.attr, 408 - &sensor_dev_attr_in2_min_alarm.dev_attr.attr, 409 - &sensor_dev_attr_in3_min_alarm.dev_attr.attr, 410 - &sensor_dev_attr_in4_min_alarm.dev_attr.attr, 411 - 412 - &sensor_dev_attr_curr1_input.dev_attr.attr, 413 - &sensor_dev_attr_curr2_input.dev_attr.attr, 414 - &sensor_dev_attr_curr3_input.dev_attr.attr, 415 - &sensor_dev_attr_curr4_input.dev_attr.attr, 416 - 417 - &sensor_dev_attr_curr1_max_alarm.dev_attr.attr, 418 - &sensor_dev_attr_curr2_max_alarm.dev_attr.attr, 419 - &sensor_dev_attr_curr3_max_alarm.dev_attr.attr, 420 - &sensor_dev_attr_curr4_max_alarm.dev_attr.attr, 421 - 422 - &sensor_dev_attr_in5_input.dev_attr.attr, 423 - &sensor_dev_attr_in6_input.dev_attr.attr, 424 - &sensor_dev_attr_in7_input.dev_attr.attr, 425 - &sensor_dev_attr_in8_input.dev_attr.attr, 426 - 427 - &sensor_dev_attr_in5_min_alarm.dev_attr.attr, 428 - &sensor_dev_attr_in6_min_alarm.dev_attr.attr, 429 - &sensor_dev_attr_in7_min_alarm.dev_attr.attr, 430 - &sensor_dev_attr_in8_min_alarm.dev_attr.attr, 431 - 432 - &sensor_dev_attr_in9_input.dev_attr.attr, 433 - 434 - &sensor_dev_attr_power1_input.dev_attr.attr, 435 - &sensor_dev_attr_power2_input.dev_attr.attr, 436 - &sensor_dev_attr_power3_input.dev_attr.attr, 437 - &sensor_dev_attr_power4_input.dev_attr.attr, 438 - 439 - NULL, 440 - }; 441 - 442 - static struct attribute *ltc4245_gpio_attributes[] = { 443 - &sensor_dev_attr_in10_input.dev_attr.attr, 444 - &sensor_dev_attr_in11_input.dev_attr.attr, 445 - NULL, 446 - }; 447 - 448 - static const struct attribute_group ltc4245_std_group = { 449 - .attrs = ltc4245_std_attributes, 450 - }; 451 - 452 - static const struct attribute_group ltc4245_gpio_group = { 453 - .attrs = ltc4245_gpio_attributes, 454 - }; 455 - 456 - static void ltc4245_sysfs_add_groups(struct ltc4245_data *data) 318 + static int ltc4245_read_power(struct device *dev, u32 attr, int channel, 319 + long *val) 457 320 { 458 - /* standard sysfs attributes */ 459 - data->groups[0] = &ltc4245_std_group; 321 + unsigned long curr; 322 + long voltage; 460 323 461 - /* if we're using the extra gpio support, register it's attributes */ 462 - if (data->use_extra_gpios) 463 - data->groups[1] = &ltc4245_gpio_group; 324 + switch (attr) { 325 + case hwmon_power_input: 326 + (void)ltc4245_update_device(dev); 327 + curr = ltc4245_get_current(dev, ltc4245_curr_regs[channel]); 328 + voltage = ltc4245_get_voltage(dev, ltc4245_in_regs[channel]); 329 + *val = abs(curr * voltage); 330 + return 0; 331 + default: 332 + return -EOPNOTSUPP; 333 + } 464 334 } 335 + 336 + static int ltc4245_read(struct device *dev, enum hwmon_sensor_types type, 337 + u32 attr, int channel, long *val) 338 + { 339 + 340 + switch (type) { 341 + case hwmon_curr: 342 + return ltc4245_read_curr(dev, attr, channel, val); 343 + case hwmon_power: 344 + return ltc4245_read_power(dev, attr, channel, val); 345 + case hwmon_in: 346 + return ltc4245_read_in(dev, attr, channel - 1, val); 347 + default: 348 + return -EOPNOTSUPP; 349 + } 350 + } 351 + 352 + static umode_t ltc4245_is_visible(const void *_data, 353 + enum hwmon_sensor_types type, 354 + u32 attr, int channel) 355 + { 356 + const struct ltc4245_data *data = _data; 357 + 358 + switch (type) { 359 + case hwmon_in: 360 + if (channel == 0) 361 + return 0; 362 + switch (attr) { 363 + case hwmon_in_input: 364 + if (channel > 9 && !data->use_extra_gpios) 365 + return 0; 366 + return S_IRUGO; 367 + case hwmon_in_min_alarm: 368 + if (channel > 8) 369 + return 0; 370 + return S_IRUGO; 371 + default: 372 + return 0; 373 + } 374 + case hwmon_curr: 375 + switch (attr) { 376 + case hwmon_curr_input: 377 + case hwmon_curr_max_alarm: 378 + return S_IRUGO; 379 + default: 380 + return 0; 381 + } 382 + case hwmon_power: 383 + switch (attr) { 384 + case hwmon_power_input: 385 + return S_IRUGO; 386 + default: 387 + return 0; 388 + } 389 + default: 390 + return 0; 391 + } 392 + } 393 + 394 + static const u32 ltc4245_in_config[] = { 395 + HWMON_I_INPUT, /* dummy, skipped in is_visible */ 396 + HWMON_I_INPUT | HWMON_I_MIN_ALARM, 397 + HWMON_I_INPUT | HWMON_I_MIN_ALARM, 398 + HWMON_I_INPUT | HWMON_I_MIN_ALARM, 399 + HWMON_I_INPUT | HWMON_I_MIN_ALARM, 400 + HWMON_I_INPUT | HWMON_I_MIN_ALARM, 401 + HWMON_I_INPUT | HWMON_I_MIN_ALARM, 402 + HWMON_I_INPUT | HWMON_I_MIN_ALARM, 403 + HWMON_I_INPUT | HWMON_I_MIN_ALARM, 404 + HWMON_I_INPUT, 405 + HWMON_I_INPUT, 406 + HWMON_I_INPUT, 407 + 0 408 + }; 409 + 410 + static const struct hwmon_channel_info ltc4245_in = { 411 + .type = hwmon_in, 412 + .config = ltc4245_in_config, 413 + }; 414 + 415 + static const u32 ltc4245_curr_config[] = { 416 + HWMON_C_INPUT | HWMON_C_MAX_ALARM, 417 + HWMON_C_INPUT | HWMON_C_MAX_ALARM, 418 + HWMON_C_INPUT | HWMON_C_MAX_ALARM, 419 + HWMON_C_INPUT | HWMON_C_MAX_ALARM, 420 + 0 421 + }; 422 + 423 + static const struct hwmon_channel_info ltc4245_curr = { 424 + .type = hwmon_curr, 425 + .config = ltc4245_curr_config, 426 + }; 427 + 428 + static const u32 ltc4245_power_config[] = { 429 + HWMON_P_INPUT, 430 + HWMON_P_INPUT, 431 + HWMON_P_INPUT, 432 + HWMON_P_INPUT, 433 + 0 434 + }; 435 + 436 + static const struct hwmon_channel_info ltc4245_power = { 437 + .type = hwmon_power, 438 + .config = ltc4245_power_config, 439 + }; 440 + 441 + static const struct hwmon_channel_info *ltc4245_info[] = { 442 + &ltc4245_in, 443 + &ltc4245_curr, 444 + &ltc4245_power, 445 + NULL 446 + }; 447 + 448 + static const struct hwmon_ops ltc4245_hwmon_ops = { 449 + .is_visible = ltc4245_is_visible, 450 + .read = ltc4245_read, 451 + }; 452 + 453 + static const struct hwmon_chip_info ltc4245_chip_info = { 454 + .ops = &ltc4245_hwmon_ops, 455 + .info = ltc4245_info, 456 + }; 465 457 466 458 static bool ltc4245_use_extra_gpios(struct i2c_client *client) 467 459 { ··· 492 502 i2c_smbus_write_byte_data(client, LTC4245_FAULT1, 0x00); 493 503 i2c_smbus_write_byte_data(client, LTC4245_FAULT2, 0x00); 494 504 495 - /* Add sysfs hooks */ 496 - ltc4245_sysfs_add_groups(data); 497 - 498 - hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev, 499 - client->name, data, 500 - data->groups); 505 + hwmon_dev = devm_hwmon_device_register_with_info(&client->dev, 506 + client->name, data, 507 + &ltc4245_chip_info, 508 + NULL); 501 509 return PTR_ERR_OR_ZERO(hwmon_dev); 502 510 } 503 511