Skip to content

Commit

Permalink
Merge tag 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/groeck/linux-staging

Pull hwmon updates from Guenter Roeck:
 "New driver for INA219 and INA226, added support for IT8782F and
  IT8783E/F to it87 driver, plus cleanups in a couple of drivers."

* tag 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging:
  hwmon: (it87) Make temp3 attribute conditional for IT8782F
  hwmon: (it87) Convert to use devm_kzalloc and devm_request_region
  hwmon: INA219 and INA226 support
  hwmon: (it87) Create voltage attributes only if voltage is enabled
  hwmon: (ntc_thermistor) Fix checkpatch warning
  hwmon: (ntc_thermistor) Optimize and fix build warning
  hwmon: (ntc_thermistor) Return error code from hwmon_device_register
  hwmon: (ntc_thermistor) Convert to devm_kzalloc
  hwmon: (ad7314) Remove unused defines, and rename OFFSET to SHIFT
  acpi_power_meter: clean up code around setup_attrs
  acpi_power_meter: drop meter_rw_attrs, use common meter_attrs
  acpi_power_meter: remove duplicate code between register_{ro,rw}_attrs
  acpi_power_meter: use a {RW,RO}_SENSOR_TEMPLATE macro to clean things up
  acpi_power_meter: use the same struct {rw,ro}_sensor_template for both
  hwmon: use module_pci_driver
  hwmon: (it87) Add support for IT8782F and IT8783E/F
  • Loading branch information
Linus Torvalds committed May 23, 2012
2 parents 468f4d1 + 4573acb commit 1259f6e
Show file tree
Hide file tree
Showing 13 changed files with 902 additions and 347 deletions.
29 changes: 29 additions & 0 deletions Documentation/hwmon/ina2xx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Kernel driver ina2xx
====================

Supported chips:
* Texas Instruments INA219
Prefix: 'ina219'
Addresses: I2C 0x40 - 0x4f
Datasheet: Publicly available at the Texas Instruments website
http://www.ti.com/

* Texas Instruments INA226
Prefix: 'ina226'
Addresses: I2C 0x40 - 0x4f
Datasheet: Publicly available at the Texas Instruments website
http://www.ti.com/

Author: Lothar Felten <l-felten@ti.com>

Description
-----------

The INA219 is a high-side current shunt and power monitor with an I2C
interface. The INA219 monitors both shunt drop and supply voltage, with
programmable conversion times and filtering.

The INA226 is a current shunt and power monitor with an I2C interface.
The INA226 monitors both a shunt voltage drop and bus supply voltage.

The shunt value in micro-ohms can be set via platform data.
28 changes: 19 additions & 9 deletions Documentation/hwmon/it87
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ Supported chips:
Prefix: 'it8728'
Addresses scanned: from Super I/O config space (8 I/O ports)
Datasheet: Not publicly available
* IT8782F
Prefix: 'it8782'
Addresses scanned: from Super I/O config space (8 I/O ports)
Datasheet: Not publicly available
* IT8783E/F
Prefix: 'it8783'
Addresses scanned: from Super I/O config space (8 I/O ports)
Datasheet: Not publicly available
* SiS950 [clone of IT8705F]
Prefix: 'it87'
Addresses scanned: from Super I/O config space (8 I/O ports)
Expand Down Expand Up @@ -75,7 +83,8 @@ Description
-----------

This driver implements support for the IT8705F, IT8712F, IT8716F,
IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E and SiS950 chips.
IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E, IT8781F, IT8782F,
IT8783E/F, and SiS950 chips.

These chips are 'Super I/O chips', supporting floppy disks, infrared ports,
joysticks and other miscellaneous stuff. For hardware monitoring, they
Expand All @@ -99,11 +108,11 @@ The IT8716F, IT8718F, IT8720F, IT8721F/IT8758E and later IT8712F revisions
have support for 2 additional fans. The additional fans are supported by the
driver.

