提交 afd8c404 编写于 作者: L Linus Torvalds

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

* 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging:
  hwmon: (ads1015) Make gain and datarate configurable
  hwmon: (ads1015) Drop dynamic attribute group
  hwmon: Add support for Texas Instruments ADS1015
  hwmon: New driver for SMSC SCH5627
  hwmon: (abituguru*) Update my email address
  hwmon: (lm75) Speed up detection
  hwmon: (lm75) Add detection of the National Semiconductor LM75A
  hp_accel: Fix driver name
  Move lis3lv02d drivers to drivers/misc
  Move hp_accel to drivers/platform/x86
  Let Kconfig handle lis3lv02d dependencies
  hwmon: (sht15) Fix integer overflow in humidity calculation
  hwmon: (sht15) Spelling fix
  hwmon: (w83795) Document pin mapping
ADS1015 (I2C)
This device is a 12-bit A-D converter with 4 inputs.
The inputs can be used single ended or in certain differential combinations.
For configuration all possible combinations are mapped to 8 channels:
0: Voltage over AIN0 and AIN1.
1: Voltage over AIN0 and AIN3.
2: Voltage over AIN1 and AIN3.
3: Voltage over AIN2 and AIN3.
4: Voltage over AIN0 and GND.
5: Voltage over AIN1 and GND.
6: Voltage over AIN2 and GND.
7: Voltage over AIN3 and GND.
Each channel can be configured individually:
- pga is the programmable gain amplifier (values are full scale)
0: +/- 6.144 V
1: +/- 4.096 V
2: +/- 2.048 V (default)
3: +/- 1.024 V
4: +/- 0.512 V
5: +/- 0.256 V
- data_rate in samples per second
0: 128
1: 250
2: 490
3: 920
4: 1600 (default)
5: 2400
6: 3300
1) The /ads1015 node
Required properties:
- compatible : must be "ti,ads1015"
- reg : I2C bus address of the device
- #address-cells : must be <1>
- #size-cells : must be <0>
The node contains child nodes for each channel that the platform uses.
Example ADS1015 node:
ads1015@49 {
compatible = "ti,ads1015";
reg = <0x49>;
#address-cells = <1>;
#size-cells = <0>;
[ child node definitions... ]
}
2) channel nodes
Required properties:
- reg : the channel number
Optional properties:
- ti,gain : the programmable gain amplifier setting
- ti,datarate : the converter data rate
Example ADS1015 channel node:
channel@4 {
reg = <4>;
ti,gain = <3>;
ti,datarate = <5>;
};
Kernel driver ads1015
=====================
Supported chips:
* Texas Instruments ADS1015
Prefix: 'ads1015'
Datasheet: Publicly available at the Texas Instruments website :
http://focus.ti.com/lit/ds/symlink/ads1015.pdf
Authors:
Dirk Eibach, Guntermann & Drunck GmbH <eibach@gdsys.de>
Description
-----------
This driver implements support for the Texas Instruments ADS1015.
This device is a 12-bit A-D converter with 4 inputs.
The inputs can be used single ended or in certain differential combinations.
The inputs can be made available by 8 sysfs input files in0_input - in7_input:
in0: Voltage over AIN0 and AIN1.
in1: Voltage over AIN0 and AIN3.
in2: Voltage over AIN1 and AIN3.
in3: Voltage over AIN2 and AIN3.
in4: Voltage over AIN0 and GND.
in5: Voltage over AIN1 and GND.
in6: Voltage over AIN2 and GND.
in7: Voltage over AIN3 and GND.
Which inputs are available can be configured using platform data or devicetree.
By default all inputs are exported.
Platform Data
-------------
In linux/i2c/ads1015.h platform data is defined, channel_data contains
configuration data for the used input combinations:
- pga is the programmable gain amplifier (values are full scale)
0: +/- 6.144 V
1: +/- 4.096 V
2: +/- 2.048 V
3: +/- 1.024 V
4: +/- 0.512 V
5: +/- 0.256 V
- data_rate in samples per second
0: 128
1: 250
2: 490
3: 920
4: 1600
5: 2400
6: 3300
Example:
struct ads1015_platform_data data = {
.channel_data = {
[2] = { .enabled = true, .pga = 1, .data_rate = 0 },
[4] = { .enabled = true, .pga = 4, .data_rate = 5 },
}
};
In this case only in2_input (FS +/- 4.096 V, 128 SPS) and in4_input
(FS +/- 0.512 V, 2400 SPS) would be created.
Devicetree
----------
Configuration is also possible via devicetree:
Documentation/devicetree/bindings/hwmon/ads1015.txt
......@@ -7,6 +7,11 @@ Supported chips:
Addresses scanned: I2C 0x48 - 0x4f
Datasheet: Publicly available at the National Semiconductor website
http://www.national.com/
* National Semiconductor LM75A
Prefix: 'lm75a'
Addresses scanned: I2C 0x48 - 0x4f
Datasheet: Publicly available at the National Semiconductor website
http://www.national.com/
* Dallas Semiconductor DS75
Prefix: 'lm75'
Addresses scanned: I2C 0x48 - 0x4f
......
Kernel driver sch5627
=====================
Supported chips:
* SMSC SCH5627
Prefix: 'sch5627'
Addresses scanned: none, address read from Super I/O config space
Datasheet: Application Note available upon request
Author: Hans de Goede <hdegoede@redhat.com>
Description
-----------
SMSC SCH5627 Super I/O chips include complete hardware monitoring
capabilities. They can monitor up to 5 voltages, 4 fans and 8 temperatures.
The hardware monitoring part of the SMSC SCH5627 is accessed by talking
through an embedded microcontroller. An application note describing the
protocol for communicating with the microcontroller is available upon
request. Please mail me if you want a copy.
Kernel driver w83795
====================
Supported chips:
* Winbond/Nuvoton W83795G
Prefix: 'w83795g'
Addresses scanned: I2C 0x2c - 0x2f
Datasheet: Available for download on nuvoton.com
* Winbond/Nuvoton W83795ADG
Prefix: 'w83795adg'
Addresses scanned: I2C 0x2c - 0x2f
Datasheet: Available for download on nuvoton.com
Authors:
Wei Song (Nuvoton)
Jean Delvare <khali@linux-fr.org>
Pin mapping
-----------
Here is a summary of the pin mapping for the W83795G and W83795ADG.
This can be useful to convert data provided by board manufacturers
into working libsensors configuration statements.
W83795G |
Pin | Name | Register | Sysfs attribute
------------------------------------------------------------------
13 | VSEN1 (VCORE1) | 10h | in0
14 | VSEN2 (VCORE2) | 11h | in1
15 | VSEN3 (VCORE3) | 12h | in2
16 | VSEN4 | 13h | in3
17 | VSEN5 | 14h | in4
18 | VSEN6 | 15h | in5
19 | VSEN7 | 16h | in6
20 | VSEN8 | 17h | in7
21 | VSEN9 | 18h | in8
22 | VSEN10 | 19h | in9
23 | VSEN11 | 1Ah | in10
28 | VTT | 1Bh | in11
24 | 3VDD | 1Ch | in12
25 | 3VSB | 1Dh | in13
26 | VBAT | 1Eh | in14
3 | VSEN12/TR5 | 1Fh | in15/temp5
4 | VSEN13/TR5 | 20h | in16/temp6
5/ 6 | VDSEN14/TR1/TD1 | 21h | in17/temp1
7/ 8 | VDSEN15/TR2/TD2 | 22h | in18/temp2
9/ 10 | VDSEN16/TR3/TD3 | 23h | in19/temp3
11/ 12 | VDSEN17/TR4/TD4 | 24h | in20/temp4
40 | FANIN1 | 2Eh | fan1
42 | FANIN2 | 2Fh | fan2
44 | FANIN3 | 30h | fan3
46 | FANIN4 | 31h | fan4
48 | FANIN5 | 32h | fan5
50 | FANIN6 | 33h | fan6
52 | FANIN7 | 34h | fan7
54 | FANIN8 | 35h | fan8
57 | FANIN9 | 36h | fan9
58 | FANIN10 | 37h | fan10
59 | FANIN11 | 38h | fan11
60 | FANIN12 | 39h | fan12
31 | FANIN13 | 3Ah | fan13
35 | FANIN14 | 3Bh | fan14
41 | FANCTL1 | 10h (bank 2) | pwm1
43 | FANCTL2 | 11h (bank 2) | pwm2
45 | FANCTL3 | 12h (bank 2) | pwm3
47 | FANCTL4 | 13h (bank 2) | pwm4
49 | FANCTL5 | 14h (bank 2) | pwm5
51 | FANCTL6 | 15h (bank 2) | pwm6
53 | FANCTL7 | 16h (bank 2) | pwm7
55 | FANCTL8 | 17h (bank 2) | pwm8
29/ 30 | PECI/TSI (DTS1) | 26h | temp7
29/ 30 | PECI/TSI (DTS2) | 27h | temp8
29/ 30 | PECI/TSI (DTS3) | 28h | temp9
29/ 30 | PECI/TSI (DTS4) | 29h | temp10
29/ 30 | PECI/TSI (DTS5) | 2Ah | temp11
29/ 30 | PECI/TSI (DTS6) | 2Bh | temp12
29/ 30 | PECI/TSI (DTS7) | 2Ch | temp13
29/ 30 | PECI/TSI (DTS8) | 2Dh | temp14
27 | CASEOPEN# | 46h | intrusion0
W83795ADG |
Pin | Name | Register | Sysfs attribute
------------------------------------------------------------------
10 | VSEN1 (VCORE1) | 10h | in0
11 | VSEN2 (VCORE2) | 11h | in1
12 | VSEN3 (VCORE3) | 12h | in2
13 | VSEN4 | 13h | in3
14 | VSEN5 | 14h | in4
15 | VSEN6 | 15h | in5
16 | VSEN7 | 16h | in6
17 | VSEN8 | 17h | in7
22 | VTT | 1Bh | in11
18 | 3VDD | 1Ch | in12
19 | 3VSB | 1Dh | in13
20 | VBAT | 1Eh | in14
48 | VSEN12/TR5 | 1Fh | in15/temp5
1 | VSEN13/TR5 | 20h | in16/temp6
2/ 3 | VDSEN14/TR1/TD1 | 21h | in17/temp1
4/ 5 | VDSEN15/TR2/TD2 | 22h | in18/temp2
6/ 7 | VDSEN16/TR3/TD3 | 23h | in19/temp3
8/ 9 | VDSEN17/TR4/TD4 | 24h | in20/temp4
32 | FANIN1 | 2Eh | fan1
34 | FANIN2 | 2Fh | fan2
36 | FANIN3 | 30h | fan3
37 | FANIN4 | 31h | fan4
38 | FANIN5 | 32h | fan5
39 | FANIN6 | 33h | fan6
40 | FANIN7 | 34h | fan7
41 | FANIN8 | 35h | fan8
43 | FANIN9 | 36h | fan9
44 | FANIN10 | 37h | fan10
45 | FANIN11 | 38h | fan11
46 | FANIN12 | 39h | fan12
24 | FANIN13 | 3Ah | fan13
28 | FANIN14 | 3Bh | fan14
33 | FANCTL1 | 10h (bank 2) | pwm1
35 | FANCTL2 | 11h (bank 2) | pwm2
23 | PECI (DTS1) | 26h | temp7
23 | PECI (DTS2) | 27h | temp8
23 | PECI (DTS3) | 28h | temp9
23 | PECI (DTS4) | 29h | temp10
23 | PECI (DTS5) | 2Ah | temp11
23 | PECI (DTS6) | 2Bh | temp12
23 | PECI (DTS7) | 2Ch | temp13
23 | PECI (DTS8) | 2Dh | temp14
21 | CASEOPEN# | 46h | intrusion0
......@@ -17,8 +17,8 @@ Description
This driver provides support for the accelerometer found in various HP laptops
sporting the feature officially called "HP Mobile Data Protection System 3D" or
"HP 3D DriveGuard". It detects automatically laptops with this sensor. Known
models (full list can be found in drivers/hwmon/hp_accel.c) will have their
axis automatically oriented on standard way (eg: you can directly play
models (full list can be found in drivers/platform/x86/hp_accel.c) will have
their axis automatically oriented on standard way (eg: you can directly play
neverball). The accelerometer data is readable via
/sys/devices/platform/lis3lv02d. Reported values are scaled
to mg values (1/1000th of earth gravity).
......
......@@ -198,7 +198,7 @@ F: Documentation/scsi/aacraid.txt
F: drivers/scsi/aacraid/
ABIT UGURU 1,2 HARDWARE MONITOR DRIVER
M: Hans de Goede <j.w.r.degoede@hhs.nl>
M: Hans de Goede <hdegoede@redhat.com>
L: lm-sensors@lm-sensors.org
S: Maintained
F: drivers/hwmon/abituguru.c
......@@ -365,6 +365,14 @@ W: http://wiki-analog.com/ADP8860
S: Supported
F: drivers/video/backlight/adp8860_bl.c
ADS1015 HARDWARE MONITOR DRIVER
M: Dirk Eibach <eibach@gdsys.de>
L: lm-sensors@lm-sensors.org
S: Maintained
F: Documentation/hwmon/ads1015
F: drivers/hwmon/ads1015.c
F: include/linux/i2c/ads1015.h
ADT746X FAN DRIVER
M: Colin Leroy <colin@colino.net>
S: Maintained
......@@ -3913,8 +3921,8 @@ S: Supported
LIS3LV02D ACCELEROMETER DRIVER
M: Eric Piel <eric.piel@tremplin-utc.net>
S: Maintained
F: Documentation/hwmon/lis3lv02d
F: drivers/hwmon/lis3lv02d.*
F: Documentation/misc-devices/lis3lv02d
F: drivers/misc/lis3lv02d/
LLC (802.2)
M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
......@@ -5769,6 +5777,13 @@ S: Supported
F: Documentation/hwmon/emc2103
F: drivers/hwmon/emc2103.c
SMSC SCH5627 HARDWARE MONITOR DRIVER
M: Hans de Goede <hdegoede@redhat.com>
L: lm-sensors@lm-sensors.org
S: Supported
F: Documentation/hwmon/sch5627
F: drivers/hwmon/sch5627.c
SMSC47B397 HARDWARE MONITOR DRIVER
M: "Mark M. Hoffman" <mhoffman@lightlink.com>
L: lm-sensors@lm-sensors.org
......
......@@ -521,7 +521,7 @@ config SENSORS_LM75
- Dallas Semiconductor DS75 and DS1775
- Maxim MAX6625 and MAX6626
- Microchip MCP980x
- National Semiconductor LM75
- National Semiconductor LM75, LM75A
- NXP's LM75A
- ST Microelectronics STDS75
- TelCom (now Microchip) TCN75
......@@ -959,6 +959,25 @@ config SENSORS_SMSC47B397
This driver can also be built as a module. If so, the module
will be called smsc47b397.
config SENSORS_SCH5627
tristate "SMSC SCH5627"
help
If you say yes here you get support for the hardware monitoring
features of the SMSC SCH5627 Super-I/O chip.
This driver can also be built as a module. If so, the module
will be called sch5627.
config SENSORS_ADS1015
tristate "Texas Instruments ADS1015"
depends on I2C
help
If you say yes here you get support for Texas Instruments ADS1015
12-bit 4-input ADC device.
This driver can also be built as a module. If so, the module
will be called ads1015.
config SENSORS_ADS7828
tristate "Texas Instruments ADS7828"
depends on I2C
......@@ -1215,40 +1234,6 @@ config SENSORS_ULTRA45
This driver provides support for the Ultra45 workstation environmental
sensors.
config SENSORS_LIS3_SPI
tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)"
depends on !ACPI && SPI_MASTER && INPUT
select INPUT_POLLDEV
default n
help
This driver provides support for the LIS3LV02Dx accelerometer connected
via SPI. The accelerometer data is readable via
/sys/devices/platform/lis3lv02d.
This driver also provides an absolute input class device, allowing
the laptop to act as a pinball machine-esque joystick.
This driver can also be built as modules. If so, the core module
will be called lis3lv02d and a specific module for the SPI transport
is called lis3lv02d_spi.
config SENSORS_LIS3_I2C
tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (I2C)"
depends on I2C && INPUT
select INPUT_POLLDEV
default n
help
This driver provides support for the LIS3LV02Dx accelerometer connected
via I2C. The accelerometer data is readable via
/sys/devices/platform/lis3lv02d.
This driver also provides an absolute input class device, allowing
the device to act as a pinball machine-esque joystick.
This driver can also be built as modules. If so, the core module
will be called lis3lv02d and a specific module for the I2C transport
is called lis3lv02d_i2c.
config SENSORS_APPLESMC
tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)"
depends on INPUT && X86
......@@ -1296,36 +1281,6 @@ config SENSORS_ATK0110
This driver can also be built as a module. If so, the module
will be called asus_atk0110.
config SENSORS_LIS3LV02D
tristate "STMicroeletronics LIS3* three-axis digital accelerometer"
depends on INPUT
select INPUT_POLLDEV
select NEW_LEDS
select LEDS_CLASS
default n
help
This driver provides support for the LIS3* accelerometers, such as the
LIS3LV02DL or the LIS331DL. In particular, it can be found in a number
of HP laptops, which have the "Mobile Data Protection System 3D" or
"3D DriveGuard" feature. On such systems the driver should load
automatically (via ACPI alias). The accelerometer might also be found
in other systems, connected via SPI or I2C. The accelerometer data is
readable via /sys/devices/platform/lis3lv02d.
This driver also provides an absolute input class device, allowing
a laptop to act as a pinball machine-esque joystick. It provides also
a misc device which can be used to detect free-fall. On HP laptops,
if the led infrastructure is activated, support for a led indicating
disk protection will be provided as hp::hddprotect. For more
information on the feature, refer to Documentation/hwmon/lis3lv02d.
This driver can also be built as modules. If so, the core module
will be called lis3lv02d and a specific module for HP laptops will be
called hp_accel.
Say Y here if you have an applicable laptop and want to experience
the awesome power of lis3lv02d.
endif # ACPI
endif # HWMON
......@@ -29,6 +29,7 @@ obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o
obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o
obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o
obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o
obj-$(CONFIG_SENSORS_ADS1015) += ads1015.o
obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o
obj-$(CONFIG_SENSORS_ADS7871) += ads7871.o
obj-$(CONFIG_SENSORS_ADT7411) += adt7411.o
......@@ -63,9 +64,6 @@ obj-$(CONFIG_SENSORS_JZ4740) += jz4740-hwmon.o
obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o
obj-$(CONFIG_SENSORS_K10TEMP) += k10temp.o
obj-$(CONFIG_SENSORS_LINEAGE) += lineage-pem.o
obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o hp_accel.o
obj-$(CONFIG_SENSORS_LIS3_SPI) += lis3lv02d.o lis3lv02d_spi.o
obj-$(CONFIG_SENSORS_LIS3_I2C) += lis3lv02d.o lis3lv02d_i2c.o
obj-$(CONFIG_SENSORS_LM63) += lm63.o
obj-$(CONFIG_SENSORS_LM70) += lm70.o
obj-$(CONFIG_SENSORS_LM73) += lm73.o
......@@ -93,6 +91,7 @@ obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
obj-$(CONFIG_SENSORS_PC87427) += pc87427.o
obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
obj-$(CONFIG_SENSORS_S3C) += s3c-hwmon.o
obj-$(CONFIG_SENSORS_SCH5627) += sch5627.o
obj-$(CONFIG_SENSORS_SHT15) += sht15.o
obj-$(CONFIG_SENSORS_SHT21) += sht21.o
obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o
......
/*
abituguru.c Copyright (c) 2005-2006 Hans de Goede <j.w.r.degoede@hhs.nl>
abituguru.c Copyright (c) 2005-2006 Hans de Goede <hdegoede@redhat.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -1505,7 +1505,7 @@ static void __exit abituguru_exit(void)
platform_driver_unregister(&abituguru_driver);
}
MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>");
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_DESCRIPTION("Abit uGuru Sensor device");
MODULE_LICENSE("GPL");
......
/*
abituguru3.c
Copyright (c) 2006-2008 Hans de Goede <j.w.r.degoede@hhs.nl>
Copyright (c) 2006-2008 Hans de Goede <hdegoede@redhat.com>
Copyright (c) 2008 Alistair John Strachan <alistair@devzero.co.uk>
This program is free software; you can redistribute it and/or modify
......@@ -1266,7 +1266,7 @@ static void __exit abituguru3_exit(void)
platform_driver_unregister(&abituguru3_driver);
}
MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>");
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_DESCRIPTION("Abit uGuru3 Sensor device");
MODULE_LICENSE("GPL");
......
/*
* ads1015.c - lm_sensors driver for ads1015 12-bit 4-input ADC
* (C) Copyright 2010
* Dirk Eibach, Guntermann & Drunck GmbH <eibach@gdsys.de>
*
* Based on the ads7828 driver by Steve Hardy.
*
* Datasheet available at: http://focus.ti.com/lit/ds/symlink/ads1015.pdf
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/i2c/ads1015.h>
/* ADS1015 registers */
enum {
ADS1015_CONVERSION = 0,
ADS1015_CONFIG = 1,
};
/* PGA fullscale voltages in mV */
static const unsigned int fullscale_table[8] = {
6144, 4096, 2048, 1024, 512, 256, 256, 256 };
/* Data rates in samples per second */
static const unsigned int data_rate_table[8] = {
128, 250, 490, 920, 1600, 2400, 3300, 3300 };
#define ADS1015_DEFAULT_CHANNELS 0xff
#define ADS1015_DEFAULT_PGA 2
#define ADS1015_DEFAULT_DATA_RATE 4
struct ads1015_data {
struct device *hwmon_dev;
struct mutex update_lock; /* mutex protect updates */
struct ads1015_channel_data channel_data[ADS1015_CHANNELS];
};
static s32 ads1015_read_reg(struct i2c_client *client, unsigned int reg)
{
s32 data = i2c_smbus_read_word_data(client, reg);
return (data < 0) ? data : swab16(data);
}
static s32 ads1015_write_reg(struct i2c_client *client, unsigned int reg,
u16 val)
{
return i2c_smbus_write_word_data(client, reg, swab16(val));
}
static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
int *value)
{
u16 config;
s16 conversion;
struct ads1015_data *data = i2c_get_clientdata(client);
unsigned int pga = data->channel_data[channel].pga;
int fullscale;
unsigned int data_rate = data->channel_data[channel].data_rate;
unsigned int conversion_time_ms;
int res;
mutex_lock(&data->update_lock);
/* get channel parameters */
res = ads1015_read_reg(client, ADS1015_CONFIG);
if (res < 0)
goto err_unlock;
config = res;
fullscale = fullscale_table[pga];
conversion_time_ms = DIV_ROUND_UP(1000, data_rate_table[data_rate]);
/* setup and start single conversion */
config &= 0x001f;
config |= (1 << 15) | (1 << 8);
config |= (channel & 0x0007) << 12;
config |= (pga & 0x0007) << 9;
config |= (data_rate & 0x0007) << 5;
res = ads1015_write_reg(client, ADS1015_CONFIG, config);
if (res < 0)
goto err_unlock;
/* wait until conversion finished */
msleep(conversion_time_ms);
res = ads1015_read_reg(client, ADS1015_CONFIG);
if (res < 0)
goto err_unlock;
config = res;
if (!(config & (1 << 15))) {
/* conversion not finished in time */
res = -EIO;
goto err_unlock;
}
res = ads1015_read_reg(client, ADS1015_CONVERSION);
if (res < 0)
goto err_unlock;
conversion = res;
mutex_unlock(&data->update_lock);
*value = DIV_ROUND_CLOSEST(conversion * fullscale, 0x7ff0);
return 0;
err_unlock:
mutex_unlock(&data->update_lock);
return res;
}
/* sysfs callback function */
static ssize_t show_in(struct device *dev, struct device_attribute *da,
char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
int in;
int res;
res = ads1015_read_value(client, attr->index, &in);
return (res < 0) ? res : sprintf(buf, "%d\n", in);
}
static const struct sensor_device_attribute ads1015_in[] = {
SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0),
SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1),
SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2),
SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3),
SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4),
SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5),
SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6),
SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7),
};
/*
* Driver interface
*/
static int ads1015_remove(struct i2c_client *client)
{
struct ads1015_data *data = i2c_get_clientdata(client);
int k;
hwmon_device_unregister(data->hwmon_dev);
for (k = 0; k < ADS1015_CHANNELS; ++k)
device_remove_file(&client->dev, &ads1015_in[k].dev_attr);
kfree(data);
return 0;
}
#ifdef CONFIG_OF
static int ads1015_get_channels_config_of(struct i2c_client *client)
{
struct ads1015_data *data = i2c_get_clientdata(client);
struct device_node *node;
if (!client->dev.of_node
|| !of_get_next_child(client->dev.of_node, NULL))
return -EINVAL;
for_each_child_of_node(client->dev.of_node, node) {
const __be32 *property;
int len;
unsigned int channel;
unsigned int pga = ADS1015_DEFAULT_PGA;
unsigned int data_rate = ADS1015_DEFAULT_DATA_RATE;
property = of_get_property(node, "reg", &len);
if (!property || len != sizeof(int)) {
dev_err(&client->dev, "invalid reg on %s\n",
node->full_name);
continue;
}
channel = be32_to_cpup(property);
if (channel > ADS1015_CHANNELS) {
dev_err(&client->dev,
"invalid channel index %d on %s\n",
channel, node->full_name);
continue;
}
property = of_get_property(node, "ti,gain", &len);
if (property && len == sizeof(int)) {
pga = be32_to_cpup(property);
if (pga > 6) {
dev_err(&client->dev,
"invalid gain on %s\n",
node->full_name);
}
}
property = of_get_property(node, "ti,datarate", &len);
if (property && len == sizeof(int)) {
data_rate = be32_to_cpup(property);
if (data_rate > 7) {
dev_err(&client->dev,
"invalid data_rate on %s\n",
node->full_name);
}
}
data->channel_data[channel].enabled = true;
data->channel_data[channel].pga = pga;
data->channel_data[channel].data_rate = data_rate;
}
return 0;
}
#endif
static void ads1015_get_channels_config(struct i2c_client *client)
{
unsigned int k;
struct ads1015_data *data = i2c_get_clientdata(client);
struct ads1015_platform_data *pdata = dev_get_platdata(&client->dev);
/* prefer platform data */
if (pdata) {
memcpy(data->channel_data, pdata->channel_data,
sizeof(data->channel_data));
return;
}
#ifdef CONFIG_OF
if (!ads1015_get_channels_config_of(client))
return;
#endif
/* fallback on default configuration */
for (k = 0; k < ADS1015_CHANNELS; ++k) {
data->channel_data[k].enabled = true;
data->channel_data[k].pga = ADS1015_DEFAULT_PGA;
data->channel_data[k].data_rate = ADS1015_DEFAULT_DATA_RATE;
}
}
static int ads1015_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ads1015_data *data;
int err;
unsigned int k;
data = kzalloc(sizeof(struct ads1015_data), GFP_KERNEL);
if (!data) {
err = -ENOMEM;
goto exit;
}
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
/* build sysfs attribute group */
ads1015_get_channels_config(client);
for (k = 0; k < ADS1015_CHANNELS; ++k) {
if (!data->channel_data[k].enabled)
continue;
err = device_create_file(&client->dev, &ads1015_in[k].dev_attr);
if (err)
goto exit_free;
}
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:
for (k = 0; k < ADS1015_CHANNELS; ++k)
device_remove_file(&client->dev, &ads1015_in[k].dev_attr);
exit_free:
kfree(data);
exit:
return err;
}
static const struct i2c_device_id ads1015_id[] = {
{ "ads1015", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ads1015_id);
static struct i2c_driver ads1015_driver = {
.driver = {
.name = "ads1015",
},
.probe = ads1015_probe,
.remove = ads1015_remove,
.id_table = ads1015_id,
};
static int __init sensors_ads1015_init(void)
{
return i2c_add_driver(&ads1015_driver);
}
static void __exit sensors_ads1015_exit(void)
{
i2c_del_driver(&ads1015_driver);
}
MODULE_AUTHOR("Dirk Eibach <eibach@gdsys.de>");
MODULE_DESCRIPTION("ADS1015 driver");
MODULE_LICENSE("GPL");
module_init(sensors_ads1015_init);
module_exit(sensors_ads1015_exit);
......@@ -232,13 +232,16 @@ static const struct i2c_device_id lm75_ids[] = {
};
MODULE_DEVICE_TABLE(i2c, lm75_ids);
#define LM75A_ID 0xA1
/* Return 0 if detection is successful, -ENODEV otherwise */
static int lm75_detect(struct i2c_client *new_client,
struct i2c_board_info *info)
{
struct i2c_adapter *adapter = new_client->adapter;
int i;
int cur, conf, hyst, os;
int conf, hyst, os;
bool is_lm75a = 0;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
I2C_FUNC_SMBUS_WORD_DATA))
......@@ -250,37 +253,58 @@ static int lm75_detect(struct i2c_client *new_client,
addresses 0x04-0x07 returning the last read value.
The cycling+unused addresses combination is not tested,
since it would significantly slow the detection down and would
hardly add any value. */
hardly add any value.
/* Unused addresses */
cur = i2c_smbus_read_word_data(new_client, 0);
conf = i2c_smbus_read_byte_data(new_client, 1);
hyst = i2c_smbus_read_word_data(new_client, 2);
if (i2c_smbus_read_word_data(new_client, 4) != hyst
|| i2c_smbus_read_word_data(new_client, 5) != hyst
|| i2c_smbus_read_word_data(new_client, 6) != hyst
|| i2c_smbus_read_word_data(new_client, 7) != hyst)
return -ENODEV;
os = i2c_smbus_read_word_data(new_client, 3);
if (i2c_smbus_read_word_data(new_client, 4) != os
|| i2c_smbus_read_word_data(new_client, 5) != os
|| i2c_smbus_read_word_data(new_client, 6) != os
|| i2c_smbus_read_word_data(new_client, 7) != os)
return -ENODEV;
The National Semiconductor LM75A is different than earlier
LM75s. It has an ID byte of 0xaX (where X is the chip
revision, with 1 being the only revision in existence) in
register 7, and unused registers return 0xff rather than the
last read value. */
/* Unused bits */
conf = i2c_smbus_read_byte_data(new_client, 1);
if (conf & 0xe0)
return -ENODEV;
/* First check for LM75A */
if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) {
/* LM75A returns 0xff on unused registers so
just to be sure we check for that too. */
if (i2c_smbus_read_byte_data(new_client, 4) != 0xff
|| i2c_smbus_read_byte_data(new_client, 5) != 0xff
|| i2c_smbus_read_byte_data(new_client, 6) != 0xff)
return -ENODEV;
is_lm75a = 1;
hyst = i2c_smbus_read_byte_data(new_client, 2);
os = i2c_smbus_read_byte_data(new_client, 3);
} else { /* Traditional style LM75 detection */
/* Unused addresses */
hyst = i2c_smbus_read_byte_data(new_client, 2);
if (i2c_smbus_read_byte_data(new_client, 4) != hyst
|| i2c_smbus_read_byte_data(new_client, 5) != hyst
|| i2c_smbus_read_byte_data(new_client, 6) != hyst
|| i2c_smbus_read_byte_data(new_client, 7) != hyst)
return -ENODEV;
os = i2c_smbus_read_byte_data(new_client, 3);
if (i2c_smbus_read_byte_data(new_client, 4) != os
|| i2c_smbus_read_byte_data(new_client, 5) != os
|| i2c_smbus_read_byte_data(new_client, 6) != os
|| i2c_smbus_read_byte_data(new_client, 7) != os)
return -ENODEV;
}
/* Addresses cycling */
for (i = 8; i < 0xff; i += 8) {
for (i = 8; i <= 248; i += 40) {
if (i2c_smbus_read_byte_data(new_client, i + 1) != conf
|| i2c_smbus_read_word_data(new_client, i + 2) != hyst
|| i2c_smbus_read_word_data(new_client, i + 3) != os)
|| i2c_smbus_read_byte_data(new_client, i + 2) != hyst
|| i2c_smbus_read_byte_data(new_client, i + 3) != os)
return -ENODEV;
if (is_lm75a && i2c_smbus_read_byte_data(new_client, i + 7)
!= LM75A_ID)
return -ENODEV;
}
strlcpy(info->type, "lm75", I2C_NAME_SIZE);
strlcpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE);
return 0;
}
......
此差异已折叠。
......@@ -333,11 +333,11 @@ static inline int sht15_calc_humid(struct sht15_data *data)
const int c1 = -4;
const int c2 = 40500; /* x 10 ^ -6 */
const int c3 = -2800; /* x10 ^ -9 */
const int c3 = -28; /* x 10 ^ -7 */
RHlinear = c1*1000
+ c2 * data->val_humid/1000
+ (data->val_humid * data->val_humid * c3)/1000000;
+ (data->val_humid * data->val_humid * c3) / 10000;
return (temp - 25000) * (10000 + 80 * data->val_humid)
/ 1000000 + RHlinear;
}
......@@ -610,7 +610,7 @@ static int __devexit sht15_remove(struct platform_device *pdev)
struct sht15_data *data = platform_get_drvdata(pdev);
/* Make sure any reads from the device are done and
* prevent new ones beginnning */
* prevent new ones from beginning */
mutex_lock(&data->read_lock);
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group);
......
......@@ -2,6 +2,14 @@
# Misc strange devices
#
# This one has to live outside of the MISC_DEVICES conditional,
# because it may be selected by drivers/platform/x86/hp_accel.
config SENSORS_LIS3LV02D
tristate
depends on INPUT
select INPUT_POLLDEV
default n
menuconfig MISC_DEVICES
bool "Misc devices"
---help---
......@@ -462,5 +470,6 @@ source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
source "drivers/misc/iwmc3200top/Kconfig"
source "drivers/misc/ti-st/Kconfig"
source "drivers/misc/lis3lv02d/Kconfig"
endif # MISC_DEVICES
......@@ -42,3 +42,4 @@ obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o
obj-$(CONFIG_PCH_PHUB) += pch_phub.o
obj-y += ti-st/
obj-$(CONFIG_AB8500_PWM) += ab8500-pwm.o
obj-y += lis3lv02d/
#
# STMicroelectonics LIS3LV02D and similar accelerometers
#
config SENSORS_LIS3_SPI
tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)"
depends on !ACPI && SPI_MASTER && INPUT
select SENSORS_LIS3LV02D
default n
help
This driver provides support for the LIS3LV02Dx accelerometer connected
via SPI. The accelerometer data is readable via
/sys/devices/platform/lis3lv02d.
This driver also provides an absolute input class device, allowing
the laptop to act as a pinball machine-esque joystick.
This driver can also be built as modules. If so, the core module
will be called lis3lv02d and a specific module for the SPI transport
is called lis3lv02d_spi.
config SENSORS_LIS3_I2C
tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (I2C)"
depends on I2C && INPUT
select SENSORS_LIS3LV02D
default n
help
This driver provides support for the LIS3LV02Dx accelerometer connected
via I2C. The accelerometer data is readable via
/sys/devices/platform/lis3lv02d.
This driver also provides an absolute input class device, allowing
the device to act as a pinball machine-esque joystick.
This driver can also be built as modules. If so, the core module
will be called lis3lv02d and a specific module for the I2C transport
is called lis3lv02d_i2c.
#
# STMicroelectonics LIS3LV02D and similar accelerometers
#
obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o
obj-$(CONFIG_SENSORS_LIS3_SPI) += lis3lv02d_spi.o
obj-$(CONFIG_SENSORS_LIS3_I2C) += lis3lv02d_i2c.o
......@@ -38,7 +38,7 @@
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
#include <linux/pm_runtime.h>
#include <asm/atomic.h>
#include <linux/atomic.h>
#include "lis3lv02d.h"
#define DRIVER_NAME "lis3lv02d"
......@@ -88,7 +88,6 @@
struct lis3lv02d lis3_dev = {
.misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait),
};
EXPORT_SYMBOL_GPL(lis3_dev);
/* just like param_set_int() but does sanity-check so that it won't point
......
......@@ -33,7 +33,7 @@
#include <linux/delay.h>
#include "lis3lv02d.h"
#define DRV_NAME "lis3lv02d_i2c"
#define DRV_NAME "lis3lv02d_i2c"
static const char reg_vdd[] = "Vdd";
static const char reg_vdd_io[] = "Vdd_IO";
......
......@@ -138,6 +138,24 @@ config TC1100_WMI
This is a driver for the WMI extensions (wireless and bluetooth power
control) of the HP Compaq TC1100 tablet.
config HP_ACCEL
tristate "HP laptop accelerometer"
depends on INPUT && ACPI
select SENSORS_LIS3LV02D
select NEW_LEDS
select LEDS_CLASS
help
This driver provides support for the "Mobile Data Protection System 3D"
or "3D DriveGuard" feature of HP laptops. On such systems the driver
should load automatically (via ACPI alias).
Support for a led indicating disk protection will be provided as
hp::hddprotect. For more information on the feature, refer to
Documentation/hwmon/lis3lv02d.
To compile this driver as a module, choose M here: the module will
be called hp_accel.
config HP_WMI
tristate "HP WMI extras"
depends on ACPI_WMI
......
......@@ -12,6 +12,7 @@ obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o
obj-$(CONFIG_DELL_WMI) += dell-wmi.o
obj-$(CONFIG_ACER_WMI) += acer-wmi.o
obj-$(CONFIG_ACERHDF) += acerhdf.o
obj-$(CONFIG_HP_ACCEL) += hp_accel.o
obj-$(CONFIG_HP_WMI) += hp-wmi.o
obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o
obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o
......
......@@ -35,11 +35,11 @@
#include <linux/freezer.h>
#include <linux/uaccess.h>
#include <linux/leds.h>
#include <linux/atomic.h>
#include <acpi/acpi_drivers.h>
#include <asm/atomic.h>
#include "lis3lv02d.h"
#include "../../misc/lis3lv02d/lis3lv02d.h"
#define DRIVER_NAME "lis3lv02d"
#define DRIVER_NAME "hp_accel"
#define ACPI_MDPS_CLASS "accelerometer"
/* Delayed LEDs infrastructure ------------------------------------ */
......@@ -402,4 +402,3 @@ MODULE_LICENSE("GPL");
module_init(lis3lv02d_init_module);
module_exit(lis3lv02d_exit_module);
/*
* Platform Data for ADS1015 12-bit 4-input ADC
* (C) Copyright 2010
* Dirk Eibach, Guntermann & Drunck GmbH <eibach@gdsys.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef LINUX_ADS1015_H
#define LINUX_ADS1015_H
#define ADS1015_CHANNELS 8
struct ads1015_channel_data {
bool enabled;
unsigned int pga;
unsigned int data_rate;
};
struct ads1015_platform_data {
struct ads1015_channel_data channel_data[ADS1015_CHANNELS];
};
#endif /* LINUX_ADS1015_H */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册