diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-04 11:48:27 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-04 11:48:27 -0700 |
commit | 24d734a2ba5133f55feb7f7df7530d4f5aa6518f (patch) | |
tree | e20d9cec46cb3f55f6ab0cc23bf13dd3ab3ff76c /drivers/hwmon/scpi-hwmon.c | |
parent | 17ece345a042347224e50032e959ad3959638b21 (diff) | |
parent | 44b413661b57cbbb7e4c3adf7b087fada42a443e (diff) |
Merge tag 'hwmon-for-linus-v4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging
Pull hwmon updates from Guenter Roeck:
- Add PMBus client driver for IR35221
- Add support for NCT6795D to nct6775 driver
- Functional improvements to adt7475, aspeed-pwm-tacho, and ibmpowernv
drivers
- Minor fixes and cleanups in various drivers
* tag 'hwmon-for-linus-v4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: (22 commits)
hwmon: (aspeed-pwm-tacho) Poll with short sleeps.
hwmon: (aspeed-pwm-tacho) reduce fan_tach period
hwmon: (ibmpowernv) Add current(A) sensor
hwmon: (ibmpowernv) introduce a legacy_compatibles array
hwmon: (pwm-fan) Switch to new atomic PWM API
hwmon: (scpi) Fix the scale of SCP sensor readings
hwmon: (aspeed-pwm-tacho) Enable both edge measurement.
hwmon: (ibmpowernv) Add highest/lowest attributes to sensors
hwmon: (pmbus) move header file out of I2C realm
hwmon: (max6639) move header file out of I2C realm
hwmon: (ltc4245) move header file out of I2C realm
hwmon: (ds620) move header file out of I2C realm
hwmon: (ads1015) move header file out of I2C realm
hwmon: (adt7475) temperature smoothing
hwmon: (adt7475) add high frequency support
hwmon: (adt7475) fan stall prevention
hwmon: (adt7475) replace find_nearest() with find_closest()
hwmon: (pmbus) Add client driver for IR35221
hwmon: (nct6775) Add support for NCT6795D
hwmon: (nct6775) Improve fan detection
...
Diffstat (limited to 'drivers/hwmon/scpi-hwmon.c')
-rw-r--r-- | drivers/hwmon/scpi-hwmon.c | 54 |
1 files changed, 48 insertions, 6 deletions
diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c index 094f948f99ff..a586480a7ca9 100644 --- a/drivers/hwmon/scpi-hwmon.c +++ b/drivers/hwmon/scpi-hwmon.c @@ -16,6 +16,7 @@ #include <linux/hwmon.h> #include <linux/module.h> +#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/scpi_protocol.h> #include <linux/slab.h> @@ -23,6 +24,7 @@ #include <linux/thermal.h> struct sensor_data { + unsigned int scale; struct scpi_sensor_info info; struct device_attribute dev_attr_input; struct device_attribute dev_attr_label; @@ -44,6 +46,30 @@ struct scpi_sensors { const struct attribute_group *groups[2]; }; +static const u32 gxbb_scpi_scale[] = { + [TEMPERATURE] = 1, /* (celsius) */ + [VOLTAGE] = 1000, /* (millivolts) */ + [CURRENT] = 1000, /* (milliamperes) */ + [POWER] = 1000000, /* (microwatts) */ + [ENERGY] = 1000000, /* (microjoules) */ +}; + +static const u32 scpi_scale[] = { + [TEMPERATURE] = 1000, /* (millicelsius) */ + [VOLTAGE] = 1000, /* (millivolts) */ + [CURRENT] = 1000, /* (milliamperes) */ + [POWER] = 1000000, /* (microwatts) */ + [ENERGY] = 1000000, /* (microjoules) */ +}; + +static void scpi_scale_reading(u64 *value, struct sensor_data *sensor) +{ + if (scpi_scale[sensor->info.class] != sensor->scale) { + *value *= scpi_scale[sensor->info.class]; + do_div(*value, sensor->scale); + } +} + static int scpi_read_temp(void *dev, int *temp) { struct scpi_thermal_zone *zone = dev; @@ -57,6 +83,8 @@ static int scpi_read_temp(void *dev, int *temp) if (ret) return ret; + scpi_scale_reading(&value, sensor); + *temp = value; return 0; } @@ -77,6 +105,8 @@ scpi_show_sensor(struct device *dev, struct device_attribute *attr, char *buf) if (ret) return ret; + scpi_scale_reading(&value, sensor); + return sprintf(buf, "%llu\n", value); } @@ -94,14 +124,23 @@ static struct thermal_zone_of_device_ops scpi_sensor_ops = { .get_temp = scpi_read_temp, }; +static const struct of_device_id scpi_of_match[] = { + {.compatible = "arm,scpi-sensors", .data = &scpi_scale}, + {.compatible = "amlogic,meson-gxbb-scpi-sensors", .data = &gxbb_scpi_scale}, + {}, +}; +MODULE_DEVICE_TABLE(of, scpi_of_match); + static int scpi_hwmon_probe(struct platform_device *pdev) { u16 nr_sensors, i; + const u32 *scale; int num_temp = 0, num_volt = 0, num_current = 0, num_power = 0; int num_energy = 0; struct scpi_ops *scpi_ops; struct device *hwdev, *dev = &pdev->dev; struct scpi_sensors *scpi_sensors; + const struct of_device_id *of_id; int idx, ret; scpi_ops = get_scpi_ops(); @@ -131,6 +170,13 @@ static int scpi_hwmon_probe(struct platform_device *pdev) scpi_sensors->scpi_ops = scpi_ops; + of_id = of_match_device(scpi_of_match, &pdev->dev); + if (!of_id) { + dev_err(&pdev->dev, "Unable to initialize scpi-hwmon data\n"); + return -ENODEV; + } + scale = of_id->data; + for (i = 0, idx = 0; i < nr_sensors; i++) { struct sensor_data *sensor = &scpi_sensors->data[idx]; @@ -178,6 +224,8 @@ static int scpi_hwmon_probe(struct platform_device *pdev) continue; } + sensor->scale = scale[sensor->info.class]; + sensor->dev_attr_input.attr.mode = S_IRUGO; sensor->dev_attr_input.show = scpi_show_sensor; sensor->dev_attr_input.attr.name = sensor->input; @@ -247,12 +295,6 @@ static int scpi_hwmon_probe(struct platform_device *pdev) return 0; } -static const struct of_device_id scpi_of_match[] = { - {.compatible = "arm,scpi-sensors"}, - {}, -}; -MODULE_DEVICE_TABLE(of, scpi_of_match); - static struct platform_driver scpi_hwmon_platdrv = { .driver = { .name = "scpi-hwmon", |