The IT8716F, IT8718F, IT8720F and IT8721F/IT8758E, and late IT8712F and
IT8705F also have optional 16-bit tachometer counters for fans 1 to 3. This
is better (no more fan clock divider mess) but not compatible with the older
chips and revisions. The 16-bit tachometer mode is enabled by the driver when
one of the above chips is detected.
The IT8716F, IT8718F, IT8720F, IT8721F/IT8758E, IT8782F, IT8783E/F, and late
IT8712F and IT8705F also have optional 16-bit tachometer counters for fans 1 to
3. This is better (no more fan clock divider mess) but not compatible with the
older chips and revisions. The 16-bit tachometer mode is enabled by the driver
when one of the above chips is detected.

The IT8726F is just bit enhanced IT8716F with additional hardware
for AMD power sequencing. Therefore the chip will appear as IT8716F
Expand Down Expand Up @@ -131,9 +140,10 @@ inputs can measure voltages between 0 and 4.08 volts, with a resolution of
0.016 volt (except IT8721F/IT8758E and IT8728F: 0.012 volt.) The battery
voltage in8 does not have limit registers.

On the IT8721F/IT8758E, some voltage inputs are internal and scaled inside
the chip (in7, in8 and optionally in3). The driver handles this transparently
so user-space doesn't have to care.
On the IT8721F/IT8758E, IT8782F, and IT8783E/F, some voltage inputs are
internal and scaled inside the chip (in7 (optional for IT8782F and IT8783E/F),
in8 and optionally in3). The driver handles this transparently so user-space
doesn't have to care.

The VID lines (IT8712F/IT8716F/IT8718F/IT8720F) encode the core voltage value:
the voltage level your processor should work with. This is hardcoded by
Expand Down
13 changes: 13 additions & 0 deletions drivers/hwmon/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1102,6 +1102,19 @@ config SENSORS_AMC6821
This driver can also be build as a module. If so, the module
will be called amc6821.

config SENSORS_INA2XX
tristate "Texas Instruments INA219, INA226"
depends on I2C && EXPERIMENTAL
help
If you say yes here you get support for INA219 and INA226 power
monitor chips.

The INA2xx driver is configured for the default configuration of
the part as described in the datasheet.
Default value for Rshunt is 10 mOhms.
This driver can also be built as a module. If so, the module
will be called ina2xx.

config SENSORS_THMC50
tristate "Texas Instruments THMC50 / Analog Devices ADM1022"
depends on I2C
Expand Down
1 change: 1 addition & 0 deletions drivers/hwmon/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o
obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o
obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o
obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o
obj-$(CONFIG_SENSORS_INA2XX) += ina2xx.o
obj-$(CONFIG_SENSORS_IT87) += it87.o
obj-$(CONFIG_SENSORS_JC42) += jc42.o
obj-$(CONFIG_SENSORS_JZ4740) += jz4740-hwmon.o
Expand Down
166 changes: 72 additions & 94 deletions drivers/hwmon/acpi_power_meter.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,7 @@ struct acpi_power_meter_resource {
struct kobject *holders_dir;
};

struct ro_sensor_template {
char *label;
ssize_t (*show)(struct device *dev,
struct device_attribute *devattr,
char *buf);
int index;
};

