Commit cdbfbba9 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'hwmon-for-linus-v4.12' of...

Merge tag 'hwmon-for-linus-v4.12' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging

Pull hwmon updates from Guenter Roeck:

 - removed twl4030-madc driver

 - added ASPEED PWM/fan driver

 - various minor improvements and fixes in several drivers

* tag 'hwmon-for-linus-v4.12' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: (36 commits)
  hwmon: (twl4030-madc) drop driver
  hwmon: (tmp103) Use SIMPLE_DEV_PM_OPS helper macro
  hwmon: (adt7475) set start bit in probe
  hwmon: (ina209) Handled signed registers
  hwmon: (lm87) Add OF device ID table
  hwmon: (lm87) Remove unused I2C devices driver_data
  drivers: hwmon: Support for ASPEED PWM/Fan tach
  Documentation: dt-bindings: Document bindings for ASPEED AST2400/AST2500 PWM and Fan tach controller device driver
  hwmon: (lm87) Allow channel data to be set from dts file
  Documentation: dtb: lm87: Add hwmon binding documentation
  hwmon: (ads7828) Accept optional parameters from device tree
  hwmon: (dell-smm) Add Dell XPS 15 9560 into DMI list
  hwmon: Constify str parameter of hwmon_ops->read_string
  dt: Add vendor prefix for Sensirion
  hwmon: (tmp421) Add OF device ID table
  hwmon: (tmp103) Add OF device ID table
  hwmon: (tmp102) Add OF device ID table
  hwmon: (stts751) Add OF device ID table
  hwmon: (ucd9200) Add OF device ID table
  hwmon: (ucd9000) Add OF device ID table
  ...
