提交 161d2e0a 编写于 作者: L Linus Torvalds

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

Pull hwmon updates from Guenter Roeck:
 "Notable changes:

   - Heiko Schocher provided a driver for TI TMP103.
   - Kamil Debski provided a driver for pwm-controlled fans.
   - Neelesh Gupta provided a driver for power, fan rpm, voltage and
     temperature reporting on powerpc/powernv systems.
   - Scott Kanowitz provided a driver supporting Lattice's POWR1220
     power manager IC.
   - Richard Zhu provided a pmbus front-end driver for TPS40422.
   - Frans Klaver added support for TMP112 to the lm75 driver.
   - Johannes Pointner added support for EPCOS B57330V2103 to the
     ntc_thermistor driver.
   - Guenter Roeck added support for TMP441 and TMP442 to the tmp421
     driver.
   - Axel Lin converted several drivers to the new hwmon API (36 of
     them, if I counted correctly), and cleaned up many of the drivers
     along the way.

  There are also a number of patches fixing bugs discovered while
  testing Axel's changes"

* tag 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: (88 commits)
  hwmon: (g762) Use of_property_read_u32 at appropriate place
  hwmon: (sis5595) Prevent overflow problem when writing large limits
  hwmon: (gpio-fan) Prevent overflow problem when writing large limits
  hwmon: (ibmpowernv) Use of_property_read_u32 at appropriate place
  hwmon: (lm85) Convert to devm_hwmon_device_register_with_groups
  hwmon: (lm85) Avoid forward declaration
  hwmon: (lm78) Convert to devm_hwmon_device_register_with_groups
  hwmon: (max6697) Use of_property_read_bool at appropriate places
  hwmon: (pwm-fan) Make SENSORS_PWM_FAN depend on OF
  hwmon: (pwm-fan) Remove duplicate dev_set_drvdata call
  hwmon: (nct6775) Remove num_attr_groups from struct nct6775_data
  hwmon: (nct6775) Update module description and Kconfig for NCT6106D and NCT6791D
  hwmon: (adt7411) Convert to devm_hwmon_device_register_with_groups
  hwmon: (g762) Convert to hwmon_device_register_with_groups
  hwmon: (emc2103) Convert to devm_hwmon_device_register_with_groups
  hwmon: (smsc47m1) Avoid forward declaration
  hwmon: (smsc47m192) Convert to devm_hwmon_device_register_with_groups
  hwmon: (smsc47m192) Avoid forward declaration
  hwmon: (max1668) Make max1668_addr_list array const
  hwmon: (max6639) Make normal_i2c array const
  ...
IBM POWERNV platform sensors
----------------------------
Required node properties:
- compatible: must be one of
"ibm,opal-sensor-cooling-fan"
"ibm,opal-sensor-amb-temp"
"ibm,opal-sensor-power-supply"
"ibm,opal-sensor-power"
- sensor-id: an opaque id provided by the firmware to the kernel, identifies a
given sensor and its attribute data
Example sensors node:
cooling-fan#8-data {
sensor-id = <0x7052107>;
compatible = "ibm,opal-sensor-cooling-fan";
};
amb-temp#1-thrs {
sensor-id = <0x5096000>;
compatible = "ibm,opal-sensor-amb-temp";
};
......@@ -3,6 +3,7 @@ NTC Thermistor hwmon sensors
Requires node properties:
- "compatible" value : one of
"epcos,b57330v2103"
"murata,ncp15wb473"
"murata,ncp18wb473"
"murata,ncp21wb473"
......
Bindings for a fan connected to the PWM lines
Required properties:
- compatible : "pwm-fan"
- pwms : the PWM that is used to control the PWM fan
Example:
pwm-fan {
compatible = "pwm-fan";
status = "okay";
pwms = <&pwm 0 10000 0>;
};
......@@ -84,5 +84,6 @@ stm,m41t80 M41T80 - SERIAL ACCESS RTC WITH ALARMS
taos,tsl2550 Ambient Light Sensor with SMBUS/Two Wire Serial Interface
ti,tsc2003 I2C Touch-Screen Controller
ti,tmp102 Low Power Digital Temperature Sensor with SMBUS/Two Wire Serial Interface
ti,tmp103 Low Power Digital Temperature Sensor with SMBUS/Two Wire Serial Interface
ti,tmp275 Digital Temperature Sensor
winbond,wpct301 i2c trusted platform module (TPM)
......@@ -42,6 +42,7 @@ dmo Data Modul AG
ebv EBV Elektronik
edt Emerging Display Technologies
emmicro EM Microelectronic
epcos EPCOS AG
epfl Ecole Polytechnique Fédérale de Lausanne
epson Seiko Epson Corp.
est ESTeem Wireless Modems
......
Kernel Driver IBMPOWERNV
========================
Supported systems:
* Any recent IBM P servers based on POWERNV platform
Author: Neelesh Gupta
Description
-----------
This driver implements reading the platform sensors data like temperature/fan/
voltage/power for 'POWERNV' platform.
The driver uses the platform device infrastructure. It probes the device tree
for sensor devices during the __init phase and registers them with the 'hwmon'.
'hwmon' populates the 'sysfs' tree having attribute files, each for a given
sensor type and its attribute data.
All the nodes in the DT appear under "/ibm,opal/sensors" and each valid node in
the DT maps to an attribute file in 'sysfs'. The node exports unique 'sensor-id'
which the driver uses to make an OPAL call to the firmware.
Usage notes
-----------
The driver is built statically with the kernel by enabling the config
CONFIG_SENSORS_IBMPOWERNV. It can also be built as module 'ibmpowernv'.
Sysfs attributes
----------------
fanX_input Measured RPM value.
fanX_min Threshold RPM for alert generation.
fanX_fault 0: No fail condition
1: Failing fan
tempX_input Measured ambient temperature.
tempX_max Threshold ambient temperature for alert generation.
inX_input Measured power supply voltage
inX_fault 0: No fail condition.
1: Failing power supply.
power1_input System power consumption (microWatt)
......@@ -42,13 +42,14 @@ Supported chips:
Addresses scanned: none
Datasheet: Publicly available at the ST website
http://www.st.com/internet/analog/product/121769.jsp
* Texas Instruments TMP100, TMP101, TMP105, TMP75, TMP175, TMP275
Prefixes: 'tmp100', 'tmp101', 'tmp105', 'tmp175', 'tmp75', 'tmp275'
* Texas Instruments TMP100, TMP101, TMP105, TMP112, TMP75, TMP175, TMP275
Prefixes: 'tmp100', 'tmp101', 'tmp105', 'tmp112', 'tmp175', 'tmp75', 'tmp275'
Addresses scanned: none
Datasheet: Publicly available at the Texas Instruments website
http://www.ti.com/product/tmp100
http://www.ti.com/product/tmp101
http://www.ti.com/product/tmp105
http://www.ti.com/product/tmp112
http://www.ti.com/product/tmp75
http://www.ti.com/product/tmp175
http://www.ti.com/product/tmp275
......
......@@ -6,6 +6,11 @@ Supported thermistors from Murata:
Prefixes: 'ncp15wb473', 'ncp18wb473', 'ncp21wb473', 'ncp03wb473', 'ncp15wl333'
Datasheet: Publicly available at Murata
Supported thermistors from EPCOS:
* EPCOS NTC Thermistors B57330V2103
Prefixes: b57330v2103
Datasheet: Publicly available at EPCOS
Other NTC thermistors can be supported simply by adding compensation
tables; e.g., NCP15WL333 support is added by the table ncpXXwl333.
......
......@@ -23,12 +23,11 @@ Supported chips:
http://www.lineagepower.com/oem/pdf/PDT012A0X.pdf
http://www.lineagepower.com/oem/pdf/UDT020A0X.pdf
http://www.lineagepower.com/oem/pdf/MDT040A0X.pdf
* Texas Instruments TPS40400, TPS40422
Prefixes: 'tps40400', 'tps40422'
* Texas Instruments TPS40400
Prefixes: 'tps40400'
Addresses scanned: -
Datasheets:
http://www.ti.com/lit/gpn/tps40400
http://www.ti.com/lit/gpn/tps40422
* Generic PMBus devices
Prefix: 'pmbus'
Addresses scanned: -
......
Kernel driver powr1220
==================
Supported chips:
* Lattice POWR1220AT8
Prefix: 'powr1220'
Addresses scanned: none
Datasheet: Publicly available at the Lattice website
http://www.latticesemi.com/
Author: Scott Kanowitz <scott.kanowitz@gmail.com>
Description
-----------
This driver supports the Lattice POWR1220AT8 chip. The POWR1220
includes voltage monitoring for 14 inputs as well as trim settings
for output voltages and GPIOs. This driver implements the voltage
monitoring portion of the chip.
Voltages are sampled by a 12-bit ADC with a step size of 2 mV.
An in-line attenuator allows measurements from 0 to 6 V. The
attenuator is enabled or disabled depending on the setting of the
input's max value. The driver will enable the attenuator for any
value over the low measurement range maximum of 2 V.
The input naming convention is as follows:
driver name pin name
in0 VMON1
in1 VMON2
in2 VMON3
in2 VMON4
in4 VMON5
in5 VMON6
in6 VMON7
in7 VMON8
in8 VMON9
in9 VMON10
in10 VMON11
in11 VMON12
in12 VCCA
in13 VCCINP
The ADC readings are updated on request with a minimum period of 1s.
Kernel driver pwm-fan
=====================
This driver enables the use of a PWM module to drive a fan. It uses the
generic PWM interface thus it is hardware independent. It can be used on
many SoCs, as long as the SoC supplies a PWM line driver that exposes
the generic PWM API.
Author: Kamil Debski <k.debski@samsung.com>
Description
-----------
The driver implements a simple interface for driving a fan connected to
a PWM output. It uses the generic PWM interface, thus it can be used with
a range of SoCs. The driver exposes the fan to the user space through
the hwmon's sysfs interface.
Kernel driver tmp103
====================
Supported chips:
* Texas Instruments TMP103
Prefix: 'tmp103'
Addresses scanned: none
Product info and datasheet: http://www.ti.com/product/tmp103
Author:
Heiko Schocher <hs@denx.de>
Description
-----------
The TMP103 is a digital output temperature sensor in a four-ball
wafer chip-scale package (WCSP). The TMP103 is capable of reading
temperatures to a resolution of 1°C. The TMP103 is specified for
operation over a temperature range of –40°C to +125°C.
Resolution: 8 Bits
Accuracy: ±1°C Typ (–10°C to +100°C)
The driver provides the common sysfs-interface for temperatures (see
Documentation/hwmon/sysfs-interface under Temperatures).
Please refer how to instantiate this driver:
Documentation/i2c/instantiating-devices
......@@ -8,12 +8,20 @@ Supported chips:
Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
* Texas Instruments TMP422
Prefix: 'tmp422'
Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f
Addresses scanned: I2C 0x4c, 0x4d, 0x4e and 0x4f
Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
* Texas Instruments TMP423
Prefix: 'tmp423'
Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f
Addresses scanned: I2C 0x4c and 0x4d
Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
* Texas Instruments TMP441
Prefix: 'tmp441'
Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f
Datasheet: http://www.ti.com/product/tmp441
* Texas Instruments TMP442
Prefix: 'tmp442'
Addresses scanned: I2C 0x4c and 0x4d
Datasheet: http://www.ti.com/product/tmp442
Authors:
Andre Prendel <andre.prendel@gmx.de>
......@@ -21,13 +29,13 @@ Authors:
Description
-----------
This driver implements support for Texas Instruments TMP421, TMP422
and TMP423 temperature sensor chips. These chips implement one local
and up to one (TMP421), up to two (TMP422) or up to three (TMP423)
remote sensors. Temperature is measured in degrees Celsius. The chips
are wired over I2C/SMBus and specified over a temperature range of -40
to +125 degrees Celsius. Resolution for both the local and remote
channels is 0.0625 degree C.
This driver implements support for Texas Instruments TMP421, TMP422,
TMP423, TMP441, and TMP442 temperature sensor chips. These chips
implement one local and up to one (TMP421, TMP441), up to two (TMP422,
TMP442) or up to three (TMP423) remote sensors. Temperature is measured
in degrees Celsius. The chips are wired over I2C/SMBus and specified
over a temperature range of -40 to +125 degrees Celsius. Resolution
for both the local and remote channels is 0.0625 degree C.
The chips support only temperature measurement. The driver exports
the temperature values via the following sysfs files:
......
Kernel driver tps40422
======================
Supported chips:
* TI TPS40422
Prefix: 'tps40422'
Addresses scanned: -
Datasheet: http://www.ti.com/lit/gpn/tps40422
Author: Zhu Laiwen <richard.zhu@nsn.com>
Description
-----------
This driver supports TI TPS40422 Dual-Output or Two-Phase Synchronous Buck
Controller with PMBus
The driver is a client driver to the core PMBus driver.
Please see Documentation/hwmon/pmbus for details on PMBus client drivers.
Usage Notes
-----------
This driver does not auto-detect devices. You will have to instantiate the
devices explicitly. Please see Documentation/i2c/instantiating-devices for
details.
Platform data support
---------------------
The driver supports standard PMBus driver platform data.
Sysfs entries
-------------
The following attributes are supported.
in[1-2]_label "vout[1-2]"
in[1-2]_input Measured voltage. From READ_VOUT register.
in[1-2]_alarm voltage alarm.
curr[1-2]_input Measured current. From READ_IOUT register.
curr[1-2]_label "iout[1-2]"
curr1_max Maximum current. From IOUT_OC_WARN_LIMIT register.
curr1_crit Critical maximum current. From IOUT_OC_FAULT_LIMIT register.
curr1_max_alarm Current high alarm. From IOUT_OC_WARN_LIMIT status.
curr1_crit_alarm Current critical high alarm. From IOUT_OC_FAULT status.
curr2_alarm Current high alarm. From IOUT_OC_WARNING status.
temp1_input Measured temperature. From READ_TEMPERATURE_2 register on page 0.
temp1_max Maximum temperature. From OT_WARN_LIMIT register.
temp1_crit Critical high temperature. From OT_FAULT_LIMIT register.
temp1_max_alarm Chip temperature high alarm. Set by comparing
READ_TEMPERATURE_2 on page 0 with OT_WARN_LIMIT if TEMP_OT_WARNING
status is set.
temp1_crit_alarm Chip temperature critical high alarm. Set by comparing
READ_TEMPERATURE_2 on page 0 with OT_FAULT_LIMIT if TEMP_OT_FAULT
status is set.
temp2_input Measured temperature. From READ_TEMPERATURE_2 register on page 1.
temp2_alarm Chip temperature alarm on page 1.
......@@ -554,6 +554,17 @@ config SENSORS_IBMPEX
This driver can also be built as a module. If so, the module
will be called ibmpex.
config SENSORS_IBMPOWERNV
tristate "IBM POWERNV platform sensors"
depends on PPC_POWERNV
default y
help
If you say yes here you get support for the temperature/fan/power
sensors on your PowerNV platform.
This driver can also be built as a module. If so, the module
will be called ibmpowernv.
config SENSORS_IIO_HWMON
tristate "Hwmon driver that uses channels specified via iio maps"
depends on IIO
......@@ -608,6 +619,18 @@ config SENSORS_JC42
This driver can also be built as a module. If so, the module
will be called jc42.
config SENSORS_POWR1220
tristate "Lattice POWR1220 Power Monitoring"
depends on I2C
default n
help
If you say yes here you get access to the hardware monitoring
functions of the Lattice POWR1220 isp Power Supply Monitoring,
Sequencing and Margining Controller.
This driver can also be built as a module. If so, the module
will be called powr1220.
config SENSORS_LINEAGE
tristate "Lineage Compact Power Line Power Entry Module"
depends on I2C
......@@ -882,8 +905,8 @@ config SENSORS_LM75
- NXP's LM75A
- ST Microelectronics STDS75
- TelCom (now Microchip) TCN75
- Texas Instruments TMP100, TMP101, TMP105, TMP75, TMP175,
TMP275
- Texas Instruments TMP100, TMP101, TMP105, TMP112, TMP75,
TMP175, TMP275
This driver supports driver model based binding through board
specific I2C device tables.
......@@ -1061,7 +1084,7 @@ config SENSORS_NTC_THERMISTOR
Currently, this driver supports
NCP15WB473, NCP18WB473, NCP21WB473, NCP03WB473, and NCP15WL333
from Murata.
from Murata and B57330V2103 from EPCOS.
This driver can also be built as a module. If so, the module
will be called ntc-thermistor.
......@@ -1082,8 +1105,8 @@ config SENSORS_NCT6775
select HWMON_VID
help
If you say yes here you get support for the hardware monitoring
functionality of the Nuvoton NCT6775F, NCT6776F, NCT6779D
and compatible Super-I/O chips. This driver replaces the
functionality of the Nuvoton NCT6106D, NCT6775F, NCT6776F, NCT6779D,
NCT6791D and compatible Super-I/O chips. This driver replaces the
w83627ehf driver for NCT6775F and NCT6776F.
This driver can also be built as a module. If so, the module
......@@ -1105,6 +1128,17 @@ config SENSORS_PCF8591
source drivers/hwmon/pmbus/Kconfig
config SENSORS_PWM_FAN
tristate "PWM fan"
depends on (PWM && OF) || COMPILE_TEST
help
If you say yes here you get support for fans connected to PWM lines.
The driver uses the generic PWM interface, thus it will work on a
variety of SoCs.
This driver can also be built as a module. If so, the module
will be called pwm-fan.
config SENSORS_SHT15
tristate "Sensiron humidity and temperature sensors. SHT15 and compat."
depends on GPIOLIB
......@@ -1393,6 +1427,17 @@ config SENSORS_TMP102
This driver can also be built as a module. If so, the module
will be called tmp102.
config SENSORS_TMP103
tristate "Texas Instruments TMP103"
depends on I2C
select REGMAP_I2C
help
If you say yes here you get support for Texas Instruments TMP103
sensor chips.
This driver can also be built as a module. If so, the module
will be called tmp103.
config SENSORS_TMP401
tristate "Texas Instruments TMP401 and compatibles"
depends on I2C
......@@ -1408,7 +1453,7 @@ config SENSORS_TMP421
depends on I2C
help
If you say yes here you get support for Texas Instruments TMP421,
TMP422 and TMP423 temperature sensor chips.
TMP422, TMP423, TMP441, and TMP442 temperature sensor chips.
This driver can also be built as a module. If so, the module
will be called tmp421.
......
......@@ -71,6 +71,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_IBMPOWERNV)+= ibmpowernv.o
obj-$(CONFIG_SENSORS_IIO_HWMON) += iio_hwmon.o
obj-$(CONFIG_SENSORS_INA209) += ina209.o
obj-$(CONFIG_SENSORS_INA2XX) += ina2xx.o
......@@ -120,6 +121,8 @@ obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o
obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
obj-$(CONFIG_SENSORS_PC87427) += pc87427.o
obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
obj-$(CONFIG_SENSORS_POWR1220) += powr1220.o
obj-$(CONFIG_SENSORS_PWM_FAN) += pwm-fan.o
obj-$(CONFIG_SENSORS_S3C) += s3c-hwmon.o
obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o
obj-$(CONFIG_SENSORS_SCH5627) += sch5627.o
......@@ -135,6 +138,7 @@ obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o
obj-$(CONFIG_SENSORS_THMC50) += thmc50.o
obj-$(CONFIG_SENSORS_TMP102) += tmp102.o
obj-$(CONFIG_SENSORS_TMP103) += tmp103.o
obj-$(CONFIG_SENSORS_TMP401) += tmp401.o
obj-$(CONFIG_SENSORS_TMP421) += tmp421.o
obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o
......
......@@ -39,7 +39,7 @@
static u8 AD7414_REG_LIMIT[] = { AD7414_REG_T_HIGH, AD7414_REG_T_LOW };
struct ad7414_data {
struct device *hwmon_dev;
struct i2c_client *client;
struct mutex lock; /* atomic read data updates */
char valid; /* !=0 if following fields are valid */
unsigned long next_update; /* In jiffies */
......@@ -72,8 +72,8 @@ static inline int ad7414_write(struct i2c_client *client, u8 reg, u8 value)
static struct ad7414_data *ad7414_update_device(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct ad7414_data *data = i2c_get_clientdata(client);
struct ad7414_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
mutex_lock(&data->lock);
......@@ -127,8 +127,8 @@ static ssize_t set_max_min(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct ad7414_data *data = i2c_get_clientdata(client);
struct ad7414_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int index = to_sensor_dev_attr(attr)->index;
u8 reg = AD7414_REG_LIMIT[index];
long temp;
......@@ -164,7 +164,7 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 3);
static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 4);
static struct attribute *ad7414_attributes[] = {
static struct attribute *ad7414_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp1_min.dev_attr.attr,
......@@ -173,27 +173,25 @@ static struct attribute *ad7414_attributes[] = {
NULL
};
static const struct attribute_group ad7414_group = {
.attrs = ad7414_attributes,
};
ATTRIBUTE_GROUPS(ad7414);
static int ad7414_probe(struct i2c_client *client,
const struct i2c_device_id *dev_id)
{
struct device *dev = &client->dev;
struct ad7414_data *data;
struct device *hwmon_dev;
int conf;
int err;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_READ_WORD_DATA))
return -EOPNOTSUPP;
data = devm_kzalloc(&client->dev, sizeof(struct ad7414_data),
GFP_KERNEL);
data = devm_kzalloc(dev, sizeof(struct ad7414_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(client, data);
data->client = client;
mutex_init(&data->lock);
dev_info(&client->dev, "chip found\n");
......@@ -201,38 +199,16 @@ static int ad7414_probe(struct i2c_client *client,
/* Make sure the chip is powered up. */
conf = i2c_smbus_read_byte_data(client, AD7414_REG_CONF);
if (conf < 0)
dev_warn(&client->dev,
"ad7414_probe unable to read config register.\n");
dev_warn(dev, "ad7414_probe unable to read config register.\n");
else {
conf &= ~(1 << 7);
i2c_smbus_write_byte_data(client, AD7414_REG_CONF, conf);
}
/* Register sysfs hooks */
err = sysfs_create_group(&client->dev.kobj, &ad7414_group);
if (err)
return err;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
return 0;
exit_remove:
sysfs_remove_group(&client->dev.kobj, &ad7414_group);
return err;
}
static int ad7414_remove(struct i2c_client *client)
{
struct ad7414_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &ad7414_group);
return 0;
hwmon_dev = devm_hwmon_device_register_with_groups(dev,
client->name,
data, ad7414_groups);
return PTR_ERR_OR_ZERO(hwmon_dev);
}
static const struct i2c_device_id ad7414_id[] = {
......@@ -246,7 +222,6 @@ static struct i2c_driver ad7414_driver = {
.name = "ad7414",
},
.probe = ad7414_probe,
.remove = ad7414_remove,
.id_table = ad7414_id,
};
......
......@@ -44,8 +44,7 @@ static const u8 AD7418_REG_TEMP[] = { AD7418_REG_TEMP_IN,
AD7418_REG_TEMP_OS };
struct ad7418_data {
struct device *hwmon_dev;
struct attribute_group attrs;
struct i2c_client *client;
enum chips type;
struct mutex lock;
int adc_max; /* number of ADC channels */
......@@ -55,48 +54,10 @@ struct ad7418_data {
u16 in[4];
};
static int ad7418_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int ad7418_remove(struct i2c_client *client);
static const struct i2c_device_id ad7418_id[] = {
{ "ad7416", ad7416 },
{ "ad7417", ad7417 },
{ "ad7418", ad7418 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ad7418_id);
static struct i2c_driver ad7418_driver = {
.driver = {
.name = "ad7418",
},
.probe = ad7418_probe,
.remove = ad7418_remove,
.id_table = ad7418_id,
};
static void ad7418_init_client(struct i2c_client *client)
{
struct ad7418_data *data = i2c_get_clientdata(client);
int reg = i2c_smbus_read_byte_data(client, AD7418_REG_CONF);
if (reg < 0) {
dev_err(&client->dev, "cannot read configuration register\n");
} else {
dev_info(&client->dev, "configuring for mode 1\n");
i2c_smbus_write_byte_data(client, AD7418_REG_CONF, reg & 0xfe);
if (data->type == ad7417 || data->type == ad7418)
i2c_smbus_write_byte_data(client,
AD7418_REG_CONF2, 0x00);
}
}
static struct ad7418_data *ad7418_update_device(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct ad7418_data *data = i2c_get_clientdata(client);
struct ad7418_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
mutex_lock(&data->lock);
......@@ -165,8 +126,8 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct ad7418_data *data = i2c_get_clientdata(client);
struct ad7418_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
int ret = kstrtol(buf, 10, &temp);
......@@ -193,14 +154,15 @@ static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_adc, NULL, 1);
static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_adc, NULL, 2);
static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_adc, NULL, 3);
static struct attribute *ad7416_attributes[] = {
static struct attribute *ad7416_attrs[] = {
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
&sensor_dev_attr_temp1_input.dev_attr.attr,
NULL
};
ATTRIBUTE_GROUPS(ad7416);
static struct attribute *ad7417_attributes[] = {
static struct attribute *ad7417_attrs[] = {
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
&sensor_dev_attr_temp1_input.dev_attr.attr,
......@@ -210,83 +172,100 @@ static struct attribute *ad7417_attributes[] = {
&sensor_dev_attr_in4_input.dev_attr.attr,
NULL
};
ATTRIBUTE_GROUPS(ad7417);
static struct attribute *ad7418_attributes[] = {
static struct attribute *ad7418_attrs[] = {
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_in1_input.dev_attr.attr,
NULL
};
ATTRIBUTE_GROUPS(ad7418);
static void ad7418_init_client(struct i2c_client *client)
{
struct ad7418_data *data = i2c_get_clientdata(client);
int reg = i2c_smbus_read_byte_data(client, AD7418_REG_CONF);
if (reg < 0) {
dev_err(&client->dev, "cannot read configuration register\n");
} else {
dev_info(&client->dev, "configuring for mode 1\n");
i2c_smbus_write_byte_data(client, AD7418_REG_CONF, reg & 0xfe);
if (data->type == ad7417 || data->type == ad7418)
i2c_smbus_write_byte_data(client,
AD7418_REG_CONF2, 0x00);
}
}
static int ad7418_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
struct i2c_adapter *adapter = client->adapter;
struct ad7418_data *data;
int err;
struct device *hwmon_dev;
const struct attribute_group **attr_groups = NULL;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA))
return -EOPNOTSUPP;
data = devm_kzalloc(&client->dev, sizeof(struct ad7418_data),
GFP_KERNEL);
data = devm_kzalloc(dev, sizeof(struct ad7418_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(client, data);
mutex_init(&data->lock);
data->client = client;
data->type = id->driver_data;
switch (data->type) {
case ad7416:
data->adc_max = 0;
data->attrs.attrs = ad7416_attributes;
attr_groups = ad7416_groups;
break;
case ad7417:
data->adc_max = 4;
data->attrs.attrs = ad7417_attributes;
attr_groups = ad7417_groups;
break;
case ad7418:
data->adc_max = 1;
data->attrs.attrs = ad7418_attributes;
attr_groups = ad7418_groups;
break;
}
dev_info(&client->dev, "%s chip found\n", client->name);
dev_info(dev, "%s chip found\n", client->name);
/* Initialize the AD7418 chip */
ad7418_init_client(client);
/* Register sysfs hooks */
err = sysfs_create_group(&client->dev.kobj, &data->attrs);
if (err)
return err;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
return 0;
exit_remove:
sysfs_remove_group(&client->dev.kobj, &data->attrs);
return err;
hwmon_dev = devm_hwmon_device_register_with_groups(dev,
client->name,
data, attr_groups);
return PTR_ERR_OR_ZERO(hwmon_dev);
}
static int ad7418_remove(struct i2c_client *client)
{
struct ad7418_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &data->attrs);
return 0;
}
static const struct i2c_device_id ad7418_id[] = {
{ "ad7416", ad7416 },
{ "ad7417", ad7417 },
{ "ad7418", ad7418 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ad7418_id);
static struct i2c_driver ad7418_driver = {
.driver = {
.name = "ad7418",
},
.probe = ad7418_probe,
.id_table = ad7418_id,
};
module_i2c_driver(ad7418_driver);
......
......@@ -98,41 +98,63 @@ struct adm1021_data {
u8 remote_temp_offset_prec;
};
static int adm1021_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int adm1021_detect(struct i2c_client *client,
struct i2c_board_info *info);
static void adm1021_init_client(struct i2c_client *client);
static struct adm1021_data *adm1021_update_device(struct device *dev);
/* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */
static bool read_only;
static struct adm1021_data *adm1021_update_device(struct device *dev)
{
struct adm1021_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
static const struct i2c_device_id adm1021_id[] = {
{ "adm1021", adm1021 },
{ "adm1023", adm1023 },
{ "max1617", max1617 },
{ "max1617a", max1617a },
{ "thmc10", thmc10 },
{ "lm84", lm84 },
{ "gl523sm", gl523sm },
{ "mc1066", mc1066 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm1021_id);
mutex_lock(&data->update_lock);
/* This is the driver that will be inserted */
static struct i2c_driver adm1021_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adm1021",
},
.probe = adm1021_probe,
.id_table = adm1021_id,
.detect = adm1021_detect,
.address_list = normal_i2c,
};
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
int i;
dev_dbg(dev, "Starting adm1021 update\n");
for (i = 0; i < 2; i++) {
data->temp[i] = 1000 *
(s8) i2c_smbus_read_byte_data(
client, ADM1021_REG_TEMP(i));
data->temp_max[i] = 1000 *
(s8) i2c_smbus_read_byte_data(
client, ADM1021_REG_TOS_R(i));
if (data->type != lm84) {
data->temp_min[i] = 1000 *
(s8) i2c_smbus_read_byte_data(client,
ADM1021_REG_THYST_R(i));
}
}
data->alarms = i2c_smbus_read_byte_data(client,
ADM1021_REG_STATUS) & 0x7c;
if (data->type == adm1023) {
/*
* The ADM1023 provides 3 extra bits of precision for
* the remote sensor in extra registers.
*/
data->temp[1] += 125 * (i2c_smbus_read_byte_data(
client, ADM1023_REG_REM_TEMP_PREC) >> 5);
data->temp_max[1] += 125 * (i2c_smbus_read_byte_data(
client, ADM1023_REG_REM_TOS_PREC) >> 5);
data->temp_min[1] += 125 * (i2c_smbus_read_byte_data(
client, ADM1023_REG_REM_THYST_PREC) >> 5);
data->remote_temp_offset =
i2c_smbus_read_byte_data(client,
ADM1023_REG_REM_OFFSET);
data->remote_temp_offset_prec =
i2c_smbus_read_byte_data(client,
ADM1023_REG_REM_OFFSET_PREC);
}
data->last_updated = jiffies;
data->valid = 1;
}
mutex_unlock(&data->update_lock);
return data;
}
static ssize_t show_temp(struct device *dev,
struct device_attribute *devattr, char *buf)
......@@ -411,6 +433,15 @@ static int adm1021_detect(struct i2c_client *client,
return 0;
}
static void adm1021_init_client(struct i2c_client *client)
{
/* Enable ADC and disable suspend mode */
i2c_smbus_write_byte_data(client, ADM1021_REG_CONFIG_W,
i2c_smbus_read_byte_data(client, ADM1021_REG_CONFIG_R) & 0xBF);
/* Set Conversion rate to 1/sec (this can be tinkered with) */
i2c_smbus_write_byte_data(client, ADM1021_REG_CONV_RATE_W, 0x04);
}
static int adm1021_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
......@@ -440,69 +471,29 @@ static int adm1021_probe(struct i2c_client *client,
return PTR_ERR_OR_ZERO(hwmon_dev);
}
static void adm1021_init_client(struct i2c_client *client)
{
/* Enable ADC and disable suspend mode */
i2c_smbus_write_byte_data(client, ADM1021_REG_CONFIG_W,
i2c_smbus_read_byte_data(client, ADM1021_REG_CONFIG_R) & 0xBF);
/* Set Conversion rate to 1/sec (this can be tinkered with) */
i2c_smbus_write_byte_data(client, ADM1021_REG_CONV_RATE_W, 0x04);
}
static struct adm1021_data *adm1021_update_device(struct device *dev)
{
struct adm1021_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
int i;
dev_dbg(dev, "Starting adm1021 update\n");
for (i = 0; i < 2; i++) {
data->temp[i] = 1000 *
(s8) i2c_smbus_read_byte_data(
client, ADM1021_REG_TEMP(i));
data->temp_max[i] = 1000 *
(s8) i2c_smbus_read_byte_data(
client, ADM1021_REG_TOS_R(i));
if (data->type != lm84) {
data->temp_min[i] = 1000 *
(s8) i2c_smbus_read_byte_data(client,
ADM1021_REG_THYST_R(i));
}
}
data->alarms = i2c_smbus_read_byte_data(client,
ADM1021_REG_STATUS) & 0x7c;
if (data->type == adm1023) {
/*
* The ADM1023 provides 3 extra bits of precision for
* the remote sensor in extra registers.
*/
data->temp[1] += 125 * (i2c_smbus_read_byte_data(
client, ADM1023_REG_REM_TEMP_PREC) >> 5);
data->temp_max[1] += 125 * (i2c_smbus_read_byte_data(
client, ADM1023_REG_REM_TOS_PREC) >> 5);
data->temp_min[1] += 125 * (i2c_smbus_read_byte_data(
client, ADM1023_REG_REM_THYST_PREC) >> 5);
data->remote_temp_offset =
i2c_smbus_read_byte_data(client,
ADM1023_REG_REM_OFFSET);
data->remote_temp_offset_prec =
i2c_smbus_read_byte_data(client,
ADM1023_REG_REM_OFFSET_PREC);
}
data->last_updated = jiffies;
data->valid = 1;
}
mutex_unlock(&data->update_lock);
static const struct i2c_device_id adm1021_id[] = {
{ "adm1021", adm1021 },
{ "adm1023", adm1023 },
{ "max1617", max1617 },
{ "max1617a", max1617a },
{ "thmc10", thmc10 },
{ "lm84", lm84 },
{ "gl523sm", gl523sm },
{ "mc1066", mc1066 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm1021_id);
return data;
}
static struct i2c_driver adm1021_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adm1021",
},
.probe = adm1021_probe,
.id_table = adm1021_id,
.detect = adm1021_detect,
.address_list = normal_i2c,
};
module_i2c_driver(adm1021_driver);
......
......@@ -102,47 +102,13 @@ static const int in_scale[6] = { 2500, 2250, 3300, 5000, 12000, 3300 };
(((val) < 0 ? (val) - 500 : \
(val) + 500) / 1000))
/*
* Functions declaration
*/
static int adm1025_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int adm1025_detect(struct i2c_client *client,
struct i2c_board_info *info);
static void adm1025_init_client(struct i2c_client *client);
static int adm1025_remove(struct i2c_client *client);
static struct adm1025_data *adm1025_update_device(struct device *dev);
/*
* Driver data (common to all clients)
*/
static const struct i2c_device_id adm1025_id[] = {
{ "adm1025", adm1025 },
{ "ne1619", ne1619 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm1025_id);
static struct i2c_driver adm1025_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adm1025",
},
.probe = adm1025_probe,
.remove = adm1025_remove,
.id_table = adm1025_id,
.detect = adm1025_detect,
.address_list = normal_i2c,
};
/*
* Client data (each client gets its own)
*/
struct adm1025_data {
struct device *hwmon_dev;
struct i2c_client *client;
const struct attribute_group *groups[3];
struct mutex update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
......@@ -158,6 +124,51 @@ struct adm1025_data {
u8 vrm;
};
static struct adm1025_data *adm1025_update_device(struct device *dev)
{
struct adm1025_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
int i;
dev_dbg(&client->dev, "Updating data.\n");
for (i = 0; i < 6; i++) {
data->in[i] = i2c_smbus_read_byte_data(client,
ADM1025_REG_IN(i));
data->in_min[i] = i2c_smbus_read_byte_data(client,
ADM1025_REG_IN_MIN(i));
data->in_max[i] = i2c_smbus_read_byte_data(client,
ADM1025_REG_IN_MAX(i));
}
for (i = 0; i < 2; i++) {
data->temp[i] = i2c_smbus_read_byte_data(client,
ADM1025_REG_TEMP(i));
data->temp_min[i] = i2c_smbus_read_byte_data(client,
ADM1025_REG_TEMP_LOW(i));
data->temp_max[i] = i2c_smbus_read_byte_data(client,
ADM1025_REG_TEMP_HIGH(i));
}
data->alarms = i2c_smbus_read_byte_data(client,
ADM1025_REG_STATUS1)
| (i2c_smbus_read_byte_data(client,
ADM1025_REG_STATUS2) << 8);
data->vid = (i2c_smbus_read_byte_data(client,
ADM1025_REG_VID) & 0x0f)
| ((i2c_smbus_read_byte_data(client,
ADM1025_REG_VID4) & 0x01) << 4);
data->last_updated = jiffies;
data->valid = 1;
}
mutex_unlock(&data->update_lock);
return data;
}
/*
* Sysfs stuff
*/
......@@ -217,8 +228,8 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int index = to_sensor_dev_attr(attr)->index;
struct i2c_client *client = to_i2c_client(dev);
struct adm1025_data *data = i2c_get_clientdata(client);
struct adm1025_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long val;
int err;
......@@ -238,8 +249,8 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int index = to_sensor_dev_attr(attr)->index;
struct i2c_client *client = to_i2c_client(dev);
struct adm1025_data *data = i2c_get_clientdata(client);
struct adm1025_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long val;
int err;
......@@ -273,8 +284,8 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int index = to_sensor_dev_attr(attr)->index;
struct i2c_client *client = to_i2c_client(dev);
struct adm1025_data *data = i2c_get_clientdata(client);
struct adm1025_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long val;
int err;
......@@ -294,8 +305,8 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int index = to_sensor_dev_attr(attr)->index;
struct i2c_client *client = to_i2c_client(dev);
struct adm1025_data *data = i2c_get_clientdata(client);
struct adm1025_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long val;
int err;
......@@ -470,51 +481,6 @@ static int adm1025_detect(struct i2c_client *client,
return 0;
}
static int adm1025_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct adm1025_data *data;
int err;
u8 config;
data = devm_kzalloc(&client->dev, sizeof(struct adm1025_data),
GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
/* Initialize the ADM1025 chip */
adm1025_init_client(client);
/* Register sysfs hooks */
err = sysfs_create_group(&client->dev.kobj, &adm1025_group);
if (err)
return err;
/* Pin 11 is either in4 (+12V) or VID4 */
config = i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG);
if (!(config & 0x20)) {
err = sysfs_create_group(&client->dev.kobj, &adm1025_group_in4);
if (err)
goto exit_remove;
}
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
return 0;
exit_remove:
sysfs_remove_group(&client->dev.kobj, &adm1025_group);
sysfs_remove_group(&client->dev.kobj, &adm1025_group_in4);
return err;
}
static void adm1025_init_client(struct i2c_client *client)
{
u8 reg;
......@@ -557,61 +523,54 @@ static void adm1025_init_client(struct i2c_client *client)
(reg&0x7E)|0x01);
}
static int adm1025_remove(struct i2c_client *client)
static int adm1025_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct adm1025_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &adm1025_group);
sysfs_remove_group(&client->dev.kobj, &adm1025_group_in4);
return 0;
}
struct device *dev = &client->dev;
struct device *hwmon_dev;
struct adm1025_data *data;
u8 config;
static struct adm1025_data *adm1025_update_device(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1025_data *data = i2c_get_clientdata(client);
data = devm_kzalloc(dev, sizeof(struct adm1025_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
mutex_lock(&data->update_lock);
i2c_set_clientdata(client, data);
data->client = client;
mutex_init(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
int i;
/* Initialize the ADM1025 chip */
adm1025_init_client(client);
dev_dbg(&client->dev, "Updating data.\n");
for (i = 0; i < 6; i++) {
data->in[i] = i2c_smbus_read_byte_data(client,
ADM1025_REG_IN(i));
data->in_min[i] = i2c_smbus_read_byte_data(client,
ADM1025_REG_IN_MIN(i));
data->in_max[i] = i2c_smbus_read_byte_data(client,
ADM1025_REG_IN_MAX(i));
}
for (i = 0; i < 2; i++) {
data->temp[i] = i2c_smbus_read_byte_data(client,
ADM1025_REG_TEMP(i));
data->temp_min[i] = i2c_smbus_read_byte_data(client,
ADM1025_REG_TEMP_LOW(i));
data->temp_max[i] = i2c_smbus_read_byte_data(client,
ADM1025_REG_TEMP_HIGH(i));
}
data->alarms = i2c_smbus_read_byte_data(client,
ADM1025_REG_STATUS1)
| (i2c_smbus_read_byte_data(client,
ADM1025_REG_STATUS2) << 8);
data->vid = (i2c_smbus_read_byte_data(client,
ADM1025_REG_VID) & 0x0f)
| ((i2c_smbus_read_byte_data(client,
ADM1025_REG_VID4) & 0x01) << 4);
/* sysfs hooks */
data->groups[0] = &adm1025_group;
/* Pin 11 is either in4 (+12V) or VID4 */
config = i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG);
if (!(config & 0x20))
data->groups[1] = &adm1025_group_in4;
data->last_updated = jiffies;
data->valid = 1;
}
hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
data, data->groups);
return PTR_ERR_OR_ZERO(hwmon_dev);
}
mutex_unlock(&data->update_lock);
static const struct i2c_device_id adm1025_id[] = {
{ "adm1025", adm1025 },
{ "ne1619", ne1619 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm1025_id);
return data;
}
static struct i2c_driver adm1025_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adm1025",
},
.probe = adm1025_probe,
.id_table = adm1025_id,
.detect = adm1025_detect,
.address_list = normal_i2c,
};
module_i2c_driver(adm1025_driver);
......
此差异已折叠。
......@@ -105,46 +105,12 @@ static const u8 ADM1029_REG_FAN_DIV[] = {
ADM1029_REG_FAN2_CONFIG,
};
/*
* Functions declaration
*/
static int adm1029_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int adm1029_detect(struct i2c_client *client,
struct i2c_board_info *info);
static int adm1029_remove(struct i2c_client *client);
static struct adm1029_data *adm1029_update_device(struct device *dev);
static int adm1029_init_client(struct i2c_client *client);
/*
* Driver data (common to all clients)
*/
static const struct i2c_device_id adm1029_id[] = {
{ "adm1029", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm1029_id);
static struct i2c_driver adm1029_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adm1029",
},
.probe = adm1029_probe,
.remove = adm1029_remove,
.id_table = adm1029_id,
.detect = adm1029_detect,
.address_list = normal_i2c,
};
/*
* Client data (each client gets its own)
*/
struct adm1029_data {
struct device *hwmon_dev;
struct i2c_client *client;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
......@@ -155,6 +121,50 @@ struct adm1029_data {
u8 fan_div[ARRAY_SIZE(ADM1029_REG_FAN_DIV)];
};
/*
* function that update the status of the chips (temperature for example)
*/
static struct adm1029_data *adm1029_update_device(struct device *dev)
{
struct adm1029_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
mutex_lock(&data->update_lock);
/*
* Use the "cache" Luke, don't recheck values
* if there are already checked not a long time later
*/
if (time_after(jiffies, data->last_updated + HZ * 2)
|| !data->valid) {
int nr;
dev_dbg(&client->dev, "Updating adm1029 data\n");
for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_TEMP); nr++) {
data->temp[nr] =
i2c_smbus_read_byte_data(client,
ADM1029_REG_TEMP[nr]);
}
for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_FAN); nr++) {
data->fan[nr] =
i2c_smbus_read_byte_data(client,
ADM1029_REG_FAN[nr]);
}
for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_FAN_DIV); nr++) {
data->fan_div[nr] =
i2c_smbus_read_byte_data(client,
ADM1029_REG_FAN_DIV[nr]);
}
data->last_updated = jiffies;
data->valid = 1;
}
mutex_unlock(&data->update_lock);
return data;
}
/*
* Sysfs stuff
*/
......@@ -197,8 +207,8 @@ show_fan_div(struct device *dev, struct device_attribute *devattr, char *buf)
static ssize_t set_fan_div(struct device *dev,
struct device_attribute *devattr, const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1029_data *data = i2c_get_clientdata(client);
struct adm1029_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
u8 reg;
long val;
......@@ -270,7 +280,7 @@ static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR,
static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
show_fan_div, set_fan_div, 1);
static struct attribute *adm1029_attributes[] = {
static struct attribute *adm1029_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_min.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
......@@ -289,9 +299,7 @@ static struct attribute *adm1029_attributes[] = {
NULL
};
static const struct attribute_group adm1029_group = {
.attrs = adm1029_attributes,
};
ATTRIBUTE_GROUPS(adm1029);
/*
* Real code
......@@ -340,48 +348,10 @@ static int adm1029_detect(struct i2c_client *client,
return 0;
}
static int adm1029_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct adm1029_data *data;
int err;
data = devm_kzalloc(&client->dev, sizeof(struct adm1029_data),
GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
/*
* Initialize the ADM1029 chip
* Check config register
*/
if (adm1029_init_client(client) == 0)
return -ENODEV;
/* Register sysfs hooks */
err = sysfs_create_group(&client->dev.kobj, &adm1029_group);
if (err)
return err;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
goto exit_remove_files;
}
return 0;
exit_remove_files:
sysfs_remove_group(&client->dev.kobj, &adm1029_group);
return err;
}
static int adm1029_init_client(struct i2c_client *client)
{
u8 config;
config = i2c_smbus_read_byte_data(client, ADM1029_REG_CONFIG);
if ((config & 0x10) == 0) {
i2c_smbus_write_byte_data(client, ADM1029_REG_CONFIG,
......@@ -396,59 +366,49 @@ static int adm1029_init_client(struct i2c_client *client)
return 1;
}
static int adm1029_remove(struct i2c_client *client)
static int adm1029_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct adm1029_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &adm1029_group);
struct device *dev = &client->dev;
struct adm1029_data *data;
struct device *hwmon_dev;
return 0;
}
data = devm_kzalloc(dev, sizeof(struct adm1029_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
/*
* function that update the status of the chips (temperature for example)
*/
static struct adm1029_data *adm1029_update_device(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1029_data *data = i2c_get_clientdata(client);
data->client = client;
mutex_init(&data->update_lock);
mutex_lock(&data->update_lock);
/*
* Use the "cache" Luke, don't recheck values
* if there are already checked not a long time later
* Initialize the ADM1029 chip
* Check config register
*/
if (time_after(jiffies, data->last_updated + HZ * 2)
|| !data->valid) {
int nr;
dev_dbg(&client->dev, "Updating adm1029 data\n");
for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_TEMP); nr++) {
data->temp[nr] =
i2c_smbus_read_byte_data(client,
ADM1029_REG_TEMP[nr]);
}
for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_FAN); nr++) {
data->fan[nr] =
i2c_smbus_read_byte_data(client,
ADM1029_REG_FAN[nr]);
}
for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_FAN_DIV); nr++) {
data->fan_div[nr] =
i2c_smbus_read_byte_data(client,
ADM1029_REG_FAN_DIV[nr]);
}
if (adm1029_init_client(client) == 0)
return -ENODEV;
data->last_updated = jiffies;
data->valid = 1;
}
hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
data,
adm1029_groups);
return PTR_ERR_OR_ZERO(hwmon_dev);
}
mutex_unlock(&data->update_lock);
static const struct i2c_device_id adm1029_id[] = {
{ "adm1029", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm1029_id);
return data;
}
static struct i2c_driver adm1029_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adm1029",
},
.probe = adm1029_probe,
.id_table = adm1029_id,
.detect = adm1029_detect,
.address_list = normal_i2c,
};
module_i2c_driver(adm1029_driver);
......
......@@ -74,7 +74,8 @@ typedef u8 auto_chan_table_t[8][2];
/* Each client has this additional data */
struct adm1031_data {
struct device *hwmon_dev;
struct i2c_client *client;
const struct attribute_group *groups[3];
struct mutex update_lock;
int chip_type;
char valid; /* !=0 if following fields are valid */
......@@ -105,34 +106,6 @@ struct adm1031_data {
s8 temp_crit[3];
};
static int adm1031_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int adm1031_detect(struct i2c_client *client,
struct i2c_board_info *info);
static void adm1031_init_client(struct i2c_client *client);
static int adm1031_remove(struct i2c_client *client);
static struct adm1031_data *adm1031_update_device(struct device *dev);
static const struct i2c_device_id adm1031_id[] = {
{ "adm1030", adm1030 },
{ "adm1031", adm1031 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm1031_id);
/* This is the driver that will be inserted */
static struct i2c_driver adm1031_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adm1031",
},
.probe = adm1031_probe,
.remove = adm1031_remove,
.id_table = adm1031_id,
.detect = adm1031_detect,
.address_list = normal_i2c,
};
static inline u8 adm1031_read_value(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
......@@ -144,6 +117,96 @@ adm1031_write_value(struct i2c_client *client, u8 reg, unsigned int value)
return i2c_smbus_write_byte_data(client, reg, value);
}
static struct adm1031_data *adm1031_update_device(struct device *dev)
{
struct adm1031_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
unsigned long next_update;
int chan;
mutex_lock(&data->update_lock);
next_update = data->last_updated
+ msecs_to_jiffies(data->update_interval);
if (time_after(jiffies, next_update) || !data->valid) {
dev_dbg(&client->dev, "Starting adm1031 update\n");
for (chan = 0;
chan < ((data->chip_type == adm1031) ? 3 : 2); chan++) {
u8 oldh, newh;
oldh =
adm1031_read_value(client, ADM1031_REG_TEMP(chan));
data->ext_temp[chan] =
adm1031_read_value(client, ADM1031_REG_EXT_TEMP);
newh =
adm1031_read_value(client, ADM1031_REG_TEMP(chan));
if (newh != oldh) {
data->ext_temp[chan] =
adm1031_read_value(client,
ADM1031_REG_EXT_TEMP);
#ifdef DEBUG
oldh =
adm1031_read_value(client,
ADM1031_REG_TEMP(chan));
/* oldh is actually newer */
if (newh != oldh)
dev_warn(&client->dev,
"Remote temperature may be wrong.\n");
#endif
}
data->temp[chan] = newh;
data->temp_offset[chan] =
adm1031_read_value(client,
ADM1031_REG_TEMP_OFFSET(chan));
data->temp_min[chan] =
adm1031_read_value(client,
ADM1031_REG_TEMP_MIN(chan));
data->temp_max[chan] =
adm1031_read_value(client,
ADM1031_REG_TEMP_MAX(chan));
data->temp_crit[chan] =
adm1031_read_value(client,
ADM1031_REG_TEMP_CRIT(chan));
data->auto_temp[chan] =
adm1031_read_value(client,
ADM1031_REG_AUTO_TEMP(chan));
}
data->conf1 = adm1031_read_value(client, ADM1031_REG_CONF1);
data->conf2 = adm1031_read_value(client, ADM1031_REG_CONF2);
data->alarm = adm1031_read_value(client, ADM1031_REG_STATUS(0))
| (adm1031_read_value(client, ADM1031_REG_STATUS(1)) << 8);
if (data->chip_type == adm1030)
data->alarm &= 0xc0ff;
for (chan = 0; chan < (data->chip_type == adm1030 ? 1 : 2);
chan++) {
data->fan_div[chan] =
adm1031_read_value(client,
ADM1031_REG_FAN_DIV(chan));
data->fan_min[chan] =
adm1031_read_value(client,
ADM1031_REG_FAN_MIN(chan));
data->fan[chan] =
adm1031_read_value(client,
ADM1031_REG_FAN_SPEED(chan));
data->pwm[chan] =
(adm1031_read_value(client,
ADM1031_REG_PWM) >> (4 * chan)) & 0x0f;
}
data->last_updated = jiffies;
data->valid = 1;
}
mutex_unlock(&data->update_lock);
return data;
}
#define TEMP_TO_REG(val) (((val) < 0 ? ((val - 500) / 1000) : \
((val + 500) / 1000)))
......@@ -280,8 +343,8 @@ static ssize_t
set_fan_auto_channel(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1031_data *data = i2c_get_clientdata(client);
struct adm1031_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
long val;
u8 reg;
......@@ -355,8 +418,8 @@ static ssize_t
set_auto_temp_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1031_data *data = i2c_get_clientdata(client);
struct adm1031_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
long val;
int ret;
......@@ -385,8 +448,8 @@ static ssize_t
set_auto_temp_max(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1031_data *data = i2c_get_clientdata(client);
struct adm1031_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
long val;
int ret;
......@@ -428,8 +491,8 @@ static ssize_t show_pwm(struct device *dev,
static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1031_data *data = i2c_get_clientdata(client);
struct adm1031_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
long val;
int ret, reg;
......@@ -541,8 +604,8 @@ static ssize_t show_fan_min(struct device *dev,
static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1031_data *data = i2c_get_clientdata(client);
struct adm1031_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
long val;
int ret;
......@@ -565,8 +628,8 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1031_data *data = i2c_get_clientdata(client);
struct adm1031_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
long val;
u8 tmp;
......@@ -667,8 +730,8 @@ static ssize_t set_temp_offset(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1031_data *data = i2c_get_clientdata(client);
struct adm1031_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
long val;
int ret;
......@@ -688,8 +751,8 @@ static ssize_t set_temp_offset(struct device *dev,
static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1031_data *data = i2c_get_clientdata(client);
struct adm1031_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
long val;
int ret;
......@@ -709,8 +772,8 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1031_data *data = i2c_get_clientdata(client);
struct adm1031_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
long val;
int ret;
......@@ -730,8 +793,8 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1031_data *data = i2c_get_clientdata(client);
struct adm1031_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int nr = to_sensor_dev_attr(attr)->index;
long val;
int ret;
......@@ -807,8 +870,7 @@ static const unsigned int update_intervals[] = {
static ssize_t show_update_interval(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1031_data *data = i2c_get_clientdata(client);
struct adm1031_data *data = dev_get_drvdata(dev);
return sprintf(buf, "%u\n", data->update_interval);
}
......@@ -817,8 +879,8 @@ static ssize_t set_update_interval(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1031_data *data = i2c_get_clientdata(client);
struct adm1031_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
unsigned long val;
int i, err;
u8 reg;
......@@ -950,64 +1012,6 @@ static int adm1031_detect(struct i2c_client *client,
return 0;
}
static int adm1031_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct adm1031_data *data;
int err;
data = devm_kzalloc(&client->dev, sizeof(struct adm1031_data),
GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(client, data);
data->chip_type = id->driver_data;
mutex_init(&data->update_lock);
if (data->chip_type == adm1030)
data->chan_select_table = &auto_channel_select_table_adm1030;
else
data->chan_select_table = &auto_channel_select_table_adm1031;
/* Initialize the ADM1031 chip */
adm1031_init_client(client);
/* Register sysfs hooks */
err = sysfs_create_group(&client->dev.kobj, &adm1031_group);
if (err)
return err;
if (data->chip_type == adm1031) {
err = sysfs_create_group(&client->dev.kobj, &adm1031_group_opt);
if (err)
goto exit_remove;
}
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
return 0;
exit_remove:
sysfs_remove_group(&client->dev.kobj, &adm1031_group);
sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt);
return err;
}
static int adm1031_remove(struct i2c_client *client)
{
struct adm1031_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &adm1031_group);
sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt);
return 0;
}
static void adm1031_init_client(struct i2c_client *client)
{
unsigned int read_val;
......@@ -1039,96 +1043,57 @@ static void adm1031_init_client(struct i2c_client *client)
data->update_interval = update_intervals[i];
}
static struct adm1031_data *adm1031_update_device(struct device *dev)
static int adm1031_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm1031_data *data = i2c_get_clientdata(client);
unsigned long next_update;
int chan;
mutex_lock(&data->update_lock);
next_update = data->last_updated
+ msecs_to_jiffies(data->update_interval);
if (time_after(jiffies, next_update) || !data->valid) {
dev_dbg(&client->dev, "Starting adm1031 update\n");
for (chan = 0;
chan < ((data->chip_type == adm1031) ? 3 : 2); chan++) {
u8 oldh, newh;
oldh =
adm1031_read_value(client, ADM1031_REG_TEMP(chan));
data->ext_temp[chan] =
adm1031_read_value(client, ADM1031_REG_EXT_TEMP);
newh =
adm1031_read_value(client, ADM1031_REG_TEMP(chan));
if (newh != oldh) {
data->ext_temp[chan] =
adm1031_read_value(client,
ADM1031_REG_EXT_TEMP);
#ifdef DEBUG
oldh =
adm1031_read_value(client,
ADM1031_REG_TEMP(chan));
struct device *dev = &client->dev;
struct device *hwmon_dev;
struct adm1031_data *data;
/* oldh is actually newer */
if (newh != oldh)
dev_warn(&client->dev,
"Remote temperature may be wrong.\n");
#endif
}
data->temp[chan] = newh;
data = devm_kzalloc(dev, sizeof(struct adm1031_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->temp_offset[chan] =
adm1031_read_value(client,
ADM1031_REG_TEMP_OFFSET(chan));
data->temp_min[chan] =
adm1031_read_value(client,
ADM1031_REG_TEMP_MIN(chan));
data->temp_max[chan] =
adm1031_read_value(client,
ADM1031_REG_TEMP_MAX(chan));
data->temp_crit[chan] =
adm1031_read_value(client,
ADM1031_REG_TEMP_CRIT(chan));
data->auto_temp[chan] =
adm1031_read_value(client,
ADM1031_REG_AUTO_TEMP(chan));
i2c_set_clientdata(client, data);
data->client = client;
data->chip_type = id->driver_data;
mutex_init(&data->update_lock);
}
if (data->chip_type == adm1030)
data->chan_select_table = &auto_channel_select_table_adm1030;
else
data->chan_select_table = &auto_channel_select_table_adm1031;
data->conf1 = adm1031_read_value(client, ADM1031_REG_CONF1);
data->conf2 = adm1031_read_value(client, ADM1031_REG_CONF2);
/* Initialize the ADM1031 chip */
adm1031_init_client(client);
data->alarm = adm1031_read_value(client, ADM1031_REG_STATUS(0))
| (adm1031_read_value(client, ADM1031_REG_STATUS(1)) << 8);
if (data->chip_type == adm1030)
data->alarm &= 0xc0ff;
/* sysfs hooks */
data->groups[0] = &adm1031_group;
if (data->chip_type == adm1031)
data->groups[1] = &adm1031_group_opt;
for (chan = 0; chan < (data->chip_type == adm1030 ? 1 : 2);
chan++) {
data->fan_div[chan] =
adm1031_read_value(client,
ADM1031_REG_FAN_DIV(chan));
data->fan_min[chan] =
adm1031_read_value(client,
ADM1031_REG_FAN_MIN(chan));
data->fan[chan] =
adm1031_read_value(client,
ADM1031_REG_FAN_SPEED(chan));
data->pwm[chan] =
(adm1031_read_value(client,
ADM1031_REG_PWM) >> (4 * chan)) & 0x0f;
}
data->last_updated = jiffies;
data->valid = 1;
}
hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
data, data->groups);
return PTR_ERR_OR_ZERO(hwmon_dev);
}
mutex_unlock(&data->update_lock);
static const struct i2c_device_id adm1031_id[] = {
{ "adm1030", adm1030 },
{ "adm1031", adm1031 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm1031_id);
return data;
}
static struct i2c_driver adm1031_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adm1031",
},
.probe = adm1031_probe,
.id_table = adm1031_id,
.detect = adm1031_detect,
.address_list = normal_i2c,
};
module_i2c_driver(adm1031_driver);
......
......@@ -130,38 +130,9 @@ static inline unsigned int AOUT_FROM_REG(u8 reg)
return SCALE(reg, 1250, 255);
}
static int adm9240_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int adm9240_detect(struct i2c_client *client,
struct i2c_board_info *info);
static void adm9240_init_client(struct i2c_client *client);
static int adm9240_remove(struct i2c_client *client);
static struct adm9240_data *adm9240_update_device(struct device *dev);
/* driver data */
static const struct i2c_device_id adm9240_id[] = {
{ "adm9240", adm9240 },
{ "ds1780", ds1780 },
{ "lm81", lm81 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm9240_id);
static struct i2c_driver adm9240_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adm9240",
},
.probe = adm9240_probe,
.remove = adm9240_remove,
.id_table = adm9240_id,
.detect = adm9240_detect,
.address_list = normal_i2c,
};
/* per client data */
struct adm9240_data {
struct device *hwmon_dev;
struct i2c_client *client;
struct mutex update_lock;
char valid;
unsigned long last_updated_measure;
......@@ -181,6 +152,110 @@ struct adm9240_data {
u8 vrm; /* -- vrm set on startup, no accessor */
};
/* write new fan div, callers must hold data->update_lock */
static void adm9240_write_fan_div(struct i2c_client *client, int nr,
u8 fan_div)
{
u8 reg, old, shift = (nr + 2) * 2;
reg = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
old = (reg >> shift) & 3;
reg &= ~(3 << shift);
reg |= (fan_div << shift);
i2c_smbus_write_byte_data(client, ADM9240_REG_VID_FAN_DIV, reg);
dev_dbg(&client->dev,
"fan%d clock divider changed from %u to %u\n",
nr + 1, 1 << old, 1 << fan_div);
}
static struct adm9240_data *adm9240_update_device(struct device *dev)
{
struct adm9240_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int i;
mutex_lock(&data->update_lock);
/* minimum measurement cycle: 1.75 seconds */
if (time_after(jiffies, data->last_updated_measure + (HZ * 7 / 4))
|| !data->valid) {
for (i = 0; i < 6; i++) { /* read voltages */
data->in[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_IN(i));
}
data->alarms = i2c_smbus_read_byte_data(client,
ADM9240_REG_INT(0)) |
i2c_smbus_read_byte_data(client,
ADM9240_REG_INT(1)) << 8;
/*
* read temperature: assume temperature changes less than
* 0.5'C per two measurement cycles thus ignore possible
* but unlikely aliasing error on lsb reading. --Grant
*/
data->temp = ((i2c_smbus_read_byte_data(client,
ADM9240_REG_TEMP) << 8) |
i2c_smbus_read_byte_data(client,
ADM9240_REG_TEMP_CONF)) / 128;
for (i = 0; i < 2; i++) { /* read fans */
data->fan[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_FAN(i));
/* adjust fan clock divider on overflow */
if (data->valid && data->fan[i] == 255 &&
data->fan_div[i] < 3) {
adm9240_write_fan_div(client, i,
++data->fan_div[i]);
/* adjust fan_min if active, but not to 0 */
if (data->fan_min[i] < 255 &&
data->fan_min[i] >= 2)
data->fan_min[i] /= 2;
}
}
data->last_updated_measure = jiffies;
}
/* minimum config reading cycle: 300 seconds */
if (time_after(jiffies, data->last_updated_config + (HZ * 300))
|| !data->valid) {
for (i = 0; i < 6; i++) {
data->in_min[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_IN_MIN(i));
data->in_max[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_IN_MAX(i));
}
for (i = 0; i < 2; i++) {
data->fan_min[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_FAN_MIN(i));
}
data->temp_max[0] = i2c_smbus_read_byte_data(client,
ADM9240_REG_TEMP_MAX(0));
data->temp_max[1] = i2c_smbus_read_byte_data(client,
ADM9240_REG_TEMP_MAX(1));
/* read fan divs and 5-bit VID */
i = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
data->fan_div[0] = (i >> 4) & 3;
data->fan_div[1] = (i >> 6) & 3;
data->vid = i & 0x0f;
data->vid |= (i2c_smbus_read_byte_data(client,
ADM9240_REG_VID4) & 1) << 4;
/* read analog out */
data->aout = i2c_smbus_read_byte_data(client,
ADM9240_REG_ANALOG_OUT);
data->last_updated_config = jiffies;
data->valid = 1;
}
mutex_unlock(&data->update_lock);
return data;
}
/*** sysfs accessors ***/
/* temperature */
......@@ -203,8 +278,8 @@ static ssize_t set_max(struct device *dev, struct device_attribute *devattr,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adm9240_data *data = i2c_get_clientdata(client);
struct adm9240_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long val;
int err;
......@@ -259,8 +334,8 @@ static ssize_t set_in_min(struct device *dev,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adm9240_data *data = i2c_get_clientdata(client);
struct adm9240_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
unsigned long val;
int err;
......@@ -281,8 +356,8 @@ static ssize_t set_in_max(struct device *dev,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adm9240_data *data = i2c_get_clientdata(client);
struct adm9240_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
unsigned long val;
int err;
......@@ -340,22 +415,6 @@ static ssize_t show_fan_div(struct device *dev,
return sprintf(buf, "%d\n", 1 << data->fan_div[attr->index]);
}
/* write new fan div, callers must hold data->update_lock */
static void adm9240_write_fan_div(struct i2c_client *client, int nr,
u8 fan_div)
{
u8 reg, old, shift = (nr + 2) * 2;
reg = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
old = (reg >> shift) & 3;
reg &= ~(3 << shift);
reg |= (fan_div << shift);
i2c_smbus_write_byte_data(client, ADM9240_REG_VID_FAN_DIV, reg);
dev_dbg(&client->dev,
"fan%d clock divider changed from %u to %u\n",
nr + 1, 1 << old, 1 << fan_div);
}
/*
* set fan speed low limit:
*
......@@ -372,8 +431,8 @@ static ssize_t set_fan_min(struct device *dev,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adm9240_data *data = i2c_get_clientdata(client);
struct adm9240_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int nr = attr->index;
u8 new_div;
unsigned long val;
......@@ -485,8 +544,8 @@ static ssize_t set_aout(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm9240_data *data = i2c_get_clientdata(client);
struct adm9240_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long val;
int err;
......@@ -506,8 +565,8 @@ static ssize_t chassis_clear(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm9240_data *data = i2c_get_clientdata(client);
struct adm9240_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
unsigned long val;
if (kstrtoul(buf, 10, &val) || val != 0)
......@@ -524,7 +583,7 @@ static ssize_t chassis_clear(struct device *dev,
static SENSOR_DEVICE_ATTR(intrusion0_alarm, S_IRUGO | S_IWUSR, show_alarm,
chassis_clear, 12);
static struct attribute *adm9240_attributes[] = {
static struct attribute *adm9240_attrs[] = {
&sensor_dev_attr_in0_input.dev_attr.attr,
&sensor_dev_attr_in0_min.dev_attr.attr,
&sensor_dev_attr_in0_max.dev_attr.attr,
......@@ -568,9 +627,7 @@ static struct attribute *adm9240_attributes[] = {
NULL
};
static const struct attribute_group adm9240_group = {
.attrs = adm9240_attributes,
};
ATTRIBUTE_GROUPS(adm9240);
/*** sensor chip detect and driver install ***/
......@@ -620,49 +677,6 @@ static int adm9240_detect(struct i2c_client *new_client,
return 0;
}
static int adm9240_probe(struct i2c_client *new_client,
const struct i2c_device_id *id)
{
struct adm9240_data *data;
int err;
data = devm_kzalloc(&new_client->dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(new_client, data);
mutex_init(&data->update_lock);
adm9240_init_client(new_client);
/* populate sysfs filesystem */
err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group);
if (err)
return err;
data->hwmon_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
return 0;
exit_remove:
sysfs_remove_group(&new_client->dev.kobj, &adm9240_group);
return err;
}
static int adm9240_remove(struct i2c_client *client)
{
struct adm9240_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &adm9240_group);
return 0;
}
static void adm9240_init_client(struct i2c_client *client)
{
struct adm9240_data *data = i2c_get_clientdata(client);
......@@ -705,93 +719,48 @@ static void adm9240_init_client(struct i2c_client *client)
}
}
static struct adm9240_data *adm9240_update_device(struct device *dev)
static int adm9240_probe(struct i2c_client *new_client,
const struct i2c_device_id *id)
{
struct i2c_client *client = to_i2c_client(dev);
struct adm9240_data *data = i2c_get_clientdata(client);
int i;
mutex_lock(&data->update_lock);
/* minimum measurement cycle: 1.75 seconds */
if (time_after(jiffies, data->last_updated_measure + (HZ * 7 / 4))
|| !data->valid) {
for (i = 0; i < 6; i++) { /* read voltages */
data->in[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_IN(i));
}
data->alarms = i2c_smbus_read_byte_data(client,
ADM9240_REG_INT(0)) |
i2c_smbus_read_byte_data(client,
ADM9240_REG_INT(1)) << 8;
/*
* read temperature: assume temperature changes less than
* 0.5'C per two measurement cycles thus ignore possible
* but unlikely aliasing error on lsb reading. --Grant
*/
data->temp = ((i2c_smbus_read_byte_data(client,
ADM9240_REG_TEMP) << 8) |
i2c_smbus_read_byte_data(client,
ADM9240_REG_TEMP_CONF)) / 128;
for (i = 0; i < 2; i++) { /* read fans */
data->fan[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_FAN(i));
/* adjust fan clock divider on overflow */
if (data->valid && data->fan[i] == 255 &&
data->fan_div[i] < 3) {
struct device *dev = &new_client->dev;
struct device *hwmon_dev;
struct adm9240_data *data;
adm9240_write_fan_div(client, i,
++data->fan_div[i]);
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
/* adjust fan_min if active, but not to 0 */
if (data->fan_min[i] < 255 &&
data->fan_min[i] >= 2)
data->fan_min[i] /= 2;
}
}
data->last_updated_measure = jiffies;
}
i2c_set_clientdata(new_client, data);
data->client = new_client;
mutex_init(&data->update_lock);
/* minimum config reading cycle: 300 seconds */
if (time_after(jiffies, data->last_updated_config + (HZ * 300))
|| !data->valid) {
adm9240_init_client(new_client);
for (i = 0; i < 6; i++) {
data->in_min[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_IN_MIN(i));
data->in_max[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_IN_MAX(i));
}
for (i = 0; i < 2; i++) {
data->fan_min[i] = i2c_smbus_read_byte_data(client,
ADM9240_REG_FAN_MIN(i));
}
data->temp_max[0] = i2c_smbus_read_byte_data(client,
ADM9240_REG_TEMP_MAX(0));
data->temp_max[1] = i2c_smbus_read_byte_data(client,
ADM9240_REG_TEMP_MAX(1));
hwmon_dev = devm_hwmon_device_register_with_groups(dev,
new_client->name,
data,
adm9240_groups);
return PTR_ERR_OR_ZERO(hwmon_dev);
}
/* read fan divs and 5-bit VID */
i = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
data->fan_div[0] = (i >> 4) & 3;
data->fan_div[1] = (i >> 6) & 3;
data->vid = i & 0x0f;
data->vid |= (i2c_smbus_read_byte_data(client,
ADM9240_REG_VID4) & 1) << 4;
/* read analog out */
data->aout = i2c_smbus_read_byte_data(client,
ADM9240_REG_ANALOG_OUT);
static const struct i2c_device_id adm9240_id[] = {
{ "adm9240", adm9240 },
{ "ds1780", ds1780 },
{ "lm81", lm81 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adm9240_id);
data->last_updated_config = jiffies;
data->valid = 1;
}
mutex_unlock(&data->update_lock);
return data;
}
static struct i2c_driver adm9240_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adm9240",
},
.probe = adm9240_probe,
.id_table = adm9240_id,
.detect = adm9240_detect,
.address_list = normal_i2c,
};
module_i2c_driver(adm9240_driver);
......
......@@ -198,7 +198,7 @@ static int ads1015_get_channels_config_of(struct i2c_client *client)
}
channel = be32_to_cpup(property);
if (channel > ADS1015_CHANNELS) {
if (channel >= ADS1015_CHANNELS) {
dev_err(&client->dev,
"invalid channel index %d on %s\n",
channel, node->full_name);
......
......@@ -50,7 +50,7 @@ enum ads7828_chips { ads7828, ads7830 };
/* Client specific data */
struct ads7828_data {
struct device *hwmon_dev;
struct i2c_client *client;
struct mutex update_lock; /* Mutex protecting updates */
unsigned long last_updated; /* Last updated time (in jiffies) */
u16 adc_input[ADS7828_NCH]; /* ADS7828_NCH samples */
......@@ -72,8 +72,8 @@ static inline u8 ads7828_cmd_byte(u8 cmd, int ch)
/* Update data for the device (all 8 channels) */
static struct ads7828_data *ads7828_update_device(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct ads7828_data *data = i2c_get_clientdata(client);
struct ads7828_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
mutex_lock(&data->update_lock);
......@@ -116,7 +116,7 @@ static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, ads7828_show_in, NULL, 5);
static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, ads7828_show_in, NULL, 6);
static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, ads7828_show_in, NULL, 7);
static struct attribute *ads7828_attributes[] = {
static struct attribute *ads7828_attrs[] = {
&sensor_dev_attr_in0_input.dev_attr.attr,
&sensor_dev_attr_in1_input.dev_attr.attr,
&sensor_dev_attr_in2_input.dev_attr.attr,
......@@ -128,29 +128,17 @@ static struct attribute *ads7828_attributes[] = {
NULL
};
static const struct attribute_group ads7828_group = {
.attrs = ads7828_attributes,
};
static int ads7828_remove(struct i2c_client *client)
{
struct ads7828_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &ads7828_group);
return 0;
}
ATTRIBUTE_GROUPS(ads7828);
static int ads7828_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ads7828_platform_data *pdata = dev_get_platdata(&client->dev);
struct device *dev = &client->dev;
struct ads7828_platform_data *pdata = dev_get_platdata(dev);
struct ads7828_data *data;
int err;
struct device *hwmon_dev;
data = devm_kzalloc(&client->dev, sizeof(struct ads7828_data),
GFP_KERNEL);
data = devm_kzalloc(dev, sizeof(struct ads7828_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
......@@ -182,24 +170,13 @@ static int ads7828_probe(struct i2c_client *client,
if (!data->diff_input)
data->cmd_byte |= ADS7828_CMD_SD_SE;
i2c_set_clientdata(client, data);
data->client = client;
mutex_init(&data->update_lock);
err = sysfs_create_group(&client->dev.kobj, &ads7828_group);
if (err)
return err;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
goto error;
}
return 0;
error:
sysfs_remove_group(&client->dev.kobj, &ads7828_group);
return err;
hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
data,
ads7828_groups);
return PTR_ERR_OR_ZERO(hwmon_dev);
}
static const struct i2c_device_id ads7828_device_ids[] = {
......@@ -216,7 +193,6 @@ static struct i2c_driver ads7828_driver = {
.id_table = ads7828_device_ids,
.probe = ads7828_probe,
.remove = ads7828_remove,
};
module_i2c_driver(ads7828_driver);
......
......@@ -51,7 +51,7 @@ struct adt7411_data {
struct mutex update_lock;
unsigned long next_update;
int vref_cached;
struct device *hwmon_dev;
struct i2c_client *client;
};
/*
......@@ -111,7 +111,8 @@ static int adt7411_modify_bit(struct i2c_client *client, u8 reg, u8 bit,
static ssize_t adt7411_show_vdd(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
struct adt7411_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int ret = adt7411_read_10_bit(client, ADT7411_REG_INT_TEMP_VDD_LSB,
ADT7411_REG_VDD_MSB, 2);
......@@ -121,7 +122,8 @@ static ssize_t adt7411_show_vdd(struct device *dev,
static ssize_t adt7411_show_temp(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
struct adt7411_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int val = adt7411_read_10_bit(client, ADT7411_REG_INT_TEMP_VDD_LSB,
ADT7411_REG_INT_TEMP_MSB, 0);
......@@ -137,8 +139,8 @@ static ssize_t adt7411_show_input(struct device *dev,
struct device_attribute *attr, char *buf)
{
int nr = to_sensor_dev_attr(attr)->index;
struct i2c_client *client = to_i2c_client(dev);
struct adt7411_data *data = i2c_get_clientdata(client);
struct adt7411_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int val;
u8 lsb_reg, lsb_shift;
......@@ -180,7 +182,8 @@ static ssize_t adt7411_show_bit(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7411_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int ret = i2c_smbus_read_byte_data(client, attr2->index);
return ret < 0 ? ret : sprintf(buf, "%u\n", !!(ret & attr2->nr));
......@@ -191,8 +194,8 @@ static ssize_t adt7411_set_bit(struct device *dev,
size_t count)
{
struct sensor_device_attribute_2 *s_attr2 = to_sensor_dev_attr_2(attr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7411_data *data = i2c_get_clientdata(client);
struct adt7411_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int ret;
unsigned long flag;
......@@ -245,9 +248,7 @@ static struct attribute *adt7411_attrs[] = {
NULL
};
static const struct attribute_group adt7411_attr_grp = {
.attrs = adt7411_attrs,
};
ATTRIBUTE_GROUPS(adt7411);
static int adt7411_detect(struct i2c_client *client,
struct i2c_board_info *info)
......@@ -281,14 +282,17 @@ static int adt7411_detect(struct i2c_client *client,
static int adt7411_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
struct adt7411_data *data;
struct device *hwmon_dev;
int ret;
data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(client, data);
data->client = client;
mutex_init(&data->device_lock);
mutex_init(&data->update_lock);
......@@ -300,32 +304,10 @@ static int adt7411_probe(struct i2c_client *client,
/* force update on first occasion */
data->next_update = jiffies;
ret = sysfs_create_group(&client->dev.kobj, &adt7411_attr_grp);
if (ret)
return ret;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
ret = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
dev_info(&client->dev, "successfully registered\n");
return 0;
exit_remove:
sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp);
return ret;
}
static int adt7411_remove(struct i2c_client *client)
{
struct adt7411_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp);
return 0;
hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
data,
adt7411_groups);
return PTR_ERR_OR_ZERO(hwmon_dev);
}
static const struct i2c_device_id adt7411_id[] = {
......@@ -339,7 +321,6 @@ static struct i2c_driver adt7411_driver = {
.name = "adt7411",
},
.probe = adt7411_probe,
.remove = adt7411_remove,
.id_table = adt7411_id,
.detect = adt7411_detect,
.address_list = normal_i2c,
......
......@@ -202,8 +202,7 @@ static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END };
(((value) & prefix##_MASK) >> prefix##_SHIFT)
struct adt7462_data {
struct device *hwmon_dev;
struct attribute_group attrs;
struct i2c_client *client;
struct mutex lock;
char sensors_valid;
char limits_valid;
......@@ -232,30 +231,6 @@ struct adt7462_data {
u8 alarms[ADT7462_ALARM_REG_COUNT];
};
static int adt7462_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int adt7462_detect(struct i2c_client *client,
struct i2c_board_info *info);
static int adt7462_remove(struct i2c_client *client);
static const struct i2c_device_id adt7462_id[] = {
{ "adt7462", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adt7462_id);
static struct i2c_driver adt7462_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adt7462",
},
.probe = adt7462_probe,
.remove = adt7462_remove,
.id_table = adt7462_id,
.detect = adt7462_detect,
.address_list = normal_i2c,
};
/*
* 16-bit registers on the ADT7462 are low-byte first. The data sheet says
* that the low byte must be read before the high byte.
......@@ -705,8 +680,8 @@ static int find_trange_value(int trange)
static struct adt7462_data *adt7462_update_device(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct adt7462_data *data = i2c_get_clientdata(client);
struct adt7462_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
unsigned long local_jiffies = jiffies;
int i;
......@@ -828,8 +803,8 @@ static ssize_t set_temp_min(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7462_data *data = i2c_get_clientdata(client);
struct adt7462_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp) || !temp_enabled(data, attr->index))
......@@ -866,8 +841,8 @@ static ssize_t set_temp_max(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7462_data *data = i2c_get_clientdata(client);
struct adt7462_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp) || !temp_enabled(data, attr->index))
......@@ -929,8 +904,8 @@ static ssize_t set_volt_max(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7462_data *data = i2c_get_clientdata(client);
struct adt7462_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int x = voltage_multiplier(data, attr->index);
long temp;
......@@ -971,8 +946,8 @@ static ssize_t set_volt_min(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7462_data *data = i2c_get_clientdata(client);
struct adt7462_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int x = voltage_multiplier(data, attr->index);
long temp;
......@@ -1061,8 +1036,8 @@ static ssize_t set_fan_min(struct device *dev,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7462_data *data = i2c_get_clientdata(client);
struct adt7462_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp) || !temp ||
......@@ -1109,8 +1084,8 @@ static ssize_t set_force_pwm_max(struct device *dev,
const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adt7462_data *data = i2c_get_clientdata(client);
struct adt7462_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
u8 reg;
......@@ -1142,8 +1117,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7462_data *data = i2c_get_clientdata(client);
struct adt7462_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
......@@ -1172,8 +1147,8 @@ static ssize_t set_pwm_max(struct device *dev,
const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adt7462_data *data = i2c_get_clientdata(client);
struct adt7462_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
......@@ -1204,8 +1179,8 @@ static ssize_t set_pwm_min(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7462_data *data = i2c_get_clientdata(client);
struct adt7462_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
......@@ -1238,8 +1213,8 @@ static ssize_t set_pwm_hyst(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7462_data *data = i2c_get_clientdata(client);
struct adt7462_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
......@@ -1283,8 +1258,8 @@ static ssize_t set_pwm_tmax(struct device *dev,
{
int temp;
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7462_data *data = i2c_get_clientdata(client);
struct adt7462_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int tmin, trange_value;
long trange;
......@@ -1324,8 +1299,8 @@ static ssize_t set_pwm_tmin(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7462_data *data = i2c_get_clientdata(client);
struct adt7462_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
......@@ -1381,8 +1356,8 @@ static ssize_t set_pwm_auto(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7462_data *data = i2c_get_clientdata(client);
struct adt7462_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
......@@ -1440,8 +1415,8 @@ static ssize_t set_pwm_auto_temp(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7462_data *data = i2c_get_clientdata(client);
struct adt7462_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
......@@ -1725,7 +1700,7 @@ static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO,
static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO,
show_pwm_auto_temp, set_pwm_auto_temp, 3);
static struct attribute *adt7462_attr[] = {
static struct attribute *adt7462_attrs[] = {
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp2_max.dev_attr.attr,
&sensor_dev_attr_temp3_max.dev_attr.attr,
......@@ -1896,6 +1871,8 @@ static struct attribute *adt7462_attr[] = {
NULL
};
ATTRIBUTE_GROUPS(adt7462);
/* Return 0 if detection is successful, -ENODEV otherwise */
static int adt7462_detect(struct i2c_client *client,
struct i2c_board_info *info)
......@@ -1926,46 +1903,41 @@ static int adt7462_detect(struct i2c_client *client,
static int adt7462_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
struct adt7462_data *data;
int err;
struct device *hwmon_dev;
data = devm_kzalloc(&client->dev, sizeof(struct adt7462_data),
GFP_KERNEL);
data = devm_kzalloc(dev, sizeof(struct adt7462_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(client, data);
data->client = client;
mutex_init(&data->lock);
dev_info(&client->dev, "%s chip found\n", client->name);
/* Register sysfs hooks */
data->attrs.attrs = adt7462_attr;
err = sysfs_create_group(&client->dev.kobj, &data->attrs);
if (err)
return err;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
return 0;
exit_remove:
sysfs_remove_group(&client->dev.kobj, &data->attrs);
return err;
hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
data,
adt7462_groups);
return PTR_ERR_OR_ZERO(hwmon_dev);
}
static int adt7462_remove(struct i2c_client *client)
{
struct adt7462_data *data = i2c_get_clientdata(client);
static const struct i2c_device_id adt7462_id[] = {
{ "adt7462", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adt7462_id);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &data->attrs);
return 0;
}
static struct i2c_driver adt7462_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adt7462",
},
.probe = adt7462_probe,
.id_table = adt7462_id,
.detect = adt7462_detect,
.address_list = normal_i2c,
};
module_i2c_driver(adt7462_driver);
......
......@@ -143,8 +143,7 @@ static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END };
#define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID)
struct adt7470_data {
struct device *hwmon_dev;
struct attribute_group attrs;
struct i2c_client *client;
struct mutex lock;
char sensors_valid;
char limits_valid;
......@@ -175,30 +174,6 @@ struct adt7470_data {
unsigned int auto_update_interval;
};
static int adt7470_probe(struct i2c_client *client,
const struct i2c_device_id *id);
static int adt7470_detect(struct i2c_client *client,
struct i2c_board_info *info);
static int adt7470_remove(struct i2c_client *client);
static const struct i2c_device_id adt7470_id[] = {
{ "adt7470", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adt7470_id);
static struct i2c_driver adt7470_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adt7470",
},
.probe = adt7470_probe,
.remove = adt7470_remove,
.id_table = adt7470_id,
.detect = adt7470_detect,
.address_list = normal_i2c,
};
/*
* 16-bit registers on the ADT7470 are low-byte first. The data sheet says
* that the low byte must be read before the high byte.
......@@ -218,18 +193,6 @@ static inline int adt7470_write_word_data(struct i2c_client *client, u8 reg,
|| i2c_smbus_write_byte_data(client, reg + 1, value >> 8);
}
static void adt7470_init_client(struct i2c_client *client)
{
int reg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG);
if (reg < 0) {
dev_err(&client->dev, "cannot read configuration register\n");
} else {
/* start monitoring (and do a self-test) */
i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, reg | 3);
}
}
/* Probe for temperature sensors. Assumes lock is held */
static int adt7470_read_temperatures(struct i2c_client *client,
struct adt7470_data *data)
......@@ -314,8 +277,8 @@ static int adt7470_update_thread(void *p)
static struct adt7470_data *adt7470_update_device(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
struct adt7470_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
unsigned long local_jiffies = jiffies;
u8 cfg;
int i;
......@@ -445,8 +408,7 @@ static ssize_t set_auto_update_interval(struct device *dev,
const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
struct adt7470_data *data = dev_get_drvdata(dev);
long temp;
if (kstrtol(buf, 10, &temp))
......@@ -474,8 +436,7 @@ static ssize_t set_num_temp_sensors(struct device *dev,
const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
struct adt7470_data *data = dev_get_drvdata(dev);
long temp;
if (kstrtol(buf, 10, &temp))
......@@ -507,8 +468,8 @@ static ssize_t set_temp_min(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
struct adt7470_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
......@@ -541,8 +502,8 @@ static ssize_t set_temp_max(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
struct adt7470_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
......@@ -596,8 +557,8 @@ static ssize_t set_fan_max(struct device *dev,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
struct adt7470_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp) || !temp)
......@@ -633,8 +594,8 @@ static ssize_t set_fan_min(struct device *dev,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
struct adt7470_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp) || !temp)
......@@ -677,8 +638,8 @@ static ssize_t set_force_pwm_max(struct device *dev,
const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
struct adt7470_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
u8 reg;
......@@ -710,8 +671,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
const char *buf, size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
struct adt7470_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
......@@ -742,8 +703,8 @@ static ssize_t set_pwm_max(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
struct adt7470_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
......@@ -775,8 +736,8 @@ static ssize_t set_pwm_min(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
struct adt7470_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
......@@ -818,8 +779,8 @@ static ssize_t set_pwm_tmin(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
struct adt7470_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long temp;
if (kstrtol(buf, 10, &temp))
......@@ -852,8 +813,8 @@ static ssize_t set_pwm_auto(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
struct adt7470_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int pwm_auto_reg = ADT7470_REG_PWM_CFG(attr->index);
int pwm_auto_reg_mask;
long temp;
......@@ -913,8 +874,8 @@ static ssize_t set_pwm_auto_temp(struct device *dev,
size_t count)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct i2c_client *client = to_i2c_client(dev);
struct adt7470_data *data = i2c_get_clientdata(client);
struct adt7470_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int pwm_auto_reg = ADT7470_REG_PWM_AUTO_TEMP(attr->index);
long temp;
u8 reg;
......@@ -1131,7 +1092,7 @@ static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO,
static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO,
show_pwm_auto_temp, set_pwm_auto_temp, 3);
static struct attribute *adt7470_attr[] = {
static struct attribute *adt7470_attrs[] = {
&dev_attr_alarm_mask.attr,
&dev_attr_num_temp_sensors.attr,
&dev_attr_auto_update_interval.attr,
......@@ -1223,6 +1184,8 @@ static struct attribute *adt7470_attr[] = {
NULL
};
ATTRIBUTE_GROUPS(adt7470);
/* Return 0 if detection is successful, -ENODEV otherwise */
static int adt7470_detect(struct i2c_client *client,
struct i2c_board_info *info)
......@@ -1250,14 +1213,26 @@ static int adt7470_detect(struct i2c_client *client,
return 0;
}
static void adt7470_init_client(struct i2c_client *client)
{
int reg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG);
if (reg < 0) {
dev_err(&client->dev, "cannot read configuration register\n");
} else {
/* start monitoring (and do a self-test) */
i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, reg | 3);
}
}
static int adt7470_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
struct adt7470_data *data;
int err;
struct device *hwmon_dev;
data = devm_kzalloc(&client->dev, sizeof(struct adt7470_data),
GFP_KERNEL);
data = devm_kzalloc(dev, sizeof(struct adt7470_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
......@@ -1265,6 +1240,7 @@ static int adt7470_probe(struct i2c_client *client,
data->auto_update_interval = AUTO_UPDATE_INTERVAL;
i2c_set_clientdata(client, data);
data->client = client;
mutex_init(&data->lock);
dev_info(&client->dev, "%s chip found\n", client->name);
......@@ -1273,32 +1249,21 @@ static int adt7470_probe(struct i2c_client *client,
adt7470_init_client(client);
/* Register sysfs hooks */
data->attrs.attrs = adt7470_attr;
err = sysfs_create_group(&client->dev.kobj, &data->attrs);
if (err)
return err;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
goto exit_remove;
}
hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
data,
adt7470_groups);
if (IS_ERR(hwmon_dev))
return PTR_ERR(hwmon_dev);
init_completion(&data->auto_update_stop);
data->auto_update = kthread_run(adt7470_update_thread, client, "%s",
dev_name(data->hwmon_dev));
dev_name(hwmon_dev));
if (IS_ERR(data->auto_update)) {
err = PTR_ERR(data->auto_update);
goto exit_unregister;
return PTR_ERR(data->auto_update);
}
return 0;
exit_unregister:
hwmon_device_unregister(data->hwmon_dev);
exit_remove:
sysfs_remove_group(&client->dev.kobj, &data->attrs);
return err;
}
static int adt7470_remove(struct i2c_client *client)
......@@ -1307,11 +1272,27 @@ static int adt7470_remove(struct i2c_client *client)
kthread_stop(data->auto_update);
wait_for_completion(&data->auto_update_stop);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &data->attrs);
return 0;
}
static const struct i2c_device_id adt7470_id[] = {
{ "adt7470", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, adt7470_id);
static struct i2c_driver adt7470_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "adt7470",
},
.probe = adt7470_probe,
.remove = adt7470_remove,
.id_table = adt7470_id,
.detect = adt7470_detect,
.address_list = normal_i2c,
};
module_i2c_driver(adt7470_driver);
MODULE_AUTHOR("Darrick J. Wong <darrick.wong@oracle.com>");
......
......@@ -21,7 +21,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/module.h>
#include <linux/init.h>
......@@ -33,7 +32,6 @@
#include <linux/err.h>
#include <linux/mutex.h>
/*
* Addresses to scan.
*/
......@@ -41,8 +39,6 @@
static const unsigned short normal_i2c[] = {0x18, 0x19, 0x1a, 0x2c, 0x2d, 0x2e,
0x4c, 0x4d, 0x4e, I2C_CLIENT_END};
/*
* Insmod parameters
*/
......@@ -53,7 +49,6 @@ module_param(pwminv, int, S_IRUGO);
static int init = 1; /*Power-on initialization.*/
module_param(init, int, S_IRUGO);
enum chips { amc6821 };
#define AMC6821_REG_DEV_ID 0x3D
......@@ -152,46 +147,12 @@ static const u8 fan_reg_hi[] = {AMC6821_REG_TDATA_HI,
AMC6821_REG_TACH_LLIMITH,
AMC6821_REG_TACH_HLIMITH, };
static int amc6821_probe(
struct i2c_client *client,
const struct i2c_device_id *id);
static int amc6821_detect(
struct i2c_client *client,
struct i2c_board_info *info);
static int amc6821_init_client(struct i2c_client *client);
static int amc6821_remove(struct i2c_client *client);
static struct amc6821_data *amc6821_update_device(struct device *dev);
/*
* Driver data (common to all clients)
*/
static const struct i2c_device_id amc6821_id[] = {
{ "amc6821", amc6821 },
{ }
};
MODULE_DEVICE_TABLE(i2c, amc6821_id);
static struct i2c_driver amc6821_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "amc6821",
},
.probe = amc6821_probe,
.remove = amc6821_remove,
.id_table = amc6821_id,
.detect = amc6821_detect,
.address_list = normal_i2c,
};
/*
* Client data (each client gets its own)
*/
struct amc6821_data {
struct device *hwmon_dev;
struct i2c_client *client;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
......@@ -213,6 +174,108 @@ struct amc6821_data {
u8 stat2;
};
static struct amc6821_data *amc6821_update_device(struct device *dev)
{
struct amc6821_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int timeout = HZ;
u8 reg;
int i;
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + timeout) ||
!data->valid) {
for (i = 0; i < TEMP_IDX_LEN; i++)
data->temp[i] = i2c_smbus_read_byte_data(client,
temp_reg[i]);
data->stat1 = i2c_smbus_read_byte_data(client,
AMC6821_REG_STAT1);
data->stat2 = i2c_smbus_read_byte_data(client,
AMC6821_REG_STAT2);
data->pwm1 = i2c_smbus_read_byte_data(client,
AMC6821_REG_DCY);
for (i = 0; i < FAN1_IDX_LEN; i++) {
data->fan[i] = i2c_smbus_read_byte_data(
client,
fan_reg_low[i]);
data->fan[i] += i2c_smbus_read_byte_data(
client,
fan_reg_hi[i]) << 8;
}
data->fan1_div = i2c_smbus_read_byte_data(client,
AMC6821_REG_CONF4);
data->fan1_div = data->fan1_div & AMC6821_CONF4_PSPR ? 4 : 2;
data->pwm1_auto_point_pwm[0] = 0;
data->pwm1_auto_point_pwm[2] = 255;
data->pwm1_auto_point_pwm[1] = i2c_smbus_read_byte_data(client,
AMC6821_REG_DCY_LOW_TEMP);
data->temp1_auto_point_temp[0] =
i2c_smbus_read_byte_data(client,
AMC6821_REG_PSV_TEMP);
data->temp2_auto_point_temp[0] =
data->temp1_auto_point_temp[0];
reg = i2c_smbus_read_byte_data(client,
AMC6821_REG_LTEMP_FAN_CTRL);
data->temp1_auto_point_temp[1] = (reg & 0xF8) >> 1;
reg &= 0x07;
reg = 0x20 >> reg;
if (reg > 0)
data->temp1_auto_point_temp[2] =
data->temp1_auto_point_temp[1] +
(data->pwm1_auto_point_pwm[2] -
data->pwm1_auto_point_pwm[1]) / reg;
else
data->temp1_auto_point_temp[2] = 255;
reg = i2c_smbus_read_byte_data(client,
AMC6821_REG_RTEMP_FAN_CTRL);
data->temp2_auto_point_temp[1] = (reg & 0xF8) >> 1;
reg &= 0x07;
reg = 0x20 >> reg;
if (reg > 0)
data->temp2_auto_point_temp[2] =
data->temp2_auto_point_temp[1] +
(data->pwm1_auto_point_pwm[2] -
data->pwm1_auto_point_pwm[1]) / reg;
else
data->temp2_auto_point_temp[2] = 255;
reg = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1);
reg = (reg >> 5) & 0x3;
switch (reg) {
case 0: /*open loop: software sets pwm1*/
data->pwm1_auto_channels_temp = 0;
data->pwm1_enable = 1;
break;
case 2: /*closed loop: remote T (temp2)*/
data->pwm1_auto_channels_temp = 2;
data->pwm1_enable = 2;
break;
case 3: /*closed loop: local and remote T (temp2)*/
data->pwm1_auto_channels_temp = 3;
data->pwm1_enable = 3;
break;
case 1: /*
* semi-open loop: software sets rpm, chip controls
* pwm1, currently not implemented
*/
data->pwm1_auto_channels_temp = 0;
data->pwm1_enable = 0;
break;
}
data->last_updated = jiffies;
data->valid = 1;
}
mutex_unlock(&data->update_lock);
return data;
}
static ssize_t get_temp(
struct device *dev,
......@@ -225,16 +288,14 @@ static ssize_t get_temp(
return sprintf(buf, "%d\n", data->temp[ix] * 1000);
}
static ssize_t set_temp(
struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct amc6821_data *data = i2c_get_clientdata(client);
struct amc6821_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int ix = to_sensor_dev_attr(attr)->index;
long val;
......@@ -253,9 +314,6 @@ static ssize_t set_temp(
return count;
}
static ssize_t get_temp_alarm(
struct device *dev,
struct device_attribute *devattr,
......@@ -294,9 +352,6 @@ static ssize_t get_temp_alarm(
return sprintf(buf, "0");
}
static ssize_t get_temp2_fault(
struct device *dev,
struct device_attribute *devattr,
......@@ -324,8 +379,8 @@ static ssize_t set_pwm1(
const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct amc6821_data *data = i2c_get_clientdata(client);
struct amc6821_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long val;
int ret = kstrtol(buf, 10, &val);
if (ret)
......@@ -353,18 +408,20 @@ static ssize_t set_pwm1_enable(
const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct amc6821_data *data = i2c_get_clientdata(client);
struct amc6821_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long val;
int config = kstrtol(buf, 10, &val);
if (config)
return config;
mutex_lock(&data->update_lock);
config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1);
if (config < 0) {
dev_err(&client->dev,
"Error reading configuration register, aborting.\n");
return config;
count = config;
goto unlock;
}
switch (val) {
......@@ -381,19 +438,19 @@ static ssize_t set_pwm1_enable(
config |= AMC6821_CONF1_FDRC1;
break;
default:
return -EINVAL;
count = -EINVAL;
goto unlock;
}
mutex_lock(&data->update_lock);
if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF1, config)) {
dev_err(&client->dev,
"Configuration register write error, aborting.\n");
count = -EIO;
}
unlock:
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t get_pwm1_auto_channels_temp(
struct device *dev,
struct device_attribute *devattr,
......@@ -403,7 +460,6 @@ static ssize_t get_pwm1_auto_channels_temp(
return sprintf(buf, "%d\n", data->pwm1_auto_channels_temp);
}
static ssize_t get_temp_auto_point_temp(
struct device *dev,
struct device_attribute *devattr,
......@@ -425,7 +481,6 @@ static ssize_t get_temp_auto_point_temp(
}
}
static ssize_t get_pwm1_auto_point_pwm(
struct device *dev,
struct device_attribute *devattr,
......@@ -436,7 +491,6 @@ static ssize_t get_pwm1_auto_point_pwm(
return sprintf(buf, "%d\n", data->pwm1_auto_point_pwm[ix]);
}
static inline ssize_t set_slope_register(struct i2c_client *client,
u8 reg,
u8 dpwm,
......@@ -459,16 +513,14 @@ static inline ssize_t set_slope_register(struct i2c_client *client,
return 0;
}
static ssize_t set_temp_auto_point_temp(
struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct amc6821_data *data = amc6821_update_device(dev);
struct i2c_client *client = data->client;
int ix = to_sensor_dev_attr_2(attr)->index;
int nr = to_sensor_dev_attr_2(attr)->nr;
u8 *ptemp;
......@@ -493,8 +545,9 @@ static ssize_t set_temp_auto_point_temp(
return -EINVAL;
}
data->valid = 0;
mutex_lock(&data->update_lock);
data->valid = 0;
switch (ix) {
case 0:
ptemp[0] = clamp_val(val / 1000, 0,
......@@ -533,16 +586,14 @@ static ssize_t set_temp_auto_point_temp(
return count;
}
static ssize_t set_pwm1_auto_point_pwm(
struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct amc6821_data *data = i2c_get_clientdata(client);
struct amc6821_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
int dpwm;
long val;
int ret = kstrtol(buf, 10, &val);
......@@ -587,8 +638,6 @@ static ssize_t get_fan(
return sprintf(buf, "%d\n", (int)(6000000 / data->fan[ix]));
}
static ssize_t get_fan1_fault(
struct device *dev,
struct device_attribute *devattr,
......@@ -601,15 +650,13 @@ static ssize_t get_fan1_fault(
return sprintf(buf, "0");
}
static ssize_t set_fan(
struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct amc6821_data *data = i2c_get_clientdata(client);
struct amc6821_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long val;
int ix = to_sensor_dev_attr(attr)->index;
int ret = kstrtol(buf, 10, &val);
......@@ -635,8 +682,6 @@ static ssize_t set_fan(
return count;
}
static ssize_t get_fan1_div(
struct device *dev,
struct device_attribute *devattr,
......@@ -651,20 +696,21 @@ static ssize_t set_fan1_div(
struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct amc6821_data *data = i2c_get_clientdata(client);
struct amc6821_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
long val;
int config = kstrtol(buf, 10, &val);
if (config)
return config;
mutex_lock(&data->update_lock);
config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF4);
if (config < 0) {
dev_err(&client->dev,
"Error reading configuration register, aborting.\n");
return config;
count = config;
goto EXIT;
}
mutex_lock(&data->update_lock);
switch (val) {
case 2:
config &= ~AMC6821_CONF4_PSPR;
......@@ -688,8 +734,6 @@ static ssize_t set_fan1_div(
return count;
}
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
get_temp, NULL, IDX_TEMP1_INPUT);
static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, get_temp,
......@@ -754,8 +798,6 @@ static SENSOR_DEVICE_ATTR_2(temp2_auto_point2_temp, S_IWUSR | S_IRUGO,
static SENSOR_DEVICE_ATTR_2(temp2_auto_point3_temp, S_IWUSR | S_IRUGO,
get_temp_auto_point_temp, set_temp_auto_point_temp, 2, 2);
static struct attribute *amc6821_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_min.dev_attr.attr,
......@@ -792,11 +834,7 @@ static struct attribute *amc6821_attrs[] = {
NULL
};
static struct attribute_group amc6821_attr_grp = {
.attrs = amc6821_attrs,
};
ATTRIBUTE_GROUPS(amc6821);
/* Return 0 if detection is successful, -ENODEV otherwise */
static int amc6821_detect(
......@@ -844,53 +882,6 @@ static int amc6821_detect(
return 0;
}
static int amc6821_probe(
struct i2c_client *client,
const struct i2c_device_id *id)
{
struct amc6821_data *data;
int err;
data = devm_kzalloc(&client->dev, sizeof(struct amc6821_data),
GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
/*
* Initialize the amc6821 chip
*/
err = amc6821_init_client(client);
if (err)
return err;
err = sysfs_create_group(&client->dev.kobj, &amc6821_attr_grp);
if (err)
return err;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (!IS_ERR(data->hwmon_dev))
return 0;
err = PTR_ERR(data->hwmon_dev);
dev_err(&client->dev, "error registering hwmon device.\n");
sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp);
return err;
}
static int amc6821_remove(struct i2c_client *client)
{
struct amc6821_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp);
return 0;
}
static int amc6821_init_client(struct i2c_client *client)
{
int config;
......@@ -977,109 +968,51 @@ static int amc6821_init_client(struct i2c_client *client)
return 0;
}
static struct amc6821_data *amc6821_update_device(struct device *dev)
static int amc6821_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_client *client = to_i2c_client(dev);
struct amc6821_data *data = i2c_get_clientdata(client);
int timeout = HZ;
u8 reg;
int i;
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + timeout) ||
!data->valid) {
for (i = 0; i < TEMP_IDX_LEN; i++)
data->temp[i] = i2c_smbus_read_byte_data(client,
temp_reg[i]);
struct device *dev = &client->dev;
struct amc6821_data *data;
struct device *hwmon_dev;
int err;
data->stat1 = i2c_smbus_read_byte_data(client,
AMC6821_REG_STAT1);
data->stat2 = i2c_smbus_read_byte_data(client,
AMC6821_REG_STAT2);
data = devm_kzalloc(dev, sizeof(struct amc6821_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->pwm1 = i2c_smbus_read_byte_data(client,
AMC6821_REG_DCY);
for (i = 0; i < FAN1_IDX_LEN; i++) {
data->fan[i] = i2c_smbus_read_byte_data(
client,
fan_reg_low[i]);
data->fan[i] += i2c_smbus_read_byte_data(
client,
fan_reg_hi[i]) << 8;
}
data->fan1_div = i2c_smbus_read_byte_data(client,
AMC6821_REG_CONF4);
data->fan1_div = data->fan1_div & AMC6821_CONF4_PSPR ? 4 : 2;
data->client = client;
mutex_init(&data->update_lock);
data->pwm1_auto_point_pwm[0] = 0;
data->pwm1_auto_point_pwm[2] = 255;
data->pwm1_auto_point_pwm[1] = i2c_smbus_read_byte_data(client,
AMC6821_REG_DCY_LOW_TEMP);
/*
* Initialize the amc6821 chip
*/
err = amc6821_init_client(client);
if (err)
return err;
data->temp1_auto_point_temp[0] =
i2c_smbus_read_byte_data(client,
AMC6821_REG_PSV_TEMP);
data->temp2_auto_point_temp[0] =
data->temp1_auto_point_temp[0];
reg = i2c_smbus_read_byte_data(client,
AMC6821_REG_LTEMP_FAN_CTRL);
data->temp1_auto_point_temp[1] = (reg & 0xF8) >> 1;
reg &= 0x07;
reg = 0x20 >> reg;
if (reg > 0)
data->temp1_auto_point_temp[2] =
data->temp1_auto_point_temp[1] +
(data->pwm1_auto_point_pwm[2] -
data->pwm1_auto_point_pwm[1]) / reg;
else
data->temp1_auto_point_temp[2] = 255;
hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
data,
amc6821_groups);
return PTR_ERR_OR_ZERO(hwmon_dev);
}
reg = i2c_smbus_read_byte_data(client,
AMC6821_REG_RTEMP_FAN_CTRL);
data->temp2_auto_point_temp[1] = (reg & 0xF8) >> 1;
reg &= 0x07;
reg = 0x20 >> reg;
if (reg > 0)
data->temp2_auto_point_temp[2] =
data->temp2_auto_point_temp[1] +
(data->pwm1_auto_point_pwm[2] -
data->pwm1_auto_point_pwm[1]) / reg;
else
data->temp2_auto_point_temp[2] = 255;
static const struct i2c_device_id amc6821_id[] = {
{ "amc6821", amc6821 },
{ }
};
reg = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1);
reg = (reg >> 5) & 0x3;
switch (reg) {
case 0: /*open loop: software sets pwm1*/
data->pwm1_auto_channels_temp = 0;
data->pwm1_enable = 1;
break;
case 2: /*closed loop: remote T (temp2)*/
data->pwm1_auto_channels_temp = 2;
data->pwm1_enable = 2;
break;
case 3: /*closed loop: local and remote T (temp2)*/
data->pwm1_auto_channels_temp = 3;
data->pwm1_enable = 3;
break;
case 1: /*
* semi-open loop: software sets rpm, chip controls
* pwm1, currently not implemented
*/
data->pwm1_auto_channels_temp = 0;
data->pwm1_enable = 0;
break;
}
MODULE_DEVICE_TABLE(i2c, amc6821_id);
data->last_updated = jiffies;
data->valid = 1;
}
mutex_unlock(&data->update_lock);
return data;
}
static struct i2c_driver amc6821_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "amc6821",
},
.probe = amc6821_probe,
.id_table = amc6821_id,
.detect = amc6821_detect,
.address_list = normal_i2c,
};
module_i2c_driver(amc6821_driver);
......
......@@ -300,7 +300,7 @@ static ssize_t store_fan16(struct device *dev,
* respectively. That doesn't mean that's what the motherboard provides. :)
*/
static int asc7621_in_scaling[] = {
static const int asc7621_in_scaling[] = {
2500, 2250, 3300, 5000, 12000
};
......@@ -451,7 +451,7 @@ static ssize_t store_temp62(struct device *dev,
* hwmon specs, we synthesize the auto_point_2 from them.
*/
static u32 asc7621_range_map[] = {
static const u32 asc7621_range_map[] = {
2000, 2500, 3330, 4000, 5000, 6670, 8000, 10000,
13330, 16000, 20000, 26670, 32000, 40000, 53330, 80000,
};
......@@ -512,7 +512,7 @@ static ssize_t show_pwm_ac(struct device *dev,
{
SETUP_SHOW_DATA_PARAM(dev, attr);
u8 config, altbit, regval;
u8 map[] = {
const u8 map[] = {
0x01, 0x02, 0x04, 0x1f, 0x00, 0x06, 0x07, 0x10,
0x08, 0x0f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f
};
......@@ -533,7 +533,7 @@ static ssize_t store_pwm_ac(struct device *dev,
SETUP_STORE_DATA_PARAM(dev, attr);
unsigned long reqval;
u8 currval, config, altbit, newval;
u16 map[] = {
const u16 map[] = {
0x04, 0x00, 0x01, 0xff, 0x02, 0xff, 0x05, 0x06,
0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
......@@ -651,7 +651,7 @@ static ssize_t store_pwm_enable(struct device *dev,
return count;
}
static u32 asc7621_pwm_freq_map[] = {
static const u32 asc7621_pwm_freq_map[] = {
10, 15, 23, 30, 38, 47, 62, 94,
23000, 24000, 25000, 26000, 27000, 28000, 29000, 30000
};
......@@ -700,7 +700,7 @@ static ssize_t store_pwm_freq(struct device *dev,
return count;
}
static u32 asc7621_pwm_auto_spinup_map[] = {
static const u32 asc7621_pwm_auto_spinup_map[] = {
0, 100, 250, 400, 700, 1000, 2000, 4000
};
......@@ -749,7 +749,7 @@ static ssize_t store_pwm_ast(struct device *dev,
return count;
}
static u32 asc7621_temp_smoothing_time_map[] = {
static const u32 asc7621_temp_smoothing_time_map[] = {
35000, 17600, 11800, 7000, 4400, 3000, 1600, 800
};
......
......@@ -46,7 +46,7 @@ MODULE_AUTHOR("Sebastian Witt <se.witt@gmx.net>");
static const unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END };
struct atxp1_data {
struct device *hwmon_dev;
struct i2c_client *client;
struct mutex update_lock;
unsigned long last_updated;
u8 valid;
......@@ -61,11 +61,8 @@ struct atxp1_data {
static struct atxp1_data *atxp1_update_device(struct device *dev)
{
struct i2c_client *client;
struct atxp1_data *data;
client = to_i2c_client(dev);
data = i2c_get_clientdata(client);
struct atxp1_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
mutex_lock(&data->update_lock);
......@@ -105,15 +102,12 @@ static ssize_t atxp1_storevcore(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct atxp1_data *data;
struct i2c_client *client;
struct atxp1_data *data = atxp1_update_device(dev);
struct i2c_client *client = data->client;
int vid, cvid;
unsigned long vcore;
int err;
client = to_i2c_client(dev);
data = atxp1_update_device(dev);
err = kstrtoul(buf, 10, &vcore);
if (err)
return err;
......@@ -184,14 +178,11 @@ static ssize_t atxp1_storegpio1(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t count)
{
struct atxp1_data *data;
struct i2c_client *client;
struct atxp1_data *data = atxp1_update_device(dev);
struct i2c_client *client = data->client;
unsigned long value;
int err;
client = to_i2c_client(dev);
data = atxp1_update_device(dev);
err = kstrtoul(buf, 16, &value);
if (err)
return err;
......@@ -234,7 +225,7 @@ static ssize_t atxp1_storegpio2(struct device *dev,
const char *buf, size_t count)
{
struct atxp1_data *data = atxp1_update_device(dev);
struct i2c_client *client = to_i2c_client(dev);
struct i2c_client *client = data->client;
unsigned long value;
int err;
......@@ -260,17 +251,13 @@ static ssize_t atxp1_storegpio2(struct device *dev,
*/
static DEVICE_ATTR(gpio2, S_IRUGO | S_IWUSR, atxp1_showgpio2, atxp1_storegpio2);
static struct attribute *atxp1_attributes[] = {
static struct attribute *atxp1_attrs[] = {
&dev_attr_gpio1.attr,
&dev_attr_gpio2.attr,
&dev_attr_cpu0_vid.attr,
NULL
};
static const struct attribute_group atxp1_group = {
.attrs = atxp1_attributes,
};
ATTRIBUTE_GROUPS(atxp1);
/* Return 0 if detection is successful, -ENODEV otherwise */
static int atxp1_detect(struct i2c_client *new_client,
......@@ -314,50 +301,30 @@ static int atxp1_detect(struct i2c_client *new_client,
return 0;
}
static int atxp1_probe(struct i2c_client *new_client,
static int atxp1_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
struct atxp1_data *data;
int err;
struct device *hwmon_dev;
data = devm_kzalloc(&new_client->dev, sizeof(struct atxp1_data),
GFP_KERNEL);
data = devm_kzalloc(dev, sizeof(struct atxp1_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
/* Get VRM */
data->vrm = vid_which_vrm();
i2c_set_clientdata(new_client, data);
data->client = client;
mutex_init(&data->update_lock);
/* Register sysfs hooks */
err = sysfs_create_group(&new_client->dev.kobj, &atxp1_group);
if (err)
return err;
data->hwmon_dev = hwmon_device_register(&new_client->dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
goto exit_remove_files;
}
dev_info(&new_client->dev, "Using VRM: %d.%d\n",
data->vrm / 10, data->vrm % 10);
return 0;
exit_remove_files:
sysfs_remove_group(&new_client->dev.kobj, &atxp1_group);
return err;
};
static int atxp1_remove(struct i2c_client *client)
{
struct atxp1_data *data = i2c_get_clientdata(client);
hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
data,
atxp1_groups);
if (IS_ERR(hwmon_dev))
return PTR_ERR(hwmon_dev);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &atxp1_group);
dev_info(dev, "Using VRM: %d.%d\n", data->vrm / 10, data->vrm % 10);
return 0;
};
......@@ -374,7 +341,6 @@ static struct i2c_driver atxp1_driver = {
.name = "atxp1",
},
.probe = atxp1_probe,
.remove = atxp1_remove,
.id_table = atxp1_id,
.detect = atxp1_detect,
.address_list = normal_i2c,
......
......@@ -67,7 +67,7 @@ static const u8 DS620_REG_TEMP[3] = {
/* Each client has this additional data */
struct ds620_data {
struct device *hwmon_dev;
struct i2c_client *client;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
......@@ -106,8 +106,8 @@ static void ds620_init_client(struct i2c_client *client)
static struct ds620_data *ds620_update_client(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct ds620_data *data = i2c_get_clientdata(client);
struct ds620_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
struct ds620_data *ret = data;
mutex_lock(&data->update_lock);
......@@ -158,8 +158,8 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da,
long val;
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
struct ds620_data *data = i2c_get_clientdata(client);
struct ds620_data *data = dev_get_drvdata(dev);
struct i2c_client *client = data->client;
res = kstrtol(buf, 10, &val);
......@@ -181,13 +181,15 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *da,
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct ds620_data *data = ds620_update_client(dev);
struct i2c_client *client = to_i2c_client(dev);
struct i2c_client *client;
u16 conf, new_conf;
int res;
if (IS_ERR(data))
return PTR_ERR(data);
client = data->client;
/* reset alarms if necessary */
res = i2c_smbus_read_word_swapped(client, DS620_REG_CONF);
if (res < 0)
......@@ -213,7 +215,7 @@ static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL,
static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL,
DS620_REG_CONFIG_THF);
static struct attribute *ds620_attributes[] = {
static struct attribute *ds620_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_min.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
......@@ -222,55 +224,28 @@ static struct attribute *ds620_attributes[] = {
NULL
};
static const struct attribute_group ds620_group = {
.attrs = ds620_attributes,
};
ATTRIBUTE_GROUPS(ds620);
static int ds620_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
struct device *hwmon_dev;
struct ds620_data *data;
int err;
data = devm_kzalloc(&client->dev, sizeof(struct ds620_data),
GFP_KERNEL);
data = devm_kzalloc(dev, sizeof(struct ds620_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
i2c_set_clientdata(client, data);
data->client = client;
mutex_init(&data->update_lock);
/* Initialize the DS620 chip */
ds620_init_client(client);
/* Register sysfs hooks */
err = sysfs_create_group(&client->dev.kobj, &ds620_group);
if (err)
return err;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
goto exit_remove_files;
}
dev_info(&client->dev, "temperature sensor found\n");
return 0;
exit_remove_files:
sysfs_remove_group(&client->dev.kobj, &ds620_group);
return err;
}
static int ds620_remove(struct i2c_client *client)
{
struct ds620_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &ds620_group);
return 0;
hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
data, ds620_groups);
return PTR_ERR_OR_ZERO(hwmon_dev);
}
static const struct i2c_device_id ds620_id[] = {
......@@ -287,7 +262,6 @@ static struct i2c_driver ds620_driver = {
.name = "ds620",
},
.probe = ds620_probe,
.remove = ds620_remove,
.id_table = ds620_id,
};
......
......@@ -416,7 +416,7 @@ static bool emc1403_regmap_is_volatile(struct device *dev, unsigned int reg)
}
}
static struct regmap_config emc1403_regmap_config = {
static const struct regmap_config emc1403_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -52,6 +52,7 @@ enum lm75_type { /* keep sorted in alphabetical order */
tmp100,
tmp101,
tmp105,
tmp112,
tmp175,
tmp275,
tmp75,
......@@ -255,6 +256,12 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
data->sample_time = HZ;
clr_mask |= 1 << 7; /* not one-shot mode */
break;
case tmp112:
set_mask |= 3 << 5; /* 12-bit mode */
clr_mask |= 1 << 7; /* not one-shot mode */
data->resolution = 12;
data->sample_time = HZ / 4;
break;
case tmp105:
case tmp175:
case tmp275:
......@@ -323,6 +330,7 @@ static const struct i2c_device_id lm75_ids[] = {
{ "tmp100", tmp100, },
{ "tmp101", tmp101, },
{ "tmp105", tmp105, },
{ "tmp112", tmp112, },
{ "tmp175", tmp175, },
{ "tmp275", tmp275, },
{ "tmp75", tmp75, },
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册