struct rw_sensor_template {
struct sensor_template {
char *label;
ssize_t (*show)(struct device *dev,
struct device_attribute *devattr,
Expand Down Expand Up @@ -469,52 +461,67 @@ static ssize_t show_name(struct device *dev,
return sprintf(buf, "%s\n", ACPI_POWER_METER_NAME);
}

#define RO_SENSOR_TEMPLATE(_label, _show, _index) \
{ \
.label = _label, \
.show = _show, \
.index = _index, \
}

#define RW_SENSOR_TEMPLATE(_label, _show, _set, _index) \
{ \
.label = _label, \
.show = _show, \
.set = _set, \
.index = _index, \
}

/* Sensor descriptions. If you add a sensor, update NUM_SENSORS above! */
static struct ro_sensor_template meter_ro_attrs[] = {
{POWER_AVERAGE_NAME, show_power, 0},
{"power1_accuracy", show_accuracy, 0},
{"power1_average_interval_min", show_val, 0},
{"power1_average_interval_max", show_val, 1},
{"power1_is_battery", show_val, 5},
{NULL, NULL, 0},
static struct sensor_template meter_attrs[] = {
RO_SENSOR_TEMPLATE(POWER_AVERAGE_NAME, show_power, 0),
RO_SENSOR_TEMPLATE("power1_accuracy", show_accuracy, 0),
RO_SENSOR_TEMPLATE("power1_average_interval_min", show_val, 0),
RO_SENSOR_TEMPLATE("power1_average_interval_max", show_val, 1),
RO_SENSOR_TEMPLATE("power1_is_battery", show_val, 5),
RW_SENSOR_TEMPLATE(POWER_AVG_INTERVAL_NAME, show_avg_interval,
set_avg_interval, 0),
{},
};

static struct rw_sensor_template meter_rw_attrs[] = {
{POWER_AVG_INTERVAL_NAME, show_avg_interval, set_avg_interval, 0},
{NULL, NULL, NULL, 0},
static struct sensor_template misc_cap_attrs[] = {
RO_SENSOR_TEMPLATE("power1_cap_min", show_val, 2),
RO_SENSOR_TEMPLATE("power1_cap_max", show_val, 3),
RO_SENSOR_TEMPLATE("power1_cap_hyst", show_val, 4),
RO_SENSOR_TEMPLATE(POWER_ALARM_NAME, show_val, 6),
{},
};

static struct ro_sensor_template misc_cap_attrs[] = {
{"power1_cap_min", show_val, 2},
{"power1_cap_max", show_val, 3},
{"power1_cap_hyst", show_val, 4},
{POWER_ALARM_NAME, show_val, 6},
{NULL, NULL, 0},
static struct sensor_template ro_cap_attrs[] = {
RO_SENSOR_TEMPLATE(POWER_CAP_NAME, show_cap, 0),
{},
};

static struct ro_sensor_template ro_cap_attrs[] = {
{POWER_CAP_NAME, show_cap, 0},
{NULL, NULL, 0},
static struct sensor_template rw_cap_attrs[] = {
RW_SENSOR_TEMPLATE(POWER_CAP_NAME, show_cap, set_cap, 0),
{},
};

static struct rw_sensor_template rw_cap_attrs[] = {
{POWER_CAP_NAME, show_cap, set_cap, 0},
{NULL, NULL, NULL, 0},
static struct sensor_template trip_attrs[] = {
RW_SENSOR_TEMPLATE("power1_average_min", show_val, set_trip, 7),
RW_SENSOR_TEMPLATE("power1_average_max", show_val, set_trip, 8),
{},
};

static struct rw_sensor_template trip_attrs[] = {
{"power1_average_min", show_val, set_trip, 7},
{"power1_average_max", show_val, set_trip, 8},
{NULL, NULL, NULL, 0},
static struct sensor_template misc_attrs[] = {
RO_SENSOR_TEMPLATE("name", show_name, 0),
RO_SENSOR_TEMPLATE("power1_model_number", show_str, 0),
RO_SENSOR_TEMPLATE("power1_oem_info", show_str, 2),
RO_SENSOR_TEMPLATE("power1_serial_number", show_str, 1),
{},
};

static struct ro_sensor_template misc_attrs[] = {
{"name", show_name, 0},
{"power1_model_number", show_str, 0},
{"power1_oem_info", show_str, 2},
{"power1_serial_number", show_str, 1},
{NULL, NULL, 0},
};
#undef RO_SENSOR_TEMPLATE
#undef RW_SENSOR_TEMPLATE

/* Read power domain data */
static void remove_domain_devices(struct acpi_power_meter_resource *resource)
Expand Down Expand Up @@ -619,49 +626,24 @@ static int read_domain_devices(struct acpi_power_meter_resource *resource)
}

/* Registration and deregistration */
static int register_ro_attrs(struct acpi_power_meter_resource *resource,
struct ro_sensor_template *ro)
static int register_attrs(struct acpi_power_meter_resource *resource,
struct sensor_template *attrs)
{
struct device *dev = &resource->acpi_dev->dev;
struct sensor_device_attribute *sensors =
&resource->sensors[resource->num_sensors];
int res = 0;

while (ro->label) {
sensors->dev_attr.attr.name = ro->label;
while (attrs->label) {
sensors->dev_attr.attr.name = attrs->label;
sensors->dev_attr.attr.mode = S_IRUGO;
sensors->dev_attr.show = ro->show;
sensors->index = ro->index;
sensors->dev_attr.show = attrs->show;
sensors->index = attrs->index;

sysfs_attr_init(&sensors->dev_attr.attr);
res = device_create_file(dev, &sensors->dev_attr);
if (res) {
sensors->dev_attr.attr.name = NULL;
goto error;
if (attrs->set) {
sensors->dev_attr.attr.mode |= S_IWUSR;
sensors->dev_attr.store = attrs->set;
}
sensors++;
resource->num_sensors++;
ro++;
}

error:
return res;
}

static int register_rw_attrs(struct acpi_power_meter_resource *resource,
struct rw_sensor_template *rw)
{
struct device *dev = &resource->acpi_dev->dev;
struct sensor_device_attribute *sensors =
&resource->sensors[resource->num_sensors];
int res = 0;

while (rw->label) {
sensors->dev_attr.attr.name = rw->label;
sensors->dev_attr.attr.mode = S_IRUGO | S_IWUSR;
sensors->dev_attr.show = rw->show;
sensors->dev_attr.store = rw->set;
sensors->index = rw->index;

sysfs_attr_init(&sensors->dev_attr.attr);
res = device_create_file(dev, &sensors->dev_attr);
Expand All @@ -671,7 +653,7 @@ static int register_rw_attrs(struct acpi_power_meter_resource *resource,
}
sensors++;
resource->num_sensors++;
rw++;
attrs++;
}

error:
Expand Down Expand Up @@ -703,10 +685,7 @@ static int setup_attrs(struct acpi_power_meter_resource *resource)
return res;

if (resource->caps.flags & POWER_METER_CAN_MEASURE) {
res = register_ro_attrs(resource, meter_ro_attrs);
if (res)
goto error;
res = register_rw_attrs(resource, meter_rw_attrs);
res = register_attrs(resource, meter_attrs);
if (res)
goto error;
}
Expand All @@ -718,28 +697,27 @@ static int setup_attrs(struct acpi_power_meter_resource *resource)
goto skip_unsafe_cap;
}

if (resource->caps.configurable_cap) {
res = register_rw_attrs(resource, rw_cap_attrs);
if (res)
goto error;
} else {
res = register_ro_attrs(resource, ro_cap_attrs);
if (res)
goto error;
}
res = register_ro_attrs(resource, misc_cap_attrs);
if (resource->caps.configurable_cap)
res = register_attrs(resource, rw_cap_attrs);
else
res = register_attrs(resource, ro_cap_attrs);

if (res)
goto error;

res = register_attrs(resource, misc_cap_attrs);
if (res)
goto error;
}
skip_unsafe_cap:

skip_unsafe_cap:
if (resource->caps.flags & POWER_METER_CAN_TRIP) {
res = register_rw_attrs(resource, trip_attrs);
res = register_attrs(resource, trip_attrs);
if (res)
goto error;
}

res = register_ro_attrs(resource, misc_attrs);
res = register_attrs(resource, misc_attrs);
if (res)
goto error;

Expand Down
11 changes: 2 additions & 9 deletions drivers/hwmon/ad7314.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,15 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>

/*
* AD7314 power mode
*/
#define AD7314_PD 0x2000

/*
* AD7314 temperature masks
*/
#define AD7314_TEMP_SIGN 0x200
#define AD7314_TEMP_MASK 0x7FE0
#define AD7314_TEMP_OFFSET 5
#define AD7314_TEMP_SHIFT 5

/*
* ADT7301 and ADT7302 temperature masks
*/
#define ADT7301_TEMP_SIGN 0x2000
#define ADT7301_TEMP_MASK 0x3FFF

enum ad7314_variant {
Expand Down Expand Up @@ -73,7 +66,7 @@ static ssize_t ad7314_show_temperature(struct device *dev,
return ret;
switch (spi_get_device_id(chip->spi_dev)->driver_data) {
case ad7314:
data = (ret & AD7314_TEMP_MASK) >> AD7314_TEMP_OFFSET;
data = (ret & AD7314_TEMP_MASK) >> AD7314_TEMP_SHIFT;
data = (data << 6) >> 6;

return sprintf(buf, "%d\n", 250 * data);
Expand Down
Loading

0 comments on commit 1259f6e

Please sign in to comment.