parents 89d1cf89 09d9d827
ads7828 properties
Required properties:
- compatible: Should be one of
ti,ads7828
ti,ads7830
- reg: I2C address
Optional properties:
- ti,differential-input
Set to use the device in differential mode.
- vref-supply
The external reference on the device is set to this regulators output. If it
does not exists the internal reference will be used and output by the ads78xx
on the "external vref" pin.
Example ADS7828 node:
ads7828: ads@48 {
comatible = "ti,ads7828";
reg = <0x48>;
vref-supply = <&vref>;
ti,differential-input;
};
ASPEED AST2400/AST2500 PWM and Fan Tacho controller device driver
The ASPEED PWM controller can support upto 8 PWM outputs. The ASPEED Fan Tacho
controller can support upto 16 Fan tachometer inputs.
There can be upto 8 fans supported. Each fan can have one PWM output and
one/two Fan tach inputs.
Required properties for pwm-tacho node:
- #address-cells : should be 1.
- #size-cells : should be 1.
- reg : address and length of the register set for the device.
- pinctrl-names : a pinctrl state named "default" must be defined.
- pinctrl-0 : phandle referencing pin configuration of the PWM ports.
- compatible : should be "aspeed,ast2400-pwm-tacho" for AST2400 and
"aspeed,ast2500-pwm-tacho" for AST2500.
- clocks : a fixed clock providing input clock frequency(PWM
and Fan Tach clock)
fan subnode format:
===================
Under fan subnode there can upto 8 child nodes, with each child node
representing a fan. If there are 8 fans each fan can have one PWM port and
one/two Fan tach inputs.
Required properties for each child node:
- reg : should specify PWM source port.
integer value in the range 0 to 7 with 0 indicating PWM port A and
7 indicating PWM port H.
- aspeed,fan-tach-ch : should specify the Fan tach input channel.
integer value in the range 0 through 15, with 0 indicating
Fan tach channel 0 and 15 indicating Fan tach channel 15.
Atleast one Fan tach input channel is required.
Examples:
pwm_tacho_fixed_clk: fixedclk {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <24000000>;
};
pwm_tacho: pwmtachocontroller@1e786000 {
#address-cells = <1>;
#size-cells = <1>;
reg = <0x1E786000 0x1000>;
compatible = "aspeed,ast2500-pwm-tacho";
clocks = <&pwm_tacho_fixed_clk>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm0_default &pinctrl_pwm1_default>;
fan@0 {
reg = <0x00>;
aspeed,fan-tach-ch = /bits/ 8 <0x00>;
};
fan@1 {
reg = <0x01>;
aspeed,fan-tach-ch = /bits/ 8 <0x01 0x02>;
};
};
*LM87 hwmon sensor.
Required properties:
- compatible: Should be
"ti,lm87"
- reg: I2C address
optional properties:
- has-temp3: This configures pins 18 and 19 to be used as a second
remote temperature sensing channel. By default the pins
are configured as voltage input pins in0 and in5.
- has-in6: When set, pin 5 is configured to be used as voltage input
in6. Otherwise the pin is set as FAN1 input.
- has-in7: When set, pin 6 is configured to be used as voltage input
in7. Otherwise the pin is set as FAN2 input.
- vcc-supply: a Phandle for the regulator supplying power, can be
cofigured to measure 5.0V power supply. Default is 3.3V.
Example:
lm87@2e {
compatible = "ti,lm87";
reg = <0x2e>;
has-temp3;
vcc-supply = <&reg_5v0>;
};
......@@ -265,6 +265,7 @@ sbs Smart Battery System
schindler Schindler
seagate Seagate Technology PLC
semtech Semtech Corporation
sensirion Sensirion AG
sgx SGX Sensortech
sharp Sharp Corporation
si-en Si-En Technology Ltd.
......
Kernel driver aspeed-pwm-tacho
==============================
Supported chips:
ASPEED AST2400/2500
Authors:
<jaghu@google.com>
Description:
------------
This driver implements support for ASPEED AST2400/2500 PWM and Fan Tacho
controller. The PWM controller supports upto 8 PWM outputs. The Fan tacho
controller supports up to 16 tachometer inputs.
The driver provides the following sensor accesses in sysfs:
fanX_input ro provide current fan rotation value in RPM as reported
by the fan to the device.
pwmX rw get or set PWM fan control value. This is an integer
value between 0(off) and 255(full speed).
......@@ -2,7 +2,7 @@ Kernel driver tc654
===================
Supported chips:
* Microship TC654 and TC655
* Microchip TC654 and TC655
Prefix: 'tc654'
Datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/20001734C.pdf
......
......@@ -341,6 +341,15 @@ config SENSORS_ASB100
This driver can also be built as a module. If so, the module
will be called asb100.
config SENSORS_ASPEED
tristate "ASPEED AST2400/AST2500 PWM and Fan tach driver"
help
This driver provides support for ASPEED AST2400/AST2500 PWM
and Fan Tacho controllers.
This driver can also be built as a module. If so, the module
will be called aspeed_pwm_tacho.
config SENSORS_ATXP1
tristate "Attansic ATXP1 VID controller"
depends on I2C
......@@ -1643,16 +1652,6 @@ config SENSORS_TMP421
This driver can also be built as a module. If so, the module
will be called tmp421.
config SENSORS_TWL4030_MADC
tristate "Texas Instruments TWL4030 MADC Hwmon"
depends on TWL4030_MADC
help
If you say yes here you get hwmon support for triton
TWL4030-MADC.
This driver can also be built as a module. If so it will be called
twl4030-madc-hwmon.
config SENSORS_VEXPRESS
tristate "Versatile Express"
depends on VEXPRESS_CONFIG
......
......@@ -46,6 +46,7 @@ obj-$(CONFIG_SENSORS_ADT7475) += adt7475.o
obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o
obj-$(CONFIG_SENSORS_ARM_SCPI) += scpi-hwmon.o
obj-$(CONFIG_SENSORS_ASC7621) += asc7621.o
obj-$(CONFIG_SENSORS_ASPEED) += aspeed-pwm-tacho.o
obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o
obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o
......@@ -157,7 +158,6 @@ obj-$(CONFIG_SENSORS_TMP103) += tmp103.o
obj-$(CONFIG_SENSORS_TMP108) += tmp108.o
obj-$(CONFIG_SENSORS_TMP401) += tmp401.o
obj-$(CONFIG_SENSORS_TMP421) += tmp421.o
obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o
obj-$(CONFIG_SENSORS_VEXPRESS) += vexpress-hwmon.o
obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o
obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
......
......@@ -217,9 +217,16 @@ static const struct i2c_device_id ad7414_id[] = {
};
MODULE_DEVICE_TABLE(i2c, ad7414_id);
static const struct of_device_id ad7414_of_match[] = {
{ .compatible = "ad,ad7414" },
{ },
};
MODULE_DEVICE_TABLE(of, ad7414_of_match);
static struct i2c_driver ad7414_driver = {
.driver = {
.name = "ad7414",
.of_match_table = of_match_ptr(ad7414_of_match),
},
.probe = ad7414_probe,
.id_table = ad7414_id,
......
......@@ -546,10 +546,17 @@ static const struct i2c_device_id adc128_id[] = {
};
MODULE_DEVICE_TABLE(i2c, adc128_id);
static const struct of_device_id adc128_of_match[] = {
{ .compatible = "ti,adc128d818" },
{ },
};
MODULE_DEVICE_TABLE(of, adc128_of_match);
static struct i2c_driver adc128_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adc128d818",
.of_match_table = of_match_ptr(adc128_of_match),
},
.probe = adc128_probe,
.remove = adc128_remove,
......
......@@ -31,6 +31,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/i2c/ads1015.h>
......@@ -268,7 +269,12 @@ static int ads1015_probe(struct i2c_client *client,
GFP_KERNEL);
if (!data)
return -ENOMEM;
data->id = id->driver_data;
if (client->dev.of_node)
data->id = (enum ads1015_chips)
of_device_get_match_data(&client->dev);
else
data->id = id->driver_data;
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
......@@ -303,9 +309,23 @@ static const struct i2c_device_id ads1015_id[] = {
};
MODULE_DEVICE_TABLE(i2c, ads1015_id);
static const struct of_device_id ads1015_of_match[] = {
{
.compatible = "ti,ads1015",
.data = (void *)ads1015
},
{
.compatible = "ti,ads1115",
.data = (void *)ads1115
},
{ },
};
MODULE_DEVICE_TABLE(of, ads1015_of_match);
static struct i2c_driver ads1015_driver = {
.driver = {
.name = "ads1015",
.of_match_table = of_match_ptr(ads1015_of_match),
},
.probe = ads1015_probe,
.remove = ads1015_remove,
......
......@@ -31,9 +31,11 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_data/ads7828.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/regulator/consumer.h>
/* The ADS7828 registers */
#define ADS7828_CMD_SD_SE 0x80 /* Single ended inputs */
......@@ -118,9 +120,12 @@ static int ads7828_probe(struct i2c_client *client,
struct ads7828_data *data;
struct device *hwmon_dev;
unsigned int vref_mv = ADS7828_INT_VREF_MV;
unsigned int vref_uv;
bool diff_input = false;
bool ext_vref = false;
unsigned int regval;
enum ads7828_chips chip;
struct regulator *reg;
data = devm_kzalloc(dev, sizeof(struct ads7828_data), GFP_KERNEL);
if (!data)
......@@ -131,14 +136,32 @@ static int ads7828_probe(struct i2c_client *client,
ext_vref = pdata->ext_vref;
if (ext_vref && pdata->vref_mv)
vref_mv = pdata->vref_mv;
} else if (dev->of_node) {
diff_input = of_property_read_bool(dev->of_node,
"ti,differential-input");
reg = devm_regulator_get_optional(dev, "vref");
if (!IS_ERR(reg)) {
vref_uv = regulator_get_voltage(reg);
vref_mv = DIV_ROUND_CLOSEST(vref_uv, 1000);
if (vref_mv < ADS7828_EXT_VREF_MV_MIN ||
vref_mv > ADS7828_EXT_VREF_MV_MAX)
return -EINVAL;
ext_vref = true;
}
}
if (client->dev.of_node)
chip = (enum ads7828_chips)
of_device_get_match_data(&client->dev);
else
chip = id->driver_data;
/* Bound Vref with min/max values */
vref_mv = clamp_val(vref_mv, ADS7828_EXT_VREF_MV_MIN,
ADS7828_EXT_VREF_MV_MAX);
/* ADS7828 uses 12-bit samples, while ADS7830 is 8-bit */
if (id->driver_data == ads7828) {
if (chip == ads7828) {
data->lsb_resol = DIV_ROUND_CLOSEST(vref_mv * 1000, 4096);
data->regmap = devm_regmap_init_i2c(client,
&ads2828_regmap_config);
......@@ -177,9 +200,23 @@ static const struct i2c_device_id ads7828_device_ids[] = {
};
MODULE_DEVICE_TABLE(i2c, ads7828_device_ids);
static const struct of_device_id ads7828_of_match[] = {
{
.compatible = "ti,ads7828",
.data = (void *)ads7828
},
{
.compatible = "ti,ads7830",
.data = (void *)ads7830
},
{ },
};
MODULE_DEVICE_TABLE(of, ads7828_of_match);
static struct i2c_driver ads7828_driver = {
.driver = {
.name = "ads7828",
.of_match_table = of_match_ptr(ads7828_of_match),
},
.id_table = ads7828_device_ids,
......
......@@ -13,6 +13,7 @@
*/
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
......@@ -58,6 +59,8 @@
#define REG_VENDID 0x3E
#define REG_DEVID2 0x3F
#define REG_CONFIG1 0x40
#define REG_STATUS1 0x41
#define REG_STATUS2 0x42
......@@ -161,6 +164,27 @@ static const struct i2c_device_id adt7475_id[] = {
};
MODULE_DEVICE_TABLE(i2c, adt7475_id);
static const struct of_device_id adt7475_of_match[] = {
{
.compatible = "adi,adt7473",
.data = (void *)adt7473
},
{
.compatible = "adi,adt7475",
.data = (void *)adt7475
},
{
.compatible = "adi,adt7476",
.data = (void *)adt7476
},
{
.compatible = "adi,adt7490",
.data = (void *)adt7490
},
{ },
};
MODULE_DEVICE_TABLE(of, adt7475_of_match);
struct adt7475_data {
struct device *hwmon_dev;
struct mutex lock;
......@@ -1250,6 +1274,7 @@ static void adt7475_remove_files(struct i2c_client *client,
static int adt7475_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
enum chips chip;
static const char * const names[] = {
[adt7473] = "ADT7473",
[adt7475] = "ADT7475",
......@@ -1268,8 +1293,13 @@ static int adt7475_probe(struct i2c_client *client,
mutex_init(&data->lock);
i2c_set_clientdata(client, data);
if (client->dev.of_node)
chip = (enum chips)of_device_get_match_data(&client->dev);
else
chip = id->driver_data;
/* Initialize device-specific values */
switch (id->driver_data) {
switch (chip) {
case adt7476:
data->has_voltage = 0x0e; /* in1 to in3 */
revision = adt7475_read(REG_DEVID2) & 0x07;
......@@ -1343,6 +1373,17 @@ static int adt7475_probe(struct i2c_client *client,
for (i = 0; i < ADT7475_PWM_COUNT; i++)
adt7475_read_pwm(client, i);
/* Start monitoring */
switch (chip) {
case adt7475:
case adt7476:
i2c_smbus_write_byte_data(client, REG_CONFIG1,
adt7475_read(REG_CONFIG1) | 0x01);
break;
default:
break;
}
ret = sysfs_create_group(&client->dev.kobj, &adt7475_attr_group);
if (ret)
return ret;
......@@ -1428,6 +1469,7 @@ static struct i2c_driver adt7475_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adt7475",
.of_match_table = of_match_ptr(adt7475_of_match),
},
.probe = adt7475_probe,
.remove = adt7475_remove,
......
This diff is collapsed.
......@@ -995,6 +995,13 @@ static struct dmi_system_id i8k_dmi_table[] __initdata = {
},
.driver_data = (void *)&i8k_config_data[DELL_XPS],
},
{
.ident = "Dell XPS 15 9560",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "XPS 15 9560"),
},
},
{ }
};
......
......@@ -186,7 +186,7 @@ static ssize_t hwmon_attr_show_string(struct device *dev,
char *buf)
{
struct hwmon_device_attribute *hattr = to_hwmon_attr(devattr);
char *s;
const char *s;
int ret;
ret = hattr->ops->read_string(dev, hattr->type, hattr->attr,
......
......@@ -117,7 +117,7 @@ static long ina209_from_reg(const u8 reg, const u16 val)
case INA209_SHUNT_VOLTAGE_POS_WARN:
case INA209_SHUNT_VOLTAGE_NEG_WARN:
/* LSB=10 uV. Convert to mV. */
return DIV_ROUND_CLOSEST(val, 100);
return DIV_ROUND_CLOSEST((s16)val, 100);
case INA209_BUS_VOLTAGE:
case INA209_BUS_VOLTAGE_MAX_PEAK:
......@@ -146,7 +146,7 @@ static long ina209_from_reg(const u8 reg, const u16 val)
case INA209_CURRENT:
/* LSB=1 mA (selected). Is in mA */
return val;
return (s16)val;
}
/* programmer goofed */
......@@ -608,11 +608,18 @@ static const struct i2c_device_id ina209_id[] = {
};
MODULE_DEVICE_TABLE(i2c, ina209_id);
static const struct of_device_id ina209_of_match[] = {
{ .compatible = "ti,ina209" },
{ },
};
MODULE_DEVICE_TABLE(of, ina209_of_match);
/* This is the driver that will be inserted */
static struct i2c_driver ina209_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "ina209",
.of_match_table = of_match_ptr(ina209_of_match),
},
.probe = ina209_probe,
.remove = ina209_remove,
......
......@@ -34,6 +34,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/jiffies.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/delay.h>
#include <linux/util_macros.h>
......@@ -424,13 +425,19 @@ static int ina2xx_probe(struct i2c_client *client,
struct device *hwmon_dev;
u32 val;
int ret, group = 0;
enum ina2xx_ids chip;
if (client->dev.of_node)
chip = (enum ina2xx_ids)of_device_get_match_data(&client->dev);
else
chip = id->driver_data;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
/* set the device type */
data->config = &ina2xx_config[id->driver_data];
data->config = &ina2xx_config[chip];
if (of_property_read_u32(dev->of_node, "shunt-resistor", &val) < 0) {
struct ina2xx_platform_data *pdata = dev_get_platdata(dev);
......@@ -487,9 +494,35 @@ static const struct i2c_device_id ina2xx_id[] = {
};
MODULE_DEVICE_TABLE(i2c, ina2xx_id);
static const struct of_device_id ina2xx_of_match[] = {
{
.compatible = "ti,ina219",
.data = (void *)ina219
},
{
.compatible = "ti,ina220",
.data = (void *)ina219
},
{
.compatible = "ti,ina226",
.data = (void *)ina226
},
{
.compatible = "ti,ina230",
.data = (void *)ina226
},
{
.compatible = "ti,ina231",
.data = (void *)ina226
},
{ },
};
MODULE_DEVICE_TABLE(of, ina2xx_of_match);
static struct i2c_driver ina2xx_driver = {
.driver = {
.name = "ina2xx",
.of_match_table = of_match_ptr(ina2xx_of_match),
},
.probe = ina2xx_probe,
.id_table = ina2xx_id,
......
......@@ -46,6 +46,7 @@
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/of_device.h>
#include <linux/sysfs.h>
#include <linux/types.h>
......@@ -1115,6 +1116,10 @@ static int lm63_probe(struct i2c_client *client,
mutex_init(&data->update_lock);
/* Set the device type */
if (client->dev.of_node)
data->kind = (enum chips)of_device_get_match_data(&client->dev);
else
data->kind = id->driver_data;
data->kind = id->driver_data;
if (data->kind == lm64)
data->temp2_offset = 16000;
......@@ -1149,10 +1154,28 @@ static const struct i2c_device_id lm63_id[] = {
};
MODULE_DEVICE_TABLE(i2c, lm63_id);
static const struct of_device_id lm63_of_match[] = {
{
.compatible = "national,lm63",
.data = (void *)lm63
},
{
.compatible = "national,lm64",
.data = (void *)lm64
},
{
.compatible = "national,lm96163",
.data = (void *)lm96163
},
{ },
};
MODULE_DEVICE_TABLE(of, lm63_of_match);
static struct i2c_driver lm63_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "lm63",
.of_match_table = of_match_ptr(lm63_of_match),
},
.probe = lm63_probe,
.id_table = lm63_id,
......
......@@ -26,6 +26,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include "lm75.h"
......@@ -273,7 +274,12 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
int status, err;
u8 set_mask, clr_mask;
int new;
enum lm75_type kind = id->driver_data;
enum lm75_type kind;
if (client->dev.of_node)
kind = (enum lm75_type)of_device_get_match_data(&client->dev);
else
kind = id->driver_data;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
......@@ -424,6 +430,95 @@ static const struct i2c_device_id lm75_ids[] = {
};
MODULE_DEVICE_TABLE(i2c, lm75_ids);
static const struct of_device_id lm75_of_match[] = {
{
.compatible = "adi,adt75",
.data = (void *)adt75
},
{
.compatible = "dallas,ds1775",
.data = (void *)ds1775
},
{
.compatible = "dallas,ds75",
.data = (void *)ds75
},
{
.compatible = "dallas,ds7505",
.data = (void *)ds7505
},
{
.compatible = "gmt,g751",
.data = (void *)g751
},
{
.compatible = "national,lm75",
.data = (void *)lm75
},
{
.compatible = "national,lm75a",
.data = (void *)lm75a
},
{
.compatible = "national,lm75b",
.data = (void *)lm75b
},
{
.compatible = "maxim,max6625",
.data = (void *)max6625
},
{
.compatible = "maxim,max6626",
.data = (void *)max6626
},
{
.compatible = "maxim,mcp980x",
.data = (void *)mcp980x
},
{
.compatible = "st,stds75",
.data = (void *)stds75
},
{
.compatible = "microchip,tcn75",
.data = (void *)tcn75
},
{
.compatible = "ti,tmp100",
.data = (void *)tmp100
},
{
.compatible = "ti,tmp101",
.data = (void *)tmp101
},
{
.compatible = "ti,tmp105",
.data = (void *)tmp105
},
{
.compatible = "ti,tmp112",
.data = (void *)tmp112
},
{
.compatible = "ti,tmp175",
.data = (void *)tmp175
},
{
.compatible = "ti,tmp275",
.data = (void *)tmp275
},
{
.compatible = "ti,tmp75",
.data = (void *)tmp75
},
{
.compatible = "ti,tmp75c",
.data = (void *)tmp75c
},
{ },
};
MODULE_DEVICE_TABLE(of, lm75_of_match);
#define LM75A_ID 0xA1
/* Return 0 if detection is successful, -ENODEV otherwise */
......@@ -560,6 +655,7 @@ static struct i2c_driver lm75_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "lm75",
.of_match_table = of_match_ptr(lm75_of_match),
.pm = LM75_DEV_PM_OPS,
},
.probe = lm75_probe,
......
......@@ -25,6 +25,7 @@
*/
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
......@@ -1552,7 +1553,10 @@ static int lm85_probe(struct i2c_client *client, const struct i2c_device_id *id)
return -ENOMEM;
data->client = client;
data->type = id->driver_data;
if (client->dev.of_node)
data->type = (enum chips)of_device_get_match_data(&client->dev);
else
data->type = id->driver_data;
mutex_init(&data->update_lock);
/* Fill in the chip specific driver values */
......@@ -1623,10 +1627,60 @@ static const struct i2c_device_id lm85_id[] = {
};
MODULE_DEVICE_TABLE(i2c, lm85_id);
static const struct of_device_id lm85_of_match[] = {
{
.compatible = "adi,adm1027",
.data = (void *)adm1027
},
{
.compatible = "adi,adt7463",
.data = (void *)adt7463
},
{
.compatible = "adi,adt7468",
.data = (void *)adt7468
},
{
.compatible = "national,lm85",
.data = (void *)lm85
},
{
.compatible = "national,lm85b",
.data = (void *)lm85
},
{
.compatible = "national,lm85c",
.data = (void *)lm85
},
{
.compatible = "smsc,emc6d100",
.data = (void *)emc6d100
},
{
.compatible = "smsc,emc6d101",
.data = (void *)emc6d100
},
{
.compatible = "smsc,emc6d102",
.data = (void *)emc6d102
},
{
.compatible = "smsc,emc6d103",
.data = (void *)emc6d103
},
{
.compatible = "smsc,emc6d103s",
.data = (void *)emc6d103s
},
{ },
};
MODULE_DEVICE_TABLE(of, lm85_of_match);
static struct i2c_driver lm85_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "lm85",
.of_match_table = of_match_ptr(lm85_of_match),
},
.probe = lm85_probe,
.id_table = lm85_id,
......
......@@ -66,6 +66,7 @@
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/regulator/consumer.h>
/*
* Addresses to scan
......@@ -74,8 +75,6 @@
static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
enum chips { lm87, adm1024 };
/*
* The LM87 registers
*/
......@@ -855,8 +854,26 @@ static int lm87_init_client(struct i2c_client *client)
{
struct lm87_data *data = i2c_get_clientdata(client);
int rc;
if (dev_get_platdata(&client->dev)) {
struct device_node *of_node = client->dev.of_node;
u8 val = 0;
struct regulator *vcc = NULL;
if (of_node) {
if (of_property_read_bool(of_node, "has-temp3"))
val |= CHAN_TEMP3;
if (of_property_read_bool(of_node, "has-in6"))
val |= CHAN_NO_FAN(0);
if (of_property_read_bool(of_node, "has-in7"))
val |= CHAN_NO_FAN(1);
vcc = devm_regulator_get_optional(&client->dev, "vcc");
if (!IS_ERR(vcc)) {
if (regulator_get_voltage(vcc) == 5000000)
val |= CHAN_VCC_5V;
}
data->channel = val;
lm87_write_value(client,
LM87_REG_CHANNEL_MODE, data->channel);
} else if (dev_get_platdata(&client->dev)) {
data->channel = *(u8 *)dev_get_platdata(&client->dev);
lm87_write_value(client,
LM87_REG_CHANNEL_MODE, data->channel);
......@@ -962,16 +979,24 @@ static int lm87_probe(struct i2c_client *client, const struct i2c_device_id *id)
*/
static const struct i2c_device_id lm87_id[] = {
{ "lm87", lm87 },
{ "adm1024", adm1024 },
{ "lm87", 0 },
{ "adm1024", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, lm87_id);
static const struct of_device_id lm87_of_match[] = {
{ .compatible = "ti,lm87" },
{ .compatible = "adi,adm1024" },
{ },
};
MODULE_DEVICE_TABLE(of, lm87_of_match);
static struct i2c_driver lm87_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "lm87",
.of_match_table = lm87_of_match,
},
.probe = lm87_probe,
.id_table = lm87_id,
......
......@@ -92,6 +92,7 @@
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/of_device.h>
#include <linux/sysfs.h>
#include <linux/interrupt.h>
#include <linux/regulator/consumer.h>
......@@ -235,6 +236,99 @@ static const struct i2c_device_id lm90_id[] = {
};
MODULE_DEVICE_TABLE(i2c, lm90_id);
static const struct of_device_id lm90_of_match[] = {
{
.compatible = "adi,adm1032",
.data = (void *)adm1032
},
{
.compatible = "adi,adt7461",
.data = (void *)adt7461
},
{
.compatible = "adi,adt7461a",
.data = (void *)adt7461
},
{
.compatible = "gmt,g781",
.data = (void *)g781
},
{
.compatible = "national,lm90",
.data = (void *)lm90
},
{
.compatible = "national,lm86",
.data = (void *)lm86
},
{
.compatible = "national,lm89",
.data = (void *)lm86
},
{
.compatible = "national,lm99",
.data = (void *)lm99
},
{
.compatible = "dallas,max6646",
.data = (void *)max6646
},
{
.compatible = "dallas,max6647",
.data = (void *)max6646
},
{
.compatible = "dallas,max6649",
.data = (void *)max6646
},
{
.compatible = "dallas,max6657",
.data = (void *)max6657
},
{
.compatible = "dallas,max6658",
.data = (void *)max6657
},
{
.compatible = "dallas,max6659",
.data = (void *)max6659
},
{
.compatible = "dallas,max6680",
.data = (void *)max6680
},
{
.compatible = "dallas,max6681",
.data = (void *)max6680
},
{
.compatible = "dallas,max6695",
.data = (void *)max6696
},
{
.compatible = "dallas,max6696",
.data = (void *)max6696
},
{
.compatible = "onnn,nct1008",
.data = (void *)adt7461
},
{
.compatible = "winbond,w83l771",
.data = (void *)w83l771
},
{
.compatible = "nxp,sa56004",
.data = (void *)sa56004
},
{
.compatible = "ti,tmp451",
.data = (void *)tmp451
},
{ },
};
MODULE_DEVICE_TABLE(of, lm90_of_match);
/*
* chip type specific parameters
*/
......@@ -1677,7 +1771,10 @@ static int lm90_probe(struct i2c_client *client,
mutex_init(&data->update_lock);
/* Set the device type */
data->kind = id->driver_data;
if (client->dev.of_node)
data->kind = (enum chips)of_device_get_match_data(&client->dev);
else
data->kind = id->driver_data;
if (data->kind == adm1032) {
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
client->flags &= ~I2C_CLIENT_PEC;
......@@ -1816,6 +1913,7 @@ static struct i2c_driver lm90_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "lm90",
.of_match_table = of_match_ptr(lm90_of_match),
},
.probe = lm90_probe,
.alert = lm90_alert,
......
......@@ -622,10 +622,18 @@ static const struct i2c_device_id lm95245_id[] = {
};
MODULE_DEVICE_TABLE(i2c, lm95245_id);
static const struct of_device_id lm95245_of_match[] = {
{ .compatible = "national,lm95235" },
{ .compatible = "national,lm95245" },
{ },
};
MODULE_DEVICE_TABLE(of, lm95245_of_match);
static struct i2c_driver lm95245_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "lm95245",
.of_match_table = of_match_ptr(lm95245_of_match),
},
.probe = lm95245_probe,
.id_table = lm95245_id,
......
......@@ -24,6 +24,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_data/max6697.h>
......@@ -632,7 +633,10 @@ static int max6697_probe(struct i2c_client *client,
if (!data)
return -ENOMEM;
data->type = id->driver_data;
if (client->dev.of_node)
data->type = (enum chips)of_device_get_match_data(&client->dev);
else
data->type = id->driver_data;
data->chip = &max6697_chip_data[data->type];
data->client = client;
mutex_init(&data->update_lock);
......@@ -662,10 +666,56 @@ static const struct i2c_device_id max6697_id[] = {
};
MODULE_DEVICE_TABLE(i2c, max6697_id);
static const struct of_device_id max6697_of_match[] = {
{
.compatible = "maxim,max6581",
.data = (void *)max6581
},
{
.compatible = "maxim,max6602",
.data = (void *)max6602
},
{
.compatible = "maxim,max6622",
.data = (void *)max6622
},
{
.compatible = "maxim,max6636",
.data = (void *)max6636
},
{
.compatible = "maxim,max6689",
.data = (void *)max6689
},
{
.compatible = "maxim,max6693",
.data = (void *)max6693
},
{
.compatible = "maxim,max6694",
.data = (void *)max6694
},
{
.compatible = "maxim,max6697",
.data = (void *)max6697
},
{
.compatible = "maxim,max6698",
.data = (void *)max6698
},
{
.compatible = "maxim,max6699",
.data = (void *)max6699
},
{ },
};
MODULE_DEVICE_TABLE(of, max6697_of_match);
static struct i2c_driver max6697_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "max6697",
.of_match_table = of_match_ptr(max6697_of_match),
},
.probe = max6697_probe,
.id_table = max6697_id,
......
......@@ -101,8 +101,8 @@ static const struct coefficients adm1075_coefficients[] = {
[0] = { 27169, 0, -1 }, /* voltage */
[1] = { 806, 20475, -1 }, /* current, irange25 */
[2] = { 404, 20475, -1 }, /* current, irange50 */
[3] = { 0, -1, 8549 }, /* power, irange25 */
[4] = { 0, -1, 4279 }, /* power, irange50 */
[3] = { 8549, 0, -1 }, /* power, irange25 */
[4] = { 4279, 0, -1 }, /* power, irange50 */
};
static const struct coefficients adm1275_coefficients[] = {
......
......@@ -21,6 +21,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/slab.h>
......@@ -119,6 +120,35 @@ static const struct i2c_device_id ucd9000_id[] = {
};
MODULE_DEVICE_TABLE(i2c, ucd9000_id);
static const struct of_device_id ucd9000_of_match[] = {
{
.compatible = "ti,ucd9000",
.data = (void *)ucd9000
},
{
.compatible = "ti,ucd90120",
.data = (void *)ucd90120
},
{
.compatible = "ti,ucd90124",
.data = (void *)ucd90124
},
{
.compatible = "ti,ucd90160",
.data = (void *)ucd90160
},
{
.compatible = "ti,ucd9090",
.data = (void *)ucd9090
},
{
.compatible = "ti,ucd90910",
.data = (void *)ucd90910
},
{ },
};
MODULE_DEVICE_TABLE(of, ucd9000_of_match);
static int ucd9000_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
......@@ -126,6 +156,7 @@ static int ucd9000_probe(struct i2c_client *client,
struct ucd9000_data *data;
struct pmbus_driver_info *info;
const struct i2c_device_id *mid;
enum chips chip;
int i, ret;
if (!i2c_check_functionality(client->adapter,
......@@ -151,7 +182,12 @@ static int ucd9000_probe(struct i2c_client *client,
return -ENODEV;
}
if (id->driver_data != ucd9000 && id->driver_data != mid->driver_data)
if (client->dev.of_node)
chip = (enum chips)of_device_get_match_data(&client->dev);
else
chip = id->driver_data;
if (chip != ucd9000 && chip != mid->driver_data)
dev_notice(&client->dev,
"Device mismatch: Configured %s, detected %s\n",
id->name, mid->name);
......@@ -234,6 +270,7 @@ static int ucd9000_probe(struct i2c_client *client,
static struct i2c_driver ucd9000_driver = {
.driver = {
.name = "ucd9000",
.of_match_table = of_match_ptr(ucd9000_of_match),
},
.probe = ucd9000_probe,
.remove = pmbus_do_remove,
......
......@@ -20,6 +20,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/slab.h>
......@@ -46,12 +47,50 @@ static const struct i2c_device_id ucd9200_id[] = {
};
MODULE_DEVICE_TABLE(i2c, ucd9200_id);
static const struct of_device_id ucd9200_of_match[] = {
{
.compatible = "ti,cd9200",
.data = (void *)ucd9200
},
{
.compatible = "ti,cd9220",
.data = (void *)ucd9220
},
{
.compatible = "ti,cd9222",
.data = (void *)ucd9222
},
{
.compatible = "ti,cd9224",
.data = (void *)ucd9224
},
{
.compatible = "ti,cd9240",
.data = (void *)ucd9240
},
{
.compatible = "ti,cd9244",
.data = (void *)ucd9244
},
{
.compatible = "ti,cd9246",
.data = (void *)ucd9246
},
{
.compatible = "ti,cd9248",
.data = (void *)ucd9248
},
{ },
};
MODULE_DEVICE_TABLE(of, ucd9200_of_match);
static int ucd9200_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1];
struct pmbus_driver_info *info;
const struct i2c_device_id *mid;
enum chips chip;
int i, j, ret;
if (!i2c_check_functionality(client->adapter,
......@@ -76,7 +115,13 @@ static int ucd9200_probe(struct i2c_client *client,
dev_err(&client->dev, "Unsupported device\n");
return -ENODEV;
}
if (id->driver_data != ucd9200 && id->driver_data != mid->driver_data)
if (client->dev.of_node)
chip = (enum chips)of_device_get_match_data(&client->dev);
else
chip = id->driver_data;
if (chip != ucd9200 && chip != mid->driver_data)
dev_notice(&client->dev,
"Device mismatch: Configured %s, detected %s\n",
id->name, mid->name);
......@@ -167,6 +212,7 @@ static int ucd9200_probe(struct i2c_client *client,
static struct i2c_driver ucd9200_driver = {
.driver = {
.name = "ucd9200",
.of_match_table = of_match_ptr(ucd9200_of_match),
},
.probe = ucd9200_probe,
.remove = pmbus_do_remove,
......
......@@ -85,6 +85,12 @@ static const struct i2c_device_id stts751_id[] = {
{ }
};
static const struct of_device_id stts751_of_match[] = {
{ .compatible = "stts751" },
{ },
};
MODULE_DEVICE_TABLE(of, stts751_of_match);
struct stts751_priv {
struct device *dev;
struct i2c_client *client;
......@@ -819,6 +825,7 @@ static struct i2c_driver stts751_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = DEVNAME,
.of_match_table = of_match_ptr(stts751_of_match),
},
.probe = stts751_probe,
.id_table = stts751_id,
......
......@@ -323,8 +323,15 @@ static const struct i2c_device_id tmp102_id[] = {
};
MODULE_DEVICE_TABLE(i2c, tmp102_id);
static const struct of_device_id tmp102_of_match[] = {
{ .compatible = "ti,tmp102" },
{ },
};
MODULE_DEVICE_TABLE(of, tmp102_of_match);
static struct i2c_driver tmp102_driver = {
.driver.name = DRIVER_NAME,
.driver.of_match_table = of_match_ptr(tmp102_of_match),
.driver.pm = &tmp102_dev_pm_ops,
.probe = tmp102_probe,
.id_table = tmp102_id,
......
......@@ -150,8 +150,7 @@ static int tmp103_probe(struct i2c_client *client,
return PTR_ERR_OR_ZERO(hwmon_dev);
}
#ifdef CONFIG_PM
static int tmp103_suspend(struct device *dev)
static int __maybe_unused tmp103_suspend(struct device *dev)
{
struct regmap *regmap = dev_get_drvdata(dev);
......@@ -159,7 +158,7 @@ static int tmp103_suspend(struct device *dev)
TMP103_CONF_SD_MASK, 0);
}
static int tmp103_resume(struct device *dev)
static int __maybe_unused tmp103_resume(struct device *dev)
{
struct regmap *regmap = dev_get_drvdata(dev);
......@@ -167,15 +166,7 @@ static int tmp103_resume(struct device *dev)
TMP103_CONF_SD_MASK, TMP103_CONF_SD);
}
static const struct dev_pm_ops tmp103_dev_pm_ops = {
.suspend = tmp103_suspend,
.resume = tmp103_resume,
};
#define TMP103_DEV_PM_OPS (&tmp103_dev_pm_ops)
#else
#define TMP103_DEV_PM_OPS NULL
#endif /* CONFIG_PM */
static SIMPLE_DEV_PM_OPS(tmp103_dev_pm_ops, tmp103_suspend, tmp103_resume);
static const struct i2c_device_id tmp103_id[] = {
{ "tmp103", 0 },
......@@ -183,10 +174,17 @@ static const struct i2c_device_id tmp103_id[] = {
};
MODULE_DEVICE_TABLE(i2c, tmp103_id);
static const struct of_device_id tmp103_of_match[] = {
{ .compatible = "ti,tmp103" },
{ },
};
MODULE_DEVICE_TABLE(of, tmp103_of_match);
static struct i2c_driver tmp103_driver = {
.driver = {
.name = "tmp103",
.pm = TMP103_DEV_PM_OPS,
.of_match_table = of_match_ptr(tmp103_of_match),
.pm = &tmp103_dev_pm_ops,
},
.probe = tmp103_probe,
.id_table = tmp103_id,
......
......@@ -29,6 +29,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/of_device.h>
#include <linux/sysfs.h>
/* Addresses to scan */
......@@ -69,6 +70,31 @@ static const struct i2c_device_id tmp421_id[] = {
};
MODULE_DEVICE_TABLE(i2c, tmp421_id);
static const struct of_device_id tmp421_of_match[] = {
{
.compatible = "ti,tmp421",
.data = (void *)2
},
{
.compatible = "ti,tmp422",
.data = (void *)3
},
{
.compatible = "ti,tmp423",
.data = (void *)4
},
{
.compatible = "ti,tmp441",
.data = (void *)2
},
{
.compatible = "ti,tmp422",
.data = (void *)3
},
{ },
};
MODULE_DEVICE_TABLE(of, tmp421_of_match);
struct tmp421_data {
struct i2c_client *client;
struct mutex update_lock;
......@@ -78,7 +104,7 @@ struct tmp421_data {
struct hwmon_chip_info chip;
char valid;
unsigned long last_updated;
int channels;
unsigned long channels;
u8 config;
s16 temp[4];
};
......@@ -272,7 +298,11 @@ static int tmp421_probe(struct i2c_client *client,
return -ENOMEM;
mutex_init(&data->update_lock);
data->channels = id->driver_data;
if (client->dev.of_node)
data->channels = (unsigned long)
of_device_get_match_data(&client->dev);
else
data->channels = id->driver_data;
data->client = client;
err = tmp421_init_client(client);
......@@ -301,6 +331,7 @@ static struct i2c_driver tmp421_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "tmp421",
.of_match_table = of_match_ptr(tmp421_of_match),
},
.probe = tmp421_probe,
.id_table = tmp421_id,
......
/*
*
* TWL4030 MADC Hwmon driver-This driver monitors the real time
* conversion of analog signals like battery temperature,
* battery type, battery level etc. User can ask for the conversion on a
* particular channel using the sysfs nodes.
*
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
* J Keerthy <j-keerthy@ti.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c/twl.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/i2c/twl4030-madc.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/stddef.h>
#include <linux/sysfs.h>
#include <linux/err.h>
#include <linux/types.h>
/*
* sysfs hook function
*/
static ssize_t madc_read(struct device *dev,
struct device_attribute *devattr, char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct twl4030_madc_request req = {
.channels = 1 << attr->index,
.method = TWL4030_MADC_SW2,
.type = TWL4030_MADC_WAIT,
};
long val;
val = twl4030_madc_conversion(&req);
if (val < 0)
return val;
return sprintf(buf, "%d\n", req.rbuf[attr->index]);
}
/* sysfs nodes to read individual channels from user side */
static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, madc_read, NULL, 0);
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, madc_read, NULL, 1);
static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, madc_read, NULL, 2);
static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, madc_read, NULL, 3);
static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, madc_read, NULL, 4);
static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, madc_read, NULL, 5);
static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, madc_read, NULL, 6);
static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, madc_read, NULL, 7);
static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, madc_read, NULL, 8);
static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, madc_read, NULL, 9);
static SENSOR_DEVICE_ATTR(curr10_input, S_IRUGO, madc_read, NULL, 10);
static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, madc_read, NULL, 11);
static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, madc_read, NULL, 12);
static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, madc_read, NULL, 15);
static struct attribute *twl4030_madc_attrs[] = {
&sensor_dev_attr_in0_input.dev_attr.attr,
&sensor_dev_attr_temp1_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_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_in9_input.dev_attr.attr,
&sensor_dev_attr_curr10_input.dev_attr.attr,
&sensor_dev_attr_in11_input.dev_attr.attr,
&sensor_dev_attr_in12_input.dev_attr.attr,
&sensor_dev_attr_in15_input.dev_attr.attr,
NULL
};
ATTRIBUTE_GROUPS(twl4030_madc);
static int twl4030_madc_hwmon_probe(struct platform_device *pdev)
{
struct device *hwmon;
hwmon = devm_hwmon_device_register_with_groups(&pdev->dev,
"twl4030_madc", NULL,
twl4030_madc_groups);
return PTR_ERR_OR_ZERO(hwmon);
}
static struct platform_driver twl4030_madc_hwmon_driver = {
.probe = twl4030_madc_hwmon_probe,
.driver = {
.name = "twl4030_madc_hwmon",
},
};
module_platform_driver(twl4030_madc_hwmon_driver);
MODULE_DESCRIPTION("TWL4030 ADC Hwmon driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("J Keerthy");
MODULE_ALIAS("platform:twl4030_madc_hwmon");
......@@ -135,11 +135,16 @@ superio_select(int ioreg, int ld)
outb(ld, ioreg + 1);
}
static inline void
static inline int
superio_enter(int ioreg)
{
if (!request_muxed_region(ioreg, 2, DRVNAME))
return -EBUSY;
outb(0x87, ioreg);
outb(0x87, ioreg);
return 0;
}
static inline void
......@@ -148,6 +153,7 @@ superio_exit(int ioreg)
outb(0xaa, ioreg);
outb(0x02, ioreg);
outb(0x02, ioreg + 1);
release_region(ioreg, 2);
}
/*
......@@ -1970,8 +1976,6 @@ w83627ehf_check_fan_inputs(const struct w83627ehf_sio_data *sio_data,
return;
}
superio_enter(sio_data->sioreg);
/* fan4 and fan5 share some pins with the GPIO and serial flash */
if (sio_data->kind == nct6775) {
/* On NCT6775, fan4 shares pins with the fdc interface */
......@@ -2013,8 +2017,6 @@ w83627ehf_check_fan_inputs(const struct w83627ehf_sio_data *sio_data,
fan4min = fan4pin;
}
superio_exit(sio_data->sioreg);
data->has_fan = data->has_fan_min = 0x03; /* fan1 and fan2 */
data->has_fan |= (fan3pin << 2);
data->has_fan_min |= (fan3pin << 2);
......@@ -2352,7 +2354,11 @@ static int w83627ehf_probe(struct platform_device *pdev)
w83627ehf_init_device(data, sio_data->kind);
data->vrm = vid_which_vrm();
superio_enter(sio_data->sioreg);
err = superio_enter(sio_data->sioreg);
if (err)
goto exit_release;
/* Read VID value */
if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b ||
sio_data->kind == nct6775 || sio_data->kind == nct6776) {
......@@ -2364,8 +2370,10 @@ static int w83627ehf_probe(struct platform_device *pdev)
superio_select(sio_data->sioreg, W83667HG_LD_VID);
data->vid = superio_inb(sio_data->sioreg, 0xe3);
err = device_create_file(dev, &dev_attr_cpu0_vid);
if (err)
if (err) {
superio_exit(sio_data->sioreg);
goto exit_release;
}
} else if (sio_data->kind != w83627uhg) {
superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) {
......@@ -2401,8 +2409,10 @@ static int w83627ehf_probe(struct platform_device *pdev)
data->vid &= 0x3f;
err = device_create_file(dev, &dev_attr_cpu0_vid);
if (err)
if (err) {
superio_exit(sio_data->sioreg);
goto exit_release;
}
} else {
dev_info(dev,
"VID pins in output mode, CPU VID not available\n");
......@@ -2424,10 +2434,10 @@ static int w83627ehf_probe(struct platform_device *pdev)
pr_info("Enabled fan debounce for chip %s\n", data->name);
}
superio_exit(sio_data->sioreg);
w83627ehf_check_fan_inputs(sio_data, data);
superio_exit(sio_data->sioreg);
/* Read fan clock dividers immediately */
w83627ehf_update_fan_div_common(dev, data);
......@@ -2712,8 +2722,11 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
u16 val;
const char *sio_name;
int err;
superio_enter(sioaddr);
err = superio_enter(sioaddr);
if (err)
return err;
if (force_id)
val = force_id;
......
......@@ -337,7 +337,7 @@ struct hwmon_ops {
int (*read)(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long *val);
int (*read_string)(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, char **str);
u32 attr, int channel, const char **str);
int (*write)(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long val);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment