diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-21 17:02:55 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-21 17:02:55 -0400 |
| commit | afd8c40431cc9e3b468a506cbf9957ffca3466fe (patch) | |
| tree | 7d5b54557a67de132d62fcb0b43184a4969644d0 | |
| parent | 366f7e7a79b19bd8c4e8f55fdf12b81538d1a7a4 (diff) | |
| parent | c0046867f34bb81ec3f237ebbc5241ae678b8379 (diff) | |
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
28 files changed, 1702 insertions, 108 deletions
diff --git a/Documentation/devicetree/bindings/hwmon/ads1015.txt b/Documentation/devicetree/bindings/hwmon/ads1015.txt new file mode 100644 index 000000000000..918a507d1159 --- /dev/null +++ b/Documentation/devicetree/bindings/hwmon/ads1015.txt | |||
| @@ -0,0 +1,73 @@ | |||
| 1 | ADS1015 (I2C) | ||
| 2 | |||
| 3 | This device is a 12-bit A-D converter with 4 inputs. | ||
| 4 | |||
| 5 | The inputs can be used single ended or in certain differential combinations. | ||
| 6 | |||
| 7 | For configuration all possible combinations are mapped to 8 channels: | ||
| 8 | 0: Voltage over AIN0 and AIN1. | ||
| 9 | 1: Voltage over AIN0 and AIN3. | ||
| 10 | 2: Voltage over AIN1 and AIN3. | ||
| 11 | 3: Voltage over AIN2 and AIN3. | ||
| 12 | 4: Voltage over AIN0 and GND. | ||
| 13 | 5: Voltage over AIN1 and GND. | ||
| 14 | 6: Voltage over AIN2 and GND. | ||
| 15 | 7: Voltage over AIN3 and GND. | ||
| 16 | |||
| 17 | Each channel can be configured individually: | ||
| 18 | - pga is the programmable gain amplifier (values are full scale) | ||
| 19 | 0: +/- 6.144 V | ||
| 20 | 1: +/- 4.096 V | ||
| 21 | 2: +/- 2.048 V (default) | ||
| 22 | 3: +/- 1.024 V | ||
| 23 | 4: +/- 0.512 V | ||
| 24 | 5: +/- 0.256 V | ||
| 25 | - data_rate in samples per second | ||
| 26 | 0: 128 | ||
| 27 | 1: 250 | ||
| 28 | 2: 490 | ||
| 29 | 3: 920 | ||
| 30 | 4: 1600 (default) | ||
| 31 | 5: 2400 | ||
| 32 | 6: 3300 | ||
| 33 | |||
| 34 | 1) The /ads1015 node | ||
| 35 | |||
| 36 | Required properties: | ||
| 37 | |||
| 38 | - compatible : must be "ti,ads1015" | ||
| 39 | - reg : I2C bus address of the device | ||
| 40 | - #address-cells : must be <1> | ||
| 41 | - #size-cells : must be <0> | ||
| 42 | |||
| 43 | The node contains child nodes for each channel that the platform uses. | ||
| 44 | |||
| 45 | Example ADS1015 node: | ||
| 46 | |||
| 47 | ads1015@49 { | ||
| 48 | compatible = "ti,ads1015"; | ||
| 49 | reg = <0x49>; | ||
| 50 | #address-cells = <1>; | ||
| 51 | #size-cells = <0>; | ||
| 52 | |||
| 53 | [ child node definitions... ] | ||
| 54 | } | ||
| 55 | |||
| 56 | 2) channel nodes | ||
| 57 | |||
| 58 | Required properties: | ||
| 59 | |||
| 60 | - reg : the channel number | ||
| 61 | |||
| 62 | Optional properties: | ||
| 63 | |||
| 64 | - ti,gain : the programmable gain amplifier setting | ||
| 65 | - ti,datarate : the converter data rate | ||
| 66 | |||
| 67 | Example ADS1015 channel node: | ||
| 68 | |||
| 69 | channel@4 { | ||
| 70 | reg = <4>; | ||
| 71 | ti,gain = <3>; | ||
| 72 | ti,datarate = <5>; | ||
| 73 | }; | ||
diff --git a/Documentation/hwmon/ads1015 b/Documentation/hwmon/ads1015 new file mode 100644 index 000000000000..f6fe9c203733 --- /dev/null +++ b/Documentation/hwmon/ads1015 | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | Kernel driver ads1015 | ||
| 2 | ===================== | ||
| 3 | |||
| 4 | Supported chips: | ||
| 5 | * Texas Instruments ADS1015 | ||
| 6 | Prefix: 'ads1015' | ||
| 7 | Datasheet: Publicly available at the Texas Instruments website : | ||
| 8 | http://focus.ti.com/lit/ds/symlink/ads1015.pdf | ||
| 9 | |||
| 10 | Authors: | ||
| 11 | Dirk Eibach, Guntermann & Drunck GmbH <eibach@gdsys.de> | ||
| 12 | |||
| 13 | Description | ||
| 14 | ----------- | ||
| 15 | |||
| 16 | This driver implements support for the Texas Instruments ADS1015. | ||
| 17 | |||
| 18 | This device is a 12-bit A-D converter with 4 inputs. | ||
| 19 | |||
| 20 | The inputs can be used single ended or in certain differential combinations. | ||
| 21 | |||
| 22 | The inputs can be made available by 8 sysfs input files in0_input - in7_input: | ||
| 23 | in0: Voltage over AIN0 and AIN1. | ||
| 24 | in1: Voltage over AIN0 and AIN3. | ||
| 25 | in2: Voltage over AIN1 and AIN3. | ||
| 26 | in3: Voltage over AIN2 and AIN3. | ||
| 27 | in4: Voltage over AIN0 and GND. | ||
| 28 | in5: Voltage over AIN1 and GND. | ||
| 29 | in6: Voltage over AIN2 and GND. | ||
| 30 | in7: Voltage over AIN3 and GND. | ||
| 31 | |||
| 32 | Which inputs are available can be configured using platform data or devicetree. | ||
| 33 | |||
| 34 | By default all inputs are exported. | ||
| 35 | |||
| 36 | Platform Data | ||
| 37 | ------------- | ||
| 38 | |||
| 39 | In linux/i2c/ads1015.h platform data is defined, channel_data contains | ||
| 40 | configuration data for the used input combinations: | ||
| 41 | - pga is the programmable gain amplifier (values are full scale) | ||
| 42 | 0: +/- 6.144 V | ||
| 43 | 1: +/- 4.096 V | ||
| 44 | 2: +/- 2.048 V | ||
| 45 | 3: +/- 1.024 V | ||
| 46 | 4: +/- 0.512 V | ||
| 47 | 5: +/- 0.256 V | ||
| 48 | - data_rate in samples per second | ||
| 49 | 0: 128 | ||
| 50 | 1: 250 | ||
| 51 | 2: 490 | ||
| 52 | 3: 920 | ||
| 53 | 4: 1600 | ||
| 54 | 5: 2400 | ||
| 55 | 6: 3300 | ||
| 56 | |||
| 57 | Example: | ||
| 58 | struct ads1015_platform_data data = { | ||
| 59 | .channel_data = { | ||
| 60 | [2] = { .enabled = true, .pga = 1, .data_rate = 0 }, | ||
| 61 | [4] = { .enabled = true, .pga = 4, .data_rate = 5 }, | ||
| 62 | } | ||
| 63 | }; | ||
| 64 | |||
| 65 | In this case only in2_input (FS +/- 4.096 V, 128 SPS) and in4_input | ||
| 66 | (FS +/- 0.512 V, 2400 SPS) would be created. | ||
| 67 | |||
| 68 | Devicetree | ||
| 69 | ---------- | ||
| 70 | |||
| 71 | Configuration is also possible via devicetree: | ||
| 72 | Documentation/devicetree/bindings/hwmon/ads1015.txt | ||
diff --git a/Documentation/hwmon/lm75 b/Documentation/hwmon/lm75 index 8e6356fe05d7..a1790401fdde 100644 --- a/Documentation/hwmon/lm75 +++ b/Documentation/hwmon/lm75 | |||
| @@ -7,6 +7,11 @@ Supported chips: | |||
| 7 | Addresses scanned: I2C 0x48 - 0x4f | 7 | Addresses scanned: I2C 0x48 - 0x4f |
| 8 | Datasheet: Publicly available at the National Semiconductor website | 8 | Datasheet: Publicly available at the National Semiconductor website |
| 9 | http://www.national.com/ | 9 | http://www.national.com/ |
| 10 | * National Semiconductor LM75A | ||
| 11 | Prefix: 'lm75a' | ||
| 12 | Addresses scanned: I2C 0x48 - 0x4f | ||
| 13 | Datasheet: Publicly available at the National Semiconductor website | ||
| 14 | http://www.national.com/ | ||
| 10 | * Dallas Semiconductor DS75 | 15 | * Dallas Semiconductor DS75 |
| 11 | Prefix: 'lm75' | 16 | Prefix: 'lm75' |
| 12 | Addresses scanned: I2C 0x48 - 0x4f | 17 | Addresses scanned: I2C 0x48 - 0x4f |
diff --git a/Documentation/hwmon/sch5627 b/Documentation/hwmon/sch5627 new file mode 100644 index 000000000000..446a054e4912 --- /dev/null +++ b/Documentation/hwmon/sch5627 | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | Kernel driver sch5627 | ||
| 2 | ===================== | ||
| 3 | |||
| 4 | Supported chips: | ||
| 5 | * SMSC SCH5627 | ||
| 6 | Prefix: 'sch5627' | ||
| 7 | Addresses scanned: none, address read from Super I/O config space | ||
| 8 | Datasheet: Application Note available upon request | ||
| 9 | |||
| 10 | Author: Hans de Goede <hdegoede@redhat.com> | ||
| 11 | |||
| 12 | |||
| 13 | Description | ||
| 14 | ----------- | ||
| 15 | |||
| 16 | SMSC SCH5627 Super I/O chips include complete hardware monitoring | ||
| 17 | capabilities. They can monitor up to 5 voltages, 4 fans and 8 temperatures. | ||
| 18 | |||
| 19 | The hardware monitoring part of the SMSC SCH5627 is accessed by talking | ||
| 20 | through an embedded microcontroller. An application note describing the | ||
| 21 | protocol for communicating with the microcontroller is available upon | ||
| 22 | request. Please mail me if you want a copy. | ||
diff --git a/Documentation/hwmon/w83795 b/Documentation/hwmon/w83795 new file mode 100644 index 000000000000..9f160371f463 --- /dev/null +++ b/Documentation/hwmon/w83795 | |||
| @@ -0,0 +1,127 @@ | |||
| 1 | Kernel driver w83795 | ||
| 2 | ==================== | ||
| 3 | |||
| 4 | Supported chips: | ||
| 5 | * Winbond/Nuvoton W83795G | ||
| 6 | Prefix: 'w83795g' | ||
| 7 | Addresses scanned: I2C 0x2c - 0x2f | ||
| 8 | Datasheet: Available for download on nuvoton.com | ||
| 9 | * Winbond/Nuvoton W83795ADG | ||
| 10 | Prefix: 'w83795adg' | ||
| 11 | Addresses scanned: I2C 0x2c - 0x2f | ||
| 12 | Datasheet: Available for download on nuvoton.com | ||
| 13 | |||
| 14 | Authors: | ||
| 15 | Wei Song (Nuvoton) | ||
| 16 | Jean Delvare <khali@linux-fr.org> | ||
| 17 | |||
| 18 | |||
| 19 | Pin mapping | ||
| 20 | ----------- | ||
| 21 | |||
| 22 | Here is a summary of the pin mapping for the W83795G and W83795ADG. | ||
| 23 | This can be useful to convert data provided by board manufacturers | ||
| 24 | into working libsensors configuration statements. | ||
| 25 | |||
| 26 | W83795G | | ||
| 27 | Pin | Name | Register | Sysfs attribute | ||
| 28 | ------------------------------------------------------------------ | ||
| 29 | 13 | VSEN1 (VCORE1) | 10h | in0 | ||
| 30 | 14 | VSEN2 (VCORE2) | 11h | in1 | ||
| 31 | 15 | VSEN3 (VCORE3) | 12h | in2 | ||
| 32 | 16 | VSEN4 | 13h | in3 | ||
| 33 | 17 | VSEN5 | 14h | in4 | ||
| 34 | 18 | VSEN6 | 15h | in5 | ||
| 35 | 19 | VSEN7 | 16h | in6 | ||
| 36 | 20 | VSEN8 | 17h | in7 | ||
| 37 | 21 | VSEN9 | 18h | in8 | ||
| 38 | 22 | VSEN10 | 19h | in9 | ||
| 39 | 23 | VSEN11 | 1Ah | in10 | ||
| 40 | 28 | VTT | 1Bh | in11 | ||
| 41 | 24 | 3VDD | 1Ch | in12 | ||
| 42 | 25 | 3VSB | 1Dh | in13 | ||
| 43 | 26 | VBAT | 1Eh | in14 | ||
| 44 | 3 | VSEN12/TR5 | 1Fh | in15/temp5 | ||
| 45 | 4 | VSEN13/TR5 | 20h | in16/temp6 | ||
| 46 | 5/ 6 | VDSEN14/TR1/TD1 | 21h | in17/temp1 | ||
| 47 | 7/ 8 | VDSEN15/TR2/TD2 | 22h | in18/temp2 | ||
| 48 | 9/ 10 | VDSEN16/TR3/TD3 | 23h | in19/temp3 | ||
| 49 | 11/ 12 | VDSEN17/TR4/TD4 | 24h | in20/temp4 | ||
| 50 | 40 | FANIN1 | 2Eh | fan1 | ||
| 51 | 42 | FANIN2 | 2Fh | fan2 | ||
| 52 | 44 | FANIN3 | 30h | fan3 | ||
| 53 | 46 | FANIN4 | 31h | fan4 | ||
| 54 | 48 | FANIN5 | 32h | fan5 | ||
| 55 | 50 | FANIN6 | 33h | fan6 | ||
| 56 | 52 | FANIN7 | 34h | fan7 | ||
| 57 | 54 | FANIN8 | 35h | fan8 | ||
| 58 | 57 | FANIN9 | 36h | fan9 | ||
| 59 | 58 | FANIN10 | 37h | fan10 | ||
| 60 | 59 | FANIN11 | 38h | fan11 | ||
| 61 | 60 | FANIN12 | 39h | fan12 | ||
| 62 | 31 | FANIN13 | 3Ah | fan13 | ||
| 63 | 35 | FANIN14 | 3Bh | fan14 | ||
| 64 | 41 | FANCTL1 | 10h (bank 2) | pwm1 | ||
| 65 | 43 | FANCTL2 | 11h (bank 2) | pwm2 | ||
| 66 | 45 | FANCTL3 | 12h (bank 2) | pwm3 | ||
| 67 | 47 | FANCTL4 | 13h (bank 2) | pwm4 | ||
| 68 | 49 | FANCTL5 | 14h (bank 2) | pwm5 | ||
| 69 | 51 | FANCTL6 | 15h (bank 2) | pwm6 | ||
| 70 | 53 | FANCTL7 | 16h (bank 2) | pwm7 | ||
| 71 | 55 | FANCTL8 | 17h (bank 2) | pwm8 | ||
| 72 | 29/ 30 | PECI/TSI (DTS1) | 26h | temp7 | ||
| 73 | 29/ 30 | PECI/TSI (DTS2) | 27h | temp8 | ||
| 74 | 29/ 30 | PECI/TSI (DTS3) | 28h | temp9 | ||
| 75 | 29/ 30 | PECI/TSI (DTS4) | 29h | temp10 | ||
| 76 | 29/ 30 | PECI/TSI (DTS5) | 2Ah | temp11 | ||
| 77 | 29/ 30 | PECI/TSI (DTS6) | 2Bh | temp12 | ||
| 78 | 29/ 30 | PECI/TSI (DTS7) | 2Ch | temp13 | ||
| 79 | 29/ 30 | PECI/TSI (DTS8) | 2Dh | temp14 | ||
| 80 | 27 | CASEOPEN# | 46h | intrusion0 | ||
| 81 | |||
| 82 | W83795ADG | | ||
| 83 | Pin | Name | Register | Sysfs attribute | ||
| 84 | ------------------------------------------------------------------ | ||
| 85 | 10 | VSEN1 (VCORE1) | 10h | in0 | ||
| 86 | 11 | VSEN2 (VCORE2) | 11h | in1 | ||
| 87 | 12 | VSEN3 (VCORE3) | 12h | in2 | ||
| 88 | 13 | VSEN4 | 13h | in3 | ||
| 89 | 14 | VSEN5 | 14h | in4 | ||
| 90 | 15 | VSEN6 | 15h | in5 | ||
| 91 | 16 | VSEN7 | 16h | in6 | ||
| 92 | 17 | VSEN8 | 17h | in7 | ||
| 93 | 22 | VTT | 1Bh | in11 | ||
| 94 | 18 | 3VDD | 1Ch | in12 | ||
| 95 | 19 | 3VSB | 1Dh | in13 | ||
| 96 | 20 | VBAT | 1Eh | in14 | ||
| 97 | 48 | VSEN12/TR5 | 1Fh | in15/temp5 | ||
| 98 | 1 | VSEN13/TR5 | 20h | in16/temp6 | ||
| 99 | 2/ 3 | VDSEN14/TR1/TD1 | 21h | in17/temp1 | ||
| 100 | 4/ 5 | VDSEN15/TR2/TD2 | 22h | in18/temp2 | ||
| 101 | 6/ 7 | VDSEN16/TR3/TD3 | 23h | in19/temp3 | ||
| 102 | 8/ 9 | VDSEN17/TR4/TD4 | 24h | in20/temp4 | ||
| 103 | 32 | FANIN1 | 2Eh | fan1 | ||
| 104 | 34 | FANIN2 | 2Fh | fan2 | ||
| 105 | 36 | FANIN3 | 30h | fan3 | ||
| 106 | 37 | FANIN4 | 31h | fan4 | ||
| 107 | 38 | FANIN5 | 32h | fan5 | ||
| 108 | 39 | FANIN6 | 33h | fan6 | ||
| 109 | 40 | FANIN7 | 34h | fan7 | ||
| 110 | 41 | FANIN8 | 35h | fan8 | ||
| 111 | 43 | FANIN9 | 36h | fan9 | ||
| 112 | 44 | FANIN10 | 37h | fan10 | ||
| 113 | 45 | FANIN11 | 38h | fan11 | ||
| 114 | 46 | FANIN12 | 39h | fan12 | ||
| 115 | 24 | FANIN13 | 3Ah | fan13 | ||
| 116 | 28 | FANIN14 | 3Bh | fan14 | ||
| 117 | 33 | FANCTL1 | 10h (bank 2) | pwm1 | ||
| 118 | 35 | FANCTL2 | 11h (bank 2) | pwm2 | ||
| 119 | 23 | PECI (DTS1) | 26h | temp7 | ||
| 120 | 23 | PECI (DTS2) | 27h | temp8 | ||
| 121 | 23 | PECI (DTS3) | 28h | temp9 | ||
| 122 | 23 | PECI (DTS4) | 29h | temp10 | ||
| 123 | 23 | PECI (DTS5) | 2Ah | temp11 | ||
| 124 | 23 | PECI (DTS6) | 2Bh | temp12 | ||
| 125 | 23 | PECI (DTS7) | 2Ch | temp13 | ||
| 126 | 23 | PECI (DTS8) | 2Dh | temp14 | ||
| 127 | 21 | CASEOPEN# | 46h | intrusion0 | ||
diff --git a/Documentation/hwmon/hpfall.c b/Documentation/laptops/hpfall.c index a4a8fc5d05d4..a4a8fc5d05d4 100644 --- a/Documentation/hwmon/hpfall.c +++ b/Documentation/laptops/hpfall.c | |||
diff --git a/Documentation/hwmon/lis3lv02d b/Documentation/misc-devices/lis3lv02d index 06534f25e643..f1a4ec840f86 100644 --- a/Documentation/hwmon/lis3lv02d +++ b/Documentation/misc-devices/lis3lv02d | |||
| @@ -17,8 +17,8 @@ Description | |||
| 17 | This driver provides support for the accelerometer found in various HP laptops | 17 | This driver provides support for the accelerometer found in various HP laptops |
| 18 | sporting the feature officially called "HP Mobile Data Protection System 3D" or | 18 | sporting the feature officially called "HP Mobile Data Protection System 3D" or |
| 19 | "HP 3D DriveGuard". It detects automatically laptops with this sensor. Known | 19 | "HP 3D DriveGuard". It detects automatically laptops with this sensor. Known |
| 20 | models (full list can be found in drivers/hwmon/hp_accel.c) will have their | 20 | models (full list can be found in drivers/platform/x86/hp_accel.c) will have |
| 21 | axis automatically oriented on standard way (eg: you can directly play | 21 | their axis automatically oriented on standard way (eg: you can directly play |
| 22 | neverball). The accelerometer data is readable via | 22 | neverball). The accelerometer data is readable via |
| 23 | /sys/devices/platform/lis3lv02d. Reported values are scaled | 23 | /sys/devices/platform/lis3lv02d. Reported values are scaled |
| 24 | to mg values (1/1000th of earth gravity). | 24 | to mg values (1/1000th of earth gravity). |
diff --git a/MAINTAINERS b/MAINTAINERS index c7a41b1fe453..38077a656820 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -198,7 +198,7 @@ F: Documentation/scsi/aacraid.txt | |||
| 198 | F: drivers/scsi/aacraid/ | 198 | F: drivers/scsi/aacraid/ |
| 199 | 199 | ||
| 200 | ABIT UGURU 1,2 HARDWARE MONITOR DRIVER | 200 | ABIT UGURU 1,2 HARDWARE MONITOR DRIVER |
| 201 | M: Hans de Goede <j.w.r.degoede@hhs.nl> | 201 | M: Hans de Goede <hdegoede@redhat.com> |
| 202 | L: lm-sensors@lm-sensors.org | 202 | L: lm-sensors@lm-sensors.org |
| 203 | S: Maintained | 203 | S: Maintained |
| 204 | F: drivers/hwmon/abituguru.c | 204 | F: drivers/hwmon/abituguru.c |
| @@ -365,6 +365,14 @@ W: http://wiki-analog.com/ADP8860 | |||
| 365 | S: Supported | 365 | S: Supported |
| 366 | F: drivers/video/backlight/adp8860_bl.c | 366 | F: drivers/video/backlight/adp8860_bl.c |
| 367 | 367 | ||
| 368 | ADS1015 HARDWARE MONITOR DRIVER | ||
| 369 | M: Dirk Eibach <eibach@gdsys.de> | ||
| 370 | L: lm-sensors@lm-sensors.org | ||
| 371 | S: Maintained | ||
| 372 | F: Documentation/hwmon/ads1015 | ||
| 373 | F: drivers/hwmon/ads1015.c | ||
| 374 | F: include/linux/i2c/ads1015.h | ||
| 375 | |||
| 368 | ADT746X FAN DRIVER | 376 | ADT746X FAN DRIVER |
| 369 | M: Colin Leroy <colin@colino.net> | 377 | M: Colin Leroy <colin@colino.net> |
| 370 | S: Maintained | 378 | S: Maintained |
| @@ -3913,8 +3921,8 @@ S: Supported | |||
| 3913 | LIS3LV02D ACCELEROMETER DRIVER | 3921 | LIS3LV02D ACCELEROMETER DRIVER |
| 3914 | M: Eric Piel <eric.piel@tremplin-utc.net> | 3922 | M: Eric Piel <eric.piel@tremplin-utc.net> |
| 3915 | S: Maintained | 3923 | S: Maintained |
| 3916 | F: Documentation/hwmon/lis3lv02d | 3924 | F: Documentation/misc-devices/lis3lv02d |
| 3917 | F: drivers/hwmon/lis3lv02d.* | 3925 | F: drivers/misc/lis3lv02d/ |
| 3918 | 3926 | ||
| 3919 | LLC (802.2) | 3927 | LLC (802.2) |
| 3920 | M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | 3928 | M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> |
| @@ -5769,6 +5777,13 @@ S: Supported | |||
| 5769 | F: Documentation/hwmon/emc2103 | 5777 | F: Documentation/hwmon/emc2103 |
| 5770 | F: drivers/hwmon/emc2103.c | 5778 | F: drivers/hwmon/emc2103.c |
| 5771 | 5779 | ||
| 5780 | SMSC SCH5627 HARDWARE MONITOR DRIVER | ||
| 5781 | M: Hans de Goede <hdegoede@redhat.com> | ||
| 5782 | L: lm-sensors@lm-sensors.org | ||
| 5783 | S: Supported | ||
| 5784 | F: Documentation/hwmon/sch5627 | ||
| 5785 | F: drivers/hwmon/sch5627.c | ||
| 5786 | |||
| 5772 | SMSC47B397 HARDWARE MONITOR DRIVER | 5787 | SMSC47B397 HARDWARE MONITOR DRIVER |
| 5773 | M: "Mark M. Hoffman" <mhoffman@lightlink.com> | 5788 | M: "Mark M. Hoffman" <mhoffman@lightlink.com> |
| 5774 | L: lm-sensors@lm-sensors.org | 5789 | L: lm-sensors@lm-sensors.org |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 1bfb4439e4e1..e4bd13b3cd8b 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
| @@ -521,7 +521,7 @@ config SENSORS_LM75 | |||
| 521 | - Dallas Semiconductor DS75 and DS1775 | 521 | - Dallas Semiconductor DS75 and DS1775 |
| 522 | - Maxim MAX6625 and MAX6626 | 522 | - Maxim MAX6625 and MAX6626 |
| 523 | - Microchip MCP980x | 523 | - Microchip MCP980x |
| 524 | - National Semiconductor LM75 | 524 | - National Semiconductor LM75, LM75A |
| 525 | - NXP's LM75A | 525 | - NXP's LM75A |
| 526 | - ST Microelectronics STDS75 | 526 | - ST Microelectronics STDS75 |
| 527 | - TelCom (now Microchip) TCN75 | 527 | - TelCom (now Microchip) TCN75 |
| @@ -959,6 +959,25 @@ config SENSORS_SMSC47B397 | |||
| 959 | This driver can also be built as a module. If so, the module | 959 | This driver can also be built as a module. If so, the module |
| 960 | will be called smsc47b397. | 960 | will be called smsc47b397. |
| 961 | 961 | ||
| 962 | config SENSORS_SCH5627 | ||
| 963 | tristate "SMSC SCH5627" | ||
| 964 | help | ||
| 965 | If you say yes here you get support for the hardware monitoring | ||
| 966 | features of the SMSC SCH5627 Super-I/O chip. | ||
| 967 | |||
| 968 | This driver can also be built as a module. If so, the module | ||
| 969 | will be called sch5627. | ||
| 970 | |||
| 971 | config SENSORS_ADS1015 | ||
| 972 | tristate "Texas Instruments ADS1015" | ||
| 973 | depends on I2C | ||
| 974 | help | ||
| 975 | If you say yes here you get support for Texas Instruments ADS1015 | ||
| 976 | 12-bit 4-input ADC device. | ||
| 977 | |||
| 978 | This driver can also be built as a module. If so, the module | ||
| 979 | will be called ads1015. | ||
| 980 | |||
| 962 | config SENSORS_ADS7828 | 981 | config SENSORS_ADS7828 |
| 963 | tristate "Texas Instruments ADS7828" | 982 | tristate "Texas Instruments ADS7828" |
| 964 | depends on I2C | 983 | depends on I2C |
| @@ -1215,40 +1234,6 @@ config SENSORS_ULTRA45 | |||
| 1215 | This driver provides support for the Ultra45 workstation environmental | 1234 | This driver provides support for the Ultra45 workstation environmental |
| 1216 | sensors. | 1235 | sensors. |
| 1217 | 1236 | ||
| 1218 | config SENSORS_LIS3_SPI | ||
| 1219 | tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)" | ||
| 1220 | depends on !ACPI && SPI_MASTER && INPUT | ||
| 1221 | select INPUT_POLLDEV | ||
| 1222 | default n | ||
| 1223 | help | ||
| 1224 | This driver provides support for the LIS3LV02Dx accelerometer connected | ||
| 1225 | via SPI. The accelerometer data is readable via | ||
| 1226 | /sys/devices/platform/lis3lv02d. | ||
| 1227 | |||
| 1228 | This driver also provides an absolute input class device, allowing | ||
| 1229 | the laptop to act as a pinball machine-esque joystick. | ||
| 1230 | |||
| 1231 | This driver can also be built as modules. If so, the core module | ||
| 1232 | will be called lis3lv02d and a specific module for the SPI transport | ||
| 1233 | is called lis3lv02d_spi. | ||
| 1234 | |||
| 1235 | config SENSORS_LIS3_I2C | ||
| 1236 | tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (I2C)" | ||
| 1237 | depends on I2C && INPUT | ||
| 1238 | select INPUT_POLLDEV | ||
| 1239 | default n | ||
| 1240 | help | ||
| 1241 | This driver provides support for the LIS3LV02Dx accelerometer connected | ||
| 1242 | via I2C. The accelerometer data is readable via | ||
| 1243 | /sys/devices/platform/lis3lv02d. | ||
| 1244 | |||
| 1245 | This driver also provides an absolute input class device, allowing | ||
| 1246 | the device to act as a pinball machine-esque joystick. | ||
| 1247 | |||
| 1248 | This driver can also be built as modules. If so, the core module | ||
| 1249 | will be called lis3lv02d and a specific module for the I2C transport | ||
| 1250 | is called lis3lv02d_i2c. | ||
| 1251 | |||
| 1252 | config SENSORS_APPLESMC | 1237 | config SENSORS_APPLESMC |
| 1253 | tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)" | 1238 | tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)" |
| 1254 | depends on INPUT && X86 | 1239 | depends on INPUT && X86 |
| @@ -1296,36 +1281,6 @@ config SENSORS_ATK0110 | |||
| 1296 | This driver can also be built as a module. If so, the module | 1281 | This driver can also be built as a module. If so, the module |
| 1297 | will be called asus_atk0110. | 1282 | will be called asus_atk0110. |
| 1298 | 1283 | ||
| 1299 | config SENSORS_LIS3LV02D | ||
| 1300 | tristate "STMicroeletronics LIS3* three-axis digital accelerometer" | ||
| 1301 | depends on INPUT | ||
| 1302 | select INPUT_POLLDEV | ||
| 1303 | select NEW_LEDS | ||
| 1304 | select LEDS_CLASS | ||
| 1305 | default n | ||
| 1306 | help | ||
| 1307 | This driver provides support for the LIS3* accelerometers, such as the | ||
| 1308 | LIS3LV02DL or the LIS331DL. In particular, it can be found in a number | ||
| 1309 | of HP laptops, which have the "Mobile Data Protection System 3D" or | ||
| 1310 | "3D DriveGuard" feature. On such systems the driver should load | ||
| 1311 | automatically (via ACPI alias). The accelerometer might also be found | ||
| 1312 | in other systems, connected via SPI or I2C. The accelerometer data is | ||
| 1313 | readable via /sys/devices/platform/lis3lv02d. | ||
| 1314 | |||
| 1315 | This driver also provides an absolute input class device, allowing | ||
| 1316 | a laptop to act as a pinball machine-esque joystick. It provides also | ||
| 1317 | a misc device which can be used to detect free-fall. On HP laptops, | ||
| 1318 | if the led infrastructure is activated, support for a led indicating | ||
| 1319 | disk protection will be provided as hp::hddprotect. For more | ||
| 1320 | information on the feature, refer to Documentation/hwmon/lis3lv02d. | ||
| 1321 | |||
| 1322 | This driver can also be built as modules. If so, the core module | ||
| 1323 | will be called lis3lv02d and a specific module for HP laptops will be | ||
| 1324 | called hp_accel. | ||
| 1325 | |||
| 1326 | Say Y here if you have an applicable laptop and want to experience | ||
| 1327 | the awesome power of lis3lv02d. | ||
| 1328 | |||
| 1329 | endif # ACPI | 1284 | endif # ACPI |
| 1330 | 1285 | ||
| 1331 | endif # HWMON | 1286 | endif # HWMON |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 8a238dec5691..54ca5939d028 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
| @@ -29,6 +29,7 @@ obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o | |||
| 29 | obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o | 29 | obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o |
| 30 | obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o | 30 | obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o |
| 31 | obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o | 31 | obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o |
| 32 | obj-$(CONFIG_SENSORS_ADS1015) += ads1015.o | ||
| 32 | obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o | 33 | obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o |
| 33 | obj-$(CONFIG_SENSORS_ADS7871) += ads7871.o | 34 | obj-$(CONFIG_SENSORS_ADS7871) += ads7871.o |
| 34 | obj-$(CONFIG_SENSORS_ADT7411) += adt7411.o | 35 | obj-$(CONFIG_SENSORS_ADT7411) += adt7411.o |
| @@ -63,9 +64,6 @@ obj-$(CONFIG_SENSORS_JZ4740) += jz4740-hwmon.o | |||
| 63 | obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o | 64 | obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o |
| 64 | obj-$(CONFIG_SENSORS_K10TEMP) += k10temp.o | 65 | obj-$(CONFIG_SENSORS_K10TEMP) += k10temp.o |
| 65 | obj-$(CONFIG_SENSORS_LINEAGE) += lineage-pem.o | 66 | obj-$(CONFIG_SENSORS_LINEAGE) += lineage-pem.o |
| 66 | obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o hp_accel.o | ||
| 67 | obj-$(CONFIG_SENSORS_LIS3_SPI) += lis3lv02d.o lis3lv02d_spi.o | ||
| 68 | obj-$(CONFIG_SENSORS_LIS3_I2C) += lis3lv02d.o lis3lv02d_i2c.o | ||
| 69 | obj-$(CONFIG_SENSORS_LM63) += lm63.o | 67 | obj-$(CONFIG_SENSORS_LM63) += lm63.o |
| 70 | obj-$(CONFIG_SENSORS_LM70) += lm70.o | 68 | obj-$(CONFIG_SENSORS_LM70) += lm70.o |
| 71 | obj-$(CONFIG_SENSORS_LM73) += lm73.o | 69 | obj-$(CONFIG_SENSORS_LM73) += lm73.o |
| @@ -93,6 +91,7 @@ obj-$(CONFIG_SENSORS_PC87360) += pc87360.o | |||
| 93 | obj-$(CONFIG_SENSORS_PC87427) += pc87427.o | 91 | obj-$(CONFIG_SENSORS_PC87427) += pc87427.o |
| 94 | obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o | 92 | obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o |
| 95 | obj-$(CONFIG_SENSORS_S3C) += s3c-hwmon.o | 93 | obj-$(CONFIG_SENSORS_S3C) += s3c-hwmon.o |
| 94 | obj-$(CONFIG_SENSORS_SCH5627) += sch5627.o | ||
| 96 | obj-$(CONFIG_SENSORS_SHT15) += sht15.o | 95 | obj-$(CONFIG_SENSORS_SHT15) += sht15.o |
| 97 | obj-$(CONFIG_SENSORS_SHT21) += sht21.o | 96 | obj-$(CONFIG_SENSORS_SHT21) += sht21.o |
| 98 | obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o | 97 | obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o |
diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c index 8f07a9dda152..0e05aa179eaa 100644 --- a/drivers/hwmon/abituguru.c +++ b/drivers/hwmon/abituguru.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | abituguru.c Copyright (c) 2005-2006 Hans de Goede <j.w.r.degoede@hhs.nl> | 2 | abituguru.c Copyright (c) 2005-2006 Hans de Goede <hdegoede@redhat.com> |
| 3 | 3 | ||
| 4 | This program is free software; you can redistribute it and/or modify | 4 | This program is free software; you can redistribute it and/or modify |
| 5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
| @@ -1505,7 +1505,7 @@ static void __exit abituguru_exit(void) | |||
| 1505 | platform_driver_unregister(&abituguru_driver); | 1505 | platform_driver_unregister(&abituguru_driver); |
| 1506 | } | 1506 | } |
| 1507 | 1507 | ||
| 1508 | MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>"); | 1508 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); |
| 1509 | MODULE_DESCRIPTION("Abit uGuru Sensor device"); | 1509 | MODULE_DESCRIPTION("Abit uGuru Sensor device"); |
| 1510 | MODULE_LICENSE("GPL"); | 1510 | MODULE_LICENSE("GPL"); |
| 1511 | 1511 | ||
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index 48d21e22e930..034cebfcd273 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | abituguru3.c | 2 | abituguru3.c |
| 3 | 3 | ||
| 4 | Copyright (c) 2006-2008 Hans de Goede <j.w.r.degoede@hhs.nl> | 4 | Copyright (c) 2006-2008 Hans de Goede <hdegoede@redhat.com> |
| 5 | Copyright (c) 2008 Alistair John Strachan <alistair@devzero.co.uk> | 5 | Copyright (c) 2008 Alistair John Strachan <alistair@devzero.co.uk> |
| 6 | 6 | ||
| 7 | This program is free software; you can redistribute it and/or modify | 7 | This program is free software; you can redistribute it and/or modify |
| @@ -1266,7 +1266,7 @@ static void __exit abituguru3_exit(void) | |||
| 1266 | platform_driver_unregister(&abituguru3_driver); | 1266 | platform_driver_unregister(&abituguru3_driver); |
| 1267 | } | 1267 | } |
| 1268 | 1268 | ||
| 1269 | MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>"); | 1269 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); |
| 1270 | MODULE_DESCRIPTION("Abit uGuru3 Sensor device"); | 1270 | MODULE_DESCRIPTION("Abit uGuru3 Sensor device"); |
| 1271 | MODULE_LICENSE("GPL"); | 1271 | MODULE_LICENSE("GPL"); |
| 1272 | 1272 | ||
diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c new file mode 100644 index 000000000000..e9beeda4cbe5 --- /dev/null +++ b/drivers/hwmon/ads1015.c | |||
| @@ -0,0 +1,337 @@ | |||
| 1 | /* | ||
| 2 | * ads1015.c - lm_sensors driver for ads1015 12-bit 4-input ADC | ||
| 3 | * (C) Copyright 2010 | ||
| 4 | * Dirk Eibach, Guntermann & Drunck GmbH <eibach@gdsys.de> | ||
| 5 | * | ||
| 6 | * Based on the ads7828 driver by Steve Hardy. | ||
| 7 | * | ||
| 8 | * Datasheet available at: http://focus.ti.com/lit/ds/symlink/ads1015.pdf | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <linux/module.h> | ||
| 26 | #include <linux/init.h> | ||
| 27 | #include <linux/slab.h> | ||
| 28 | #include <linux/delay.h> | ||
| 29 | #include <linux/i2c.h> | ||
| 30 | #include <linux/hwmon.h> | ||
| 31 | #include <linux/hwmon-sysfs.h> | ||
| 32 | #include <linux/err.h> | ||
| 33 | #include <linux/mutex.h> | ||
| 34 | #include <linux/of.h> | ||
| 35 | |||
| 36 | #include <linux/i2c/ads1015.h> | ||
| 37 | |||
| 38 | /* ADS1015 registers */ | ||
| 39 | enum { | ||
| 40 | ADS1015_CONVERSION = 0, | ||
| 41 | ADS1015_CONFIG = 1, | ||
| 42 | }; | ||
| 43 | |||
| 44 | /* PGA fullscale voltages in mV */ | ||
| 45 | static const unsigned int fullscale_table[8] = { | ||
| 46 | 6144, 4096, 2048, 1024, 512, 256, 256, 256 }; | ||
| 47 | |||
| 48 | /* Data rates in samples per second */ | ||
| 49 | static const unsigned int data_rate_table[8] = { | ||
| 50 | 128, 250, 490, 920, 1600, 2400, 3300, 3300 }; | ||
| 51 | |||
| 52 | #define ADS1015_DEFAULT_CHANNELS 0xff | ||
| 53 | #define ADS1015_DEFAULT_PGA 2 | ||
| 54 | #define ADS1015_DEFAULT_DATA_RATE 4 | ||
| 55 | |||
| 56 | struct ads1015_data { | ||
| 57 | struct device *hwmon_dev; | ||
| 58 | struct mutex update_lock; /* mutex protect updates */ | ||
| 59 | struct ads1015_channel_data channel_data[ADS1015_CHANNELS]; | ||
| 60 | }; | ||
| 61 | |||
| 62 | static s32 ads1015_read_reg(struct i2c_client *client, unsigned int reg) | ||
| 63 | { | ||
| 64 | s32 data = i2c_smbus_read_word_data(client, reg); | ||
| 65 | |||
| 66 | return (data < 0) ? data : swab16(data); | ||
| 67 | } | ||
| 68 | |||
| 69 | static s32 ads1015_write_reg(struct i2c_client *client, unsigned int reg, | ||
| 70 | u16 val) | ||
| 71 | { | ||
| 72 | return i2c_smbus_write_word_data(client, reg, swab16(val)); | ||
| 73 | } | ||
| 74 | |||
| 75 | static int ads1015_read_value(struct i2c_client *client, unsigned int channel, | ||
| 76 | int *value) | ||
| 77 | { | ||
| 78 | u16 config; | ||
| 79 | s16 conversion; | ||
| 80 | struct ads1015_data *data = i2c_get_clientdata(client); | ||
| 81 | unsigned int pga = data->channel_data[channel].pga; | ||
| 82 | int fullscale; | ||
| 83 | unsigned int data_rate = data->channel_data[channel].data_rate; | ||
| 84 | unsigned int conversion_time_ms; | ||
| 85 | int res; | ||
| 86 | |||
| 87 | mutex_lock(&data->update_lock); | ||
| 88 | |||
| 89 | /* get channel parameters */ | ||
| 90 | res = ads1015_read_reg(client, ADS1015_CONFIG); | ||
| 91 | if (res < 0) | ||
| 92 | goto err_unlock; | ||
| 93 | config = res; | ||
| 94 | fullscale = fullscale_table[pga]; | ||
| 95 | conversion_time_ms = DIV_ROUND_UP(1000, data_rate_table[data_rate]); | ||
| 96 | |||
| 97 | /* setup and start single conversion */ | ||
| 98 | config &= 0x001f; | ||
| 99 | config |= (1 << 15) | (1 << 8); | ||
| 100 | config |= (channel & 0x0007) << 12; | ||
| 101 | config |= (pga & 0x0007) << 9; | ||
| 102 | config |= (data_rate & 0x0007) << 5; | ||
| 103 | |||
| 104 | res = ads1015_write_reg(client, ADS1015_CONFIG, config); | ||
| 105 | if (res < 0) | ||
| 106 | goto err_unlock; | ||
| 107 | |||
| 108 | /* wait until conversion finished */ | ||
| 109 | msleep(conversion_time_ms); | ||
| 110 | res = ads1015_read_reg(client, ADS1015_CONFIG); | ||
| 111 | if (res < 0) | ||
| 112 | goto err_unlock; | ||
| 113 | config = res; | ||
| 114 | if (!(config & (1 << 15))) { | ||
| 115 | /* conversion not finished in time */ | ||
| 116 | res = -EIO; | ||
| 117 | goto err_unlock; | ||
| 118 | } | ||
| 119 | |||
| 120 | res = ads1015_read_reg(client, ADS1015_CONVERSION); | ||
| 121 | if (res < 0) | ||
| 122 | goto err_unlock; | ||
| 123 | conversion = res; | ||
| 124 | |||
| 125 | mutex_unlock(&data->update_lock); | ||
| 126 | |||
| 127 | *value = DIV_ROUND_CLOSEST(conversion * fullscale, 0x7ff0); | ||
| 128 | |||
| 129 | return 0; | ||
| 130 | |||
| 131 | err_unlock: | ||
| 132 | mutex_unlock(&data->update_lock); | ||
| 133 | return res; | ||
| 134 | } | ||
| 135 | |||
| 136 | /* sysfs callback function */ | ||
| 137 | static ssize_t show_in(struct device *dev, struct device_attribute *da, | ||
| 138 | char *buf) | ||
| 139 | { | ||
| 140 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | ||
| 141 | struct i2c_client *client = to_i2c_client(dev); | ||
| 142 | int in; | ||
| 143 | int res; | ||
| 144 | |||
| 145 | res = ads1015_read_value(client, attr->index, &in); | ||
| 146 | |||
| 147 | return (res < 0) ? res : sprintf(buf, "%d\n", in); | ||
| 148 | } | ||
| 149 | |||
| 150 | static const struct sensor_device_attribute ads1015_in[] = { | ||
| 151 | SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0), | ||
| 152 | SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1), | ||
| 153 | SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2), | ||
| 154 | SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3), | ||
| 155 | SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4), | ||
| 156 | SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5), | ||
| 157 | SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6), | ||
| 158 | SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7), | ||
| 159 | }; | ||
| 160 | |||
| 161 | /* | ||
| 162 | * Driver interface | ||
| 163 | */ | ||
| 164 | |||
| 165 | static int ads1015_remove(struct i2c_client *client) | ||
| 166 | { | ||
| 167 | struct ads1015_data *data = i2c_get_clientdata(client); | ||
| 168 | int k; | ||
| 169 | |||
| 170 | hwmon_device_unregister(data->hwmon_dev); | ||
| 171 | for (k = 0; k < ADS1015_CHANNELS; ++k) | ||
| 172 | device_remove_file(&client->dev, &ads1015_in[k].dev_attr); | ||
| 173 | kfree(data); | ||
| 174 | return 0; | ||
| 175 | } | ||
| 176 | |||
| 177 | #ifdef CONFIG_OF | ||
| 178 | static int ads1015_get_channels_config_of(struct i2c_client *client) | ||
| 179 | { | ||
| 180 | struct ads1015_data *data = i2c_get_clientdata(client); | ||
| 181 | struct device_node *node; | ||
| 182 | |||
| 183 | if (!client->dev.of_node | ||
| 184 | || !of_get_next_child(client->dev.of_node, NULL)) | ||
| 185 | return -EINVAL; | ||
| 186 | |||
| 187 | for_each_child_of_node(client->dev.of_node, node) { | ||
| 188 | const __be32 *property; | ||
| 189 | int len; | ||
| 190 | unsigned int channel; | ||
| 191 | unsigned int pga = ADS1015_DEFAULT_PGA; | ||
| 192 | unsigned int data_rate = ADS1015_DEFAULT_DATA_RATE; | ||
| 193 | |||
| 194 | property = of_get_property(node, "reg", &len); | ||
| 195 | if (!property || len != sizeof(int)) { | ||
| 196 | dev_err(&client->dev, "invalid reg on %s\n", | ||
| 197 | node->full_name); | ||
| 198 | continue; | ||
| 199 | } | ||
| 200 | |||
| 201 | channel = be32_to_cpup(property); | ||
| 202 | if (channel > ADS1015_CHANNELS) { | ||
| 203 | dev_err(&client->dev, | ||
| 204 | "invalid channel index %d on %s\n", | ||
| 205 | channel, node->full_name); | ||
| 206 | continue; | ||
| 207 | } | ||
| 208 | |||
| 209 | property = of_get_property(node, "ti,gain", &len); | ||
| 210 | if (property && len == sizeof(int)) { | ||
| 211 | pga = be32_to_cpup(property); | ||
| 212 | if (pga > 6) { | ||
| 213 | dev_err(&client->dev, | ||
| 214 | "invalid gain on %s\n", | ||
| 215 | node->full_name); | ||
| 216 | } | ||
| 217 | } | ||
| 218 | |||
| 219 | property = of_get_property(node, "ti,datarate", &len); | ||
| 220 | if (property && len == sizeof(int)) { | ||
| 221 | data_rate = be32_to_cpup(property); | ||
| 222 | if (data_rate > 7) { | ||
| 223 | dev_err(&client->dev, | ||
| 224 | "invalid data_rate on %s\n", | ||
| 225 | node->full_name); | ||
| 226 | } | ||
| 227 | } | ||
| 228 | |||
| 229 | data->channel_data[channel].enabled = true; | ||
| 230 | data->channel_data[channel].pga = pga; | ||
| 231 | data->channel_data[channel].data_rate = data_rate; | ||
| 232 | } | ||
| 233 | |||
| 234 | return 0; | ||
| 235 | } | ||
| 236 | #endif | ||
| 237 | |||
| 238 | static void ads1015_get_channels_config(struct i2c_client *client) | ||
| 239 | { | ||
| 240 | unsigned int k; | ||
| 241 | struct ads1015_data *data = i2c_get_clientdata(client); | ||
| 242 | struct ads1015_platform_data *pdata = dev_get_platdata(&client->dev); | ||
| 243 | |||
| 244 | /* prefer platform data */ | ||
| 245 | if (pdata) { | ||
| 246 | memcpy(data->channel_data, pdata->channel_data, | ||
| 247 | sizeof(data->channel_data)); | ||
| 248 | return; | ||
| 249 | } | ||
| 250 | |||
| 251 | #ifdef CONFIG_OF | ||
| 252 | if (!ads1015_get_channels_config_of(client)) | ||
| 253 | return; | ||
| 254 | #endif | ||
| 255 | |||
| 256 | /* fallback on default configuration */ | ||
| 257 | for (k = 0; k < ADS1015_CHANNELS; ++k) { | ||
| 258 | data->channel_data[k].enabled = true; | ||
| 259 | data->channel_data[k].pga = ADS1015_DEFAULT_PGA; | ||
| 260 | data->channel_data[k].data_rate = ADS1015_DEFAULT_DATA_RATE; | ||
| 261 | } | ||
| 262 | } | ||
| 263 | |||
| 264 | static int ads1015_probe(struct i2c_client *client, | ||
| 265 | const struct i2c_device_id *id) | ||
| 266 | { | ||
| 267 | struct ads1015_data *data; | ||
| 268 | int err; | ||
| 269 | unsigned int k; | ||
| 270 | |||
| 271 | data = kzalloc(sizeof(struct ads1015_data), GFP_KERNEL); | ||
| 272 | if (!data) { | ||
| 273 | err = -ENOMEM; | ||
| 274 | goto exit; | ||
| 275 | } | ||
| 276 | |||
| 277 | i2c_set_clientdata(client, data); | ||
| 278 | mutex_init(&data->update_lock); | ||
| 279 | |||
| 280 | /* build sysfs attribute group */ | ||
| 281 | ads1015_get_channels_config(client); | ||
| 282 | for (k = 0; k < ADS1015_CHANNELS; ++k) { | ||
| 283 | if (!data->channel_data[k].enabled) | ||
| 284 | continue; | ||
| 285 | err = device_create_file(&client->dev, &ads1015_in[k].dev_attr); | ||
| 286 | if (err) | ||
| 287 | goto exit_free; | ||
| 288 | } | ||
| 289 | |||
| 290 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
| 291 | if (IS_ERR(data->hwmon_dev)) { | ||
| 292 | err = PTR_ERR(data->hwmon_dev); | ||
| 293 | goto exit_remove; | ||
| 294 | } | ||
| 295 | |||
| 296 | return 0; | ||
| 297 | |||
| 298 | exit_remove: | ||
| 299 | for (k = 0; k < ADS1015_CHANNELS; ++k) | ||
| 300 | device_remove_file(&client->dev, &ads1015_in[k].dev_attr); | ||
| 301 | exit_free: | ||
| 302 | kfree(data); | ||
| 303 | exit: | ||
| 304 | return err; | ||
| 305 | } | ||
| 306 | |||
| 307 | static const struct i2c_device_id ads1015_id[] = { | ||
| 308 | { "ads1015", 0 }, | ||
| 309 | { } | ||
| 310 | }; | ||
| 311 | MODULE_DEVICE_TABLE(i2c, ads1015_id); | ||
| 312 | |||
| 313 | static struct i2c_driver ads1015_driver = { | ||
| 314 | .driver = { | ||
| 315 | .name = "ads1015", | ||
| 316 | }, | ||
| 317 | .probe = ads1015_probe, | ||
| 318 | .remove = ads1015_remove, | ||
| 319 | .id_table = ads1015_id, | ||
| 320 | }; | ||
| 321 | |||
| 322 | static int __init sensors_ads1015_init(void) | ||
| 323 | { | ||
| 324 | return i2c_add_driver(&ads1015_driver); | ||
| 325 | } | ||
| 326 | |||
| 327 | static void __exit sensors_ads1015_exit(void) | ||
| 328 | { | ||
| 329 | i2c_del_driver(&ads1015_driver); | ||
| 330 | } | ||
| 331 | |||
| 332 | MODULE_AUTHOR("Dirk Eibach <eibach@gdsys.de>"); | ||
| 333 | MODULE_DESCRIPTION("ADS1015 driver"); | ||
| 334 | MODULE_LICENSE("GPL"); | ||
| 335 | |||
| 336 | module_init(sensors_ads1015_init); | ||
| 337 | module_exit(sensors_ads1015_exit); | ||
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index f36eb80d227f..ef902d5d06ab 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c | |||
| @@ -232,13 +232,16 @@ static const struct i2c_device_id lm75_ids[] = { | |||
| 232 | }; | 232 | }; |
| 233 | MODULE_DEVICE_TABLE(i2c, lm75_ids); | 233 | MODULE_DEVICE_TABLE(i2c, lm75_ids); |
| 234 | 234 | ||
| 235 | #define LM75A_ID 0xA1 | ||
| 236 | |||
| 235 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 237 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
| 236 | static int lm75_detect(struct i2c_client *new_client, | 238 | static int lm75_detect(struct i2c_client *new_client, |
| 237 | struct i2c_board_info *info) | 239 | struct i2c_board_info *info) |
| 238 | { | 240 | { |
| 239 | struct i2c_adapter *adapter = new_client->adapter; | 241 | struct i2c_adapter *adapter = new_client->adapter; |
| 240 | int i; | 242 | int i; |
| 241 | int cur, conf, hyst, os; | 243 | int conf, hyst, os; |
| 244 | bool is_lm75a = 0; | ||
| 242 | 245 | ||
| 243 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | | 246 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | |
| 244 | I2C_FUNC_SMBUS_WORD_DATA)) | 247 | I2C_FUNC_SMBUS_WORD_DATA)) |
| @@ -250,37 +253,58 @@ static int lm75_detect(struct i2c_client *new_client, | |||
| 250 | addresses 0x04-0x07 returning the last read value. | 253 | addresses 0x04-0x07 returning the last read value. |
| 251 | The cycling+unused addresses combination is not tested, | 254 | The cycling+unused addresses combination is not tested, |
| 252 | since it would significantly slow the detection down and would | 255 | since it would significantly slow the detection down and would |
| 253 | hardly add any value. */ | 256 | hardly add any value. |
| 254 | 257 | ||
| 255 | /* Unused addresses */ | 258 | The National Semiconductor LM75A is different than earlier |
| 256 | cur = i2c_smbus_read_word_data(new_client, 0); | 259 | LM75s. It has an ID byte of 0xaX (where X is the chip |
| 257 | conf = i2c_smbus_read_byte_data(new_client, 1); | 260 | revision, with 1 being the only revision in existence) in |
| 258 | hyst = i2c_smbus_read_word_data(new_client, 2); | 261 | register 7, and unused registers return 0xff rather than the |
| 259 | if (i2c_smbus_read_word_data(new_client, 4) != hyst | 262 | last read value. */ |
| 260 | || i2c_smbus_read_word_data(new_client, 5) != hyst | ||
| 261 | || i2c_smbus_read_word_data(new_client, 6) != hyst | ||
| 262 | || i2c_smbus_read_word_data(new_client, 7) != hyst) | ||
| 263 | return -ENODEV; | ||
| 264 | os = i2c_smbus_read_word_data(new_client, 3); | ||
| 265 | if (i2c_smbus_read_word_data(new_client, 4) != os | ||
| 266 | || i2c_smbus_read_word_data(new_client, 5) != os | ||
| 267 | || i2c_smbus_read_word_data(new_client, 6) != os | ||
| 268 | || i2c_smbus_read_word_data(new_client, 7) != os) | ||
| 269 | return -ENODEV; | ||
| 270 | 263 | ||
| 271 | /* Unused bits */ | 264 | /* Unused bits */ |
| 265 | conf = i2c_smbus_read_byte_data(new_client, 1); | ||
| 272 | if (conf & 0xe0) | 266 | if (conf & 0xe0) |
| 273 | return -ENODEV; | 267 | return -ENODEV; |
| 274 | 268 | ||
| 269 | /* First check for LM75A */ | ||
| 270 | if (i2c_smbus_read_byte_data(new_client, 7) == LM75A_ID) { | ||
| 271 | /* LM75A returns 0xff on unused registers so | ||
| 272 | just to be sure we check for that too. */ | ||
| 273 | if (i2c_smbus_read_byte_data(new_client, 4) != 0xff | ||
| 274 | || i2c_smbus_read_byte_data(new_client, 5) != 0xff | ||
| 275 | || i2c_smbus_read_byte_data(new_client, 6) != 0xff) | ||
| 276 | return -ENODEV; | ||
| 277 | is_lm75a = 1; | ||
| 278 | hyst = i2c_smbus_read_byte_data(new_client, 2); | ||
| 279 | os = i2c_smbus_read_byte_data(new_client, 3); | ||
| 280 | } else { /* Traditional style LM75 detection */ | ||
| 281 | /* Unused addresses */ | ||
| 282 | hyst = i2c_smbus_read_byte_data(new_client, 2); | ||
| 283 | if (i2c_smbus_read_byte_data(new_client, 4) != hyst | ||
| 284 | || i2c_smbus_read_byte_data(new_client, 5) != hyst | ||
| 285 | || i2c_smbus_read_byte_data(new_client, 6) != hyst | ||
| 286 | || i2c_smbus_read_byte_data(new_client, 7) != hyst) | ||
| 287 | return -ENODEV; | ||
| 288 | os = i2c_smbus_read_byte_data(new_client, 3); | ||
| 289 | if (i2c_smbus_read_byte_data(new_client, 4) != os | ||
| 290 | || i2c_smbus_read_byte_data(new_client, 5) != os | ||
| 291 | || i2c_smbus_read_byte_data(new_client, 6) != os | ||
| 292 | || i2c_smbus_read_byte_data(new_client, 7) != os) | ||
| 293 | return -ENODEV; | ||
| 294 | } | ||
| 295 | |||
| 275 | /* Addresses cycling */ | 296 | /* Addresses cycling */ |
| 276 | for (i = 8; i < 0xff; i += 8) { | 297 | for (i = 8; i <= 248; i += 40) { |
| 277 | if (i2c_smbus_read_byte_data(new_client, i + 1) != conf | 298 | if (i2c_smbus_read_byte_data(new_client, i + 1) != conf |
| 278 | || i2c_smbus_read_word_data(new_client, i + 2) != hyst | 299 | || i2c_smbus_read_byte_data(new_client, i + 2) != hyst |
| 279 | || i2c_smbus_read_word_data(new_client, i + 3) != os) | 300 | || i2c_smbus_read_byte_data(new_client, i + 3) != os) |
| 301 | return -ENODEV; | ||
| 302 | if (is_lm75a && i2c_smbus_read_byte_data(new_client, i + 7) | ||
| 303 | != LM75A_ID) | ||
| 280 | return -ENODEV; | 304 | return -ENODEV; |
| 281 | } | 305 | } |
| 282 | 306 | ||
| 283 | strlcpy(info->type, "lm75", I2C_NAME_SIZE); | 307 | strlcpy(info->type, is_lm75a ? "lm75a" : "lm75", I2C_NAME_SIZE); |
| 284 | 308 | ||
| 285 | return 0; | 309 | return 0; |
| 286 | } | 310 | } |
diff --git a/drivers/hwmon/sch5627.c b/drivers/hwmon/sch5627.c new file mode 100644 index 000000000000..9a51dcca9b0d --- /dev/null +++ b/drivers/hwmon/sch5627.c | |||
| @@ -0,0 +1,858 @@ | |||
| 1 | /*************************************************************************** | ||
| 2 | * Copyright (C) 2010-2011 Hans de Goede <hdegoede@redhat.com> * | ||
| 3 | * * | ||
| 4 | * This program is free software; you can redistribute it and/or modify * | ||
| 5 | * it under the terms of the GNU General Public License as published by * | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or * | ||
| 7 | * (at your option) any later version. * | ||
| 8 | * * | ||
| 9 | * This program is distributed in the hope that it will be useful, * | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
| 12 | * GNU General Public License for more details. * | ||
| 13 | * * | ||
| 14 | * You should have received a copy of the GNU General Public License * | ||
| 15 | * along with this program; if not, write to the * | ||
| 16 | * Free Software Foundation, Inc., * | ||
| 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
| 18 | ***************************************************************************/ | ||
| 19 | |||
| 20 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 21 | |||
| 22 | #include <linux/module.h> | ||
| 23 | #include <linux/init.h> | ||
| 24 | #include <linux/slab.h> | ||
| 25 | #include <linux/jiffies.h> | ||
| 26 | #include <linux/platform_device.h> | ||
| 27 | #include <linux/hwmon.h> | ||
| 28 | #include <linux/hwmon-sysfs.h> | ||
| 29 | #include <linux/err.h> | ||
| 30 | #include <linux/mutex.h> | ||
| 31 | #include <linux/io.h> | ||
| 32 | #include <linux/acpi.h> | ||
| 33 | #include <linux/delay.h> | ||
| 34 | |||
| 35 | #define DRVNAME "sch5627" | ||
| 36 | #define DEVNAME DRVNAME /* We only support one model */ | ||
| 37 | |||
| 38 | #define SIO_SCH5627_EM_LD 0x0C /* Embedded Microcontroller LD */ | ||
| 39 | #define SIO_UNLOCK_KEY 0x55 /* Key to enable Super-I/O */ | ||
| 40 | #define SIO_LOCK_KEY 0xAA /* Key to disable Super-I/O */ | ||
| 41 | |||
| 42 | #define SIO_REG_LDSEL 0x07 /* Logical device select */ | ||
| 43 | #define SIO_REG_DEVID 0x20 /* Device ID */ | ||
| 44 | #define SIO_REG_ENABLE 0x30 /* Logical device enable */ | ||
| 45 | #define SIO_REG_ADDR 0x66 /* Logical device address (2 bytes) */ | ||
| 46 | |||
| 47 | #define SIO_SCH5627_ID 0xC6 /* Chipset ID */ | ||
| 48 | |||
| 49 | #define REGION_LENGTH 9 | ||
| 50 | |||
| 51 | #define SCH5627_HWMON_ID 0xa5 | ||
| 52 | #define SCH5627_COMPANY_ID 0x5c | ||
| 53 | #define SCH5627_PRIMARY_ID 0xa0 | ||
| 54 | |||
| 55 | #define SCH5627_REG_BUILD_CODE 0x39 | ||
| 56 | #define SCH5627_REG_BUILD_ID 0x3a | ||
| 57 | #define SCH5627_REG_HWMON_ID 0x3c | ||
| 58 | #define SCH5627_REG_HWMON_REV 0x3d | ||
| 59 | #define SCH5627_REG_COMPANY_ID 0x3e | ||
| 60 | #define SCH5627_REG_PRIMARY_ID 0x3f | ||
| 61 | #define SCH5627_REG_CTRL 0x40 | ||
| 62 | |||
| 63 | #define SCH5627_NO_TEMPS 8 | ||
| 64 | #define SCH5627_NO_FANS 4 | ||
| 65 | #define SCH5627_NO_IN 5 | ||
| 66 | |||
| 67 | static const u16 SCH5627_REG_TEMP_MSB[SCH5627_NO_TEMPS] = { | ||
| 68 | 0x2B, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x180, 0x181 }; | ||
| 69 | static const u16 SCH5627_REG_TEMP_LSN[SCH5627_NO_TEMPS] = { | ||
| 70 | 0xE2, 0xE1, 0xE1, 0xE5, 0xE5, 0xE6, 0x182, 0x182 }; | ||
| 71 | static const u16 SCH5627_REG_TEMP_HIGH_NIBBLE[SCH5627_NO_TEMPS] = { | ||
| 72 | 0, 0, 1, 1, 0, 0, 0, 1 }; | ||
| 73 | static const u16 SCH5627_REG_TEMP_HIGH[SCH5627_NO_TEMPS] = { | ||
| 74 | 0x61, 0x57, 0x59, 0x5B, 0x5D, 0x5F, 0x184, 0x186 }; | ||
| 75 | static const u16 SCH5627_REG_TEMP_ABS[SCH5627_NO_TEMPS] = { | ||
| 76 | 0x9B, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x1A8, 0x1A9 }; | ||
| 77 | |||
| 78 | static const u16 SCH5627_REG_FAN[SCH5627_NO_FANS] = { | ||
| 79 | 0x2C, 0x2E, 0x30, 0x32 }; | ||
| 80 | static const u16 SCH5627_REG_FAN_MIN[SCH5627_NO_FANS] = { | ||
| 81 | 0x62, 0x64, 0x66, 0x68 }; | ||
| 82 | |||
| 83 | static const u16 SCH5627_REG_IN_MSB[SCH5627_NO_IN] = { | ||
| 84 | 0x22, 0x23, 0x24, 0x25, 0x189 }; | ||
| 85 | static const u16 SCH5627_REG_IN_LSN[SCH5627_NO_IN] = { | ||
| 86 | 0xE4, 0xE4, 0xE3, 0xE3, 0x18A }; | ||
| 87 | static const u16 SCH5627_REG_IN_HIGH_NIBBLE[SCH5627_NO_IN] = { | ||
| 88 | 1, 0, 1, 0, 1 }; | ||
| 89 | static const u16 SCH5627_REG_IN_FACTOR[SCH5627_NO_IN] = { | ||
| 90 | 10745, 3660, 9765, 10745, 3660 }; | ||
| 91 | static const char * const SCH5627_IN_LABELS[SCH5627_NO_IN] = { | ||
| 92 | "VCC", "VTT", "VBAT", "VTR", "V_IN" }; | ||
| 93 | |||
| 94 | struct sch5627_data { | ||
| 95 | unsigned short addr; | ||
| 96 | struct device *hwmon_dev; | ||
| 97 | u8 temp_max[SCH5627_NO_TEMPS]; | ||
| 98 | u8 temp_crit[SCH5627_NO_TEMPS]; | ||
| 99 | u16 fan_min[SCH5627_NO_FANS]; | ||
| 100 | |||
| 101 | struct mutex update_lock; | ||
| 102 | char valid; /* !=0 if following fields are valid */ | ||
| 103 | unsigned long last_updated; /* In jiffies */ | ||
| 104 | u16 temp[SCH5627_NO_TEMPS]; | ||
| 105 | u16 fan[SCH5627_NO_FANS]; | ||
| 106 | u16 in[SCH5627_NO_IN]; | ||
| 107 | }; | ||
| 108 | |||
| 109 | static struct platform_device *sch5627_pdev; | ||
| 110 | |||
| 111 | /* Super I/O functions */ | ||
| 112 | static inline int superio_inb(int base, int reg) | ||
| 113 | { | ||
| 114 | outb(reg, base); | ||
| 115 | return inb(base + 1); | ||
| 116 | } | ||
| 117 | |||
| 118 | static inline int superio_enter(int base) | ||
| 119 | { | ||
| 120 | /* Don't step on other drivers' I/O space by accident */ | ||
| 121 | if (!request_muxed_region(base, 2, DRVNAME)) { | ||
| 122 | pr_err("I/O address 0x%04x already in use\n", base); | ||
| 123 | return -EBUSY; | ||
| 124 | } | ||
| 125 | |||
| 126 | outb(SIO_UNLOCK_KEY, base); | ||
| 127 | |||
| 128 | return 0; | ||
| 129 | } | ||
| 130 | |||
| 131 | static inline void superio_select(int base, int ld) | ||
| 132 | { | ||
| 133 | outb(SIO_REG_LDSEL, base); | ||
| 134 | outb(ld, base + 1); | ||
| 135 | } | ||
| 136 | |||
| 137 | static inline void superio_exit(int base) | ||
| 138 | { | ||
| 139 | outb(SIO_LOCK_KEY, base); | ||
| 140 | release_region(base, 2); | ||
| 141 | } | ||
| 142 | |||
| 143 | static int sch5627_read_virtual_reg(struct sch5627_data *data, u16 reg) | ||
| 144 | { | ||
| 145 | u8 val; | ||
| 146 | int i; | ||
| 147 | /* | ||
| 148 | * According to SMSC for the commands we use the maximum time for | ||
| 149 | * the EM to respond is 15 ms, but testing shows in practice it | ||
| 150 | * responds within 15-32 reads, so we first busy poll, and if | ||
| 151 | * that fails sleep a bit and try again until we are way past | ||
| 152 | * the 15 ms maximum response time. | ||
| 153 | */ | ||
| 154 | const int max_busy_polls = 64; | ||
| 155 | const int max_lazy_polls = 32; | ||
| 156 | |||
| 157 | /* (Optional) Write-Clear the EC to Host Mailbox Register */ | ||
| 158 | val = inb(data->addr + 1); | ||
| 159 | outb(val, data->addr + 1); | ||
| 160 | |||
| 161 | /* Set Mailbox Address Pointer to first location in Region 1 */ | ||
| 162 | outb(0x00, data->addr + 2); | ||
| 163 | outb(0x80, data->addr + 3); | ||
| 164 | |||
| 165 | /* Write Request Packet Header */ | ||
| 166 | outb(0x02, data->addr + 4); /* Access Type: VREG read */ | ||
| 167 | outb(0x01, data->addr + 5); /* # of Entries: 1 Byte (8-bit) */ | ||
| 168 | outb(0x04, data->addr + 2); /* Mailbox AP to first data entry loc. */ | ||
| 169 | |||
| 170 | /* Write Address field */ | ||
| 171 | outb(reg & 0xff, data->addr + 6); | ||
| 172 | outb(reg >> 8, data->addr + 7); | ||
| 173 | |||
| 174 | /* Execute the Random Access Command */ | ||
| 175 | outb(0x01, data->addr); /* Write 01h to the Host-to-EC register */ | ||
| 176 | |||
| 177 | /* EM Interface Polling "Algorithm" */ | ||
| 178 | for (i = 0; i < max_busy_polls + max_lazy_polls; i++) { | ||
| 179 | if (i >= max_busy_polls) | ||
| 180 | msleep(1); | ||
| 181 | /* Read Interrupt source Register */ | ||
| 182 | val = inb(data->addr + 8); | ||
| 183 | /* Write Clear the interrupt source bits */ | ||
| 184 | if (val) | ||
| 185 | outb(val, data->addr + 8); | ||
| 186 | /* Command Completed ? */ | ||
| 187 | if (val & 0x01) | ||
| 188 | break; | ||
| 189 | } | ||
| 190 | if (i == max_busy_polls + max_lazy_polls) { | ||
| 191 | pr_err("Max retries exceeded reading virtual " | ||
| 192 | "register 0x%04hx (%d)\n", reg, 1); | ||
| 193 | return -EIO; | ||
| 194 | } | ||
| 195 | |||
| 196 | /* | ||
| 197 | * According to SMSC we may need to retry this, but sofar I've always | ||
| 198 | * seen this succeed in 1 try. | ||
| 199 | */ | ||
| 200 | for (i = 0; i < max_busy_polls; i++) { | ||
| 201 | /* Read EC-to-Host Register */ | ||
| 202 | val = inb(data->addr + 1); | ||
| 203 | /* Command Completed ? */ | ||
| 204 | if (val == 0x01) | ||
| 205 | break; | ||
| 206 | |||
| 207 | if (i == 0) | ||
| 208 | pr_warn("EC reports: 0x%02x reading virtual register " | ||
| 209 | "0x%04hx\n", (unsigned int)val, reg); | ||
| 210 | } | ||
| 211 | if (i == max_busy_polls) { | ||
| 212 | pr_err("Max retries exceeded reading virtual " | ||
| 213 | "register 0x%04hx (%d)\n", reg, 2); | ||
| 214 | return -EIO; | ||
| 215 | } | ||
| 216 | |||
| 217 | /* | ||
| 218 | * According to the SMSC app note we should now do: | ||
| 219 | * | ||
| 220 | * Set Mailbox Address Pointer to first location in Region 1 * | ||
| 221 | * outb(0x00, data->addr + 2); | ||
| 222 | * outb(0x80, data->addr + 3); | ||
| 223 | * | ||
| 224 | * But if we do that things don't work, so let's not. | ||
| 225 | */ | ||
| 226 | |||
| 227 | /* Read Data from Mailbox */ | ||
| 228 | return inb(data->addr + 4); | ||
| 229 | } | ||
| 230 | |||
| 231 | static int sch5627_read_virtual_reg16(struct sch5627_data *data, u16 reg) | ||
| 232 | { | ||
| 233 | int lsb, msb; | ||
| 234 | |||
| 235 | /* Read LSB first, this will cause the matching MSB to be latched */ | ||
| 236 | lsb = sch5627_read_virtual_reg(data, reg); | ||
| 237 | if (lsb < 0) | ||
| 238 | return lsb; | ||
| 239 | |||
| 240 | msb = sch5627_read_virtual_reg(data, reg + 1); | ||
| 241 | if (msb < 0) | ||
| 242 | return msb; | ||
| 243 | |||
| 244 | return lsb | (msb << 8); | ||
| 245 | } | ||
| 246 | |||
| 247 | static int sch5627_read_virtual_reg12(struct sch5627_data *data, u16 msb_reg, | ||
| 248 | u16 lsn_reg, int high_nibble) | ||
| 249 | { | ||
| 250 | int msb, lsn; | ||
| 251 | |||
| 252 | /* Read MSB first, this will cause the matching LSN to be latched */ | ||
| 253 | msb = sch5627_read_virtual_reg(data, msb_reg); | ||
| 254 | if (msb < 0) | ||
| 255 | return msb; | ||
| 256 | |||
| 257 | lsn = sch5627_read_virtual_reg(data, lsn_reg); | ||
| 258 | if (lsn < 0) | ||
| 259 | return lsn; | ||
| 260 | |||
| 261 | if (high_nibble) | ||
| 262 | return (msb << 4) | (lsn >> 4); | ||
| 263 | else | ||
| 264 | return (msb << 4) | (lsn & 0x0f); | ||
| 265 | } | ||
| 266 | |||
| 267 | static struct sch5627_data *sch5627_update_device(struct device *dev) | ||
| 268 | { | ||
| 269 | struct sch5627_data *data = dev_get_drvdata(dev); | ||
| 270 | struct sch5627_data *ret = data; | ||
| 271 | int i, val; | ||
| 272 | |||
| 273 | mutex_lock(&data->update_lock); | ||
| 274 | |||
| 275 | /* Cache the values for 1 second */ | ||
| 276 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | ||
| 277 | for (i = 0; i < SCH5627_NO_TEMPS; i++) { | ||
| 278 | val = sch5627_read_virtual_reg12(data, | ||
| 279 | SCH5627_REG_TEMP_MSB[i], | ||
| 280 | SCH5627_REG_TEMP_LSN[i], | ||
| 281 | SCH5627_REG_TEMP_HIGH_NIBBLE[i]); | ||
| 282 | if (unlikely(val < 0)) { | ||
| 283 | ret = ERR_PTR(val); | ||
| 284 | goto abort; | ||
| 285 | } | ||
| 286 | data->temp[i] = val; | ||
| 287 | } | ||
| 288 | |||
| 289 | for (i = 0; i < SCH5627_NO_FANS; i++) { | ||
| 290 | val = sch5627_read_virtual_reg16(data, | ||
| 291 | SCH5627_REG_FAN[i]); | ||
| 292 | if (unlikely(val < 0)) { | ||
| 293 | ret = ERR_PTR(val); | ||
| 294 | goto abort; | ||
| 295 | } | ||
| 296 | data->fan[i] = val; | ||
| 297 | } | ||
| 298 | |||
| 299 | for (i = 0; i < SCH5627_NO_IN; i++) { | ||
| 300 | val = sch5627_read_virtual_reg12(data, | ||
| 301 | SCH5627_REG_IN_MSB[i], | ||
| 302 | SCH5627_REG_IN_LSN[i], | ||
| 303 | SCH5627_REG_IN_HIGH_NIBBLE[i]); | ||
| 304 | if (unlikely(val < 0)) { | ||
| 305 | ret = ERR_PTR(val); | ||
| 306 | goto abort; | ||
| 307 | } | ||
| 308 | data->in[i] = val; | ||
| 309 | } | ||
| 310 | |||
| 311 | data->last_updated = jiffies; | ||
| 312 | data->valid = 1; | ||
| 313 | } | ||
| 314 | abort: | ||
| 315 | mutex_unlock(&data->update_lock); | ||
| 316 | return ret; | ||
| 317 | } | ||
| 318 | |||
| 319 | static int __devinit sch5627_read_limits(struct sch5627_data *data) | ||
| 320 | { | ||
| 321 | int i, val; | ||
| 322 | |||
| 323 | for (i = 0; i < SCH5627_NO_TEMPS; i++) { | ||
| 324 | /* | ||
| 325 | * Note what SMSC calls ABS, is what lm_sensors calls max | ||
| 326 | * (aka high), and HIGH is what lm_sensors calls crit. | ||
| 327 | */ | ||
| 328 | val = sch5627_read_virtual_reg(data, SCH5627_REG_TEMP_ABS[i]); | ||
| 329 | if (val < 0) | ||
| 330 | return val; | ||
| 331 | data->temp_max[i] = val; | ||
| 332 | |||
| 333 | val = sch5627_read_virtual_reg(data, SCH5627_REG_TEMP_HIGH[i]); | ||
| 334 | if (val < 0) | ||
| 335 | return val; | ||
| 336 | data->temp_crit[i] = val; | ||
| 337 | } | ||
| 338 | for (i = 0; i < SCH5627_NO_FANS; i++) { | ||
| 339 | val = sch5627_read_virtual_reg16(data, SCH5627_REG_FAN_MIN[i]); | ||
| 340 | if (val < 0) | ||
| 341 | return val; | ||
| 342 | data->fan_min[i] = val; | ||
| 343 | } | ||
| 344 | |||
| 345 | return 0; | ||
| 346 | } | ||
| 347 | |||
| 348 | static int reg_to_temp(u16 reg) | ||
| 349 | { | ||
| 350 | return (reg * 625) / 10 - 64000; | ||
| 351 | } | ||
| 352 | |||
| 353 | static int reg_to_temp_limit(u8 reg) | ||
| 354 | { | ||
| 355 | return (reg - 64) * 1000; | ||
| 356 | } | ||
| 357 | |||
| 358 | static int reg_to_rpm(u16 reg) | ||
| 359 | { | ||
| 360 | if (reg == 0) | ||
| 361 | return -EIO; | ||
| 362 | if (reg == 0xffff) | ||
| 363 | return 0; | ||
| 364 | |||
| 365 | return 5400540 / reg; | ||
| 366 | } | ||
| 367 | |||
| 368 | static ssize_t show_name(struct device *dev, struct device_attribute *devattr, | ||
| 369 | char *buf) | ||
| 370 | { | ||
| 371 | return snprintf(buf, PAGE_SIZE, "%s\n", DEVNAME); | ||
| 372 | } | ||
| 373 | |||
| 374 | static ssize_t show_temp(struct device *dev, struct device_attribute | ||
| 375 | *devattr, char *buf) | ||
| 376 | { | ||
| 377 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 378 | struct sch5627_data *data = sch5627_update_device(dev); | ||
| 379 | int val; | ||
| 380 | |||
| 381 | if (IS_ERR(data)) | ||
| 382 | return PTR_ERR(data); | ||
| 383 | |||
| 384 | val = reg_to_temp(data->temp[attr->index]); | ||
| 385 | return snprintf(buf, PAGE_SIZE, "%d\n", val); | ||
| 386 | } | ||
| 387 | |||
| 388 | static ssize_t show_temp_fault(struct device *dev, struct device_attribute | ||
| 389 | *devattr, char *buf) | ||
| 390 | { | ||
| 391 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 392 | struct sch5627_data *data = sch5627_update_device(dev); | ||
| 393 | |||
| 394 | if (IS_ERR(data)) | ||
| 395 | return PTR_ERR(data); | ||
| 396 | |||
| 397 | return snprintf(buf, PAGE_SIZE, "%d\n", data->temp[attr->index] == 0); | ||
| 398 | } | ||
| 399 | |||
| 400 | static ssize_t show_temp_max(struct device *dev, struct device_attribute | ||
| 401 | *devattr, char *buf) | ||
| 402 | { | ||
| 403 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 404 | struct sch5627_data *data = dev_get_drvdata(dev); | ||
| 405 | int val; | ||
| 406 | |||
| 407 | val = reg_to_temp_limit(data->temp_max[attr->index]); | ||
| 408 | return snprintf(buf, PAGE_SIZE, "%d\n", val); | ||
| 409 | } | ||
| 410 | |||
| 411 | static ssize_t show_temp_crit(struct device *dev, struct device_attribute | ||
| 412 | *devattr, char *buf) | ||
| 413 | { | ||
| 414 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 415 | struct sch5627_data *data = dev_get_drvdata(dev); | ||
| 416 | int val; | ||
| 417 | |||
| 418 | val = reg_to_temp_limit(data->temp_crit[attr->index]); | ||
| 419 | return snprintf(buf, PAGE_SIZE, "%d\n", val); | ||
| 420 | } | ||
| 421 | |||
| 422 | static ssize_t show_fan(struct device *dev, struct device_attribute | ||
| 423 | *devattr, char *buf) | ||
| 424 | { | ||
| 425 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 426 | struct sch5627_data *data = sch5627_update_device(dev); | ||
| 427 | int val; | ||
| 428 | |||
| 429 | if (IS_ERR(data)) | ||
| 430 | return PTR_ERR(data); | ||
| 431 | |||
| 432 | val = reg_to_rpm(data->fan[attr->index]); | ||
| 433 | if (val < 0) | ||
| 434 | return val; | ||
| 435 | |||
| 436 | return snprintf(buf, PAGE_SIZE, "%d\n", val); | ||
| 437 | } | ||
| 438 | |||
| 439 | static ssize_t show_fan_fault(struct device *dev, struct device_attribute | ||
| 440 | *devattr, char *buf) | ||
| 441 | { | ||
| 442 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 443 | struct sch5627_data *data = sch5627_update_device(dev); | ||
| 444 | |||
| 445 | if (IS_ERR(data)) | ||
| 446 | return PTR_ERR(data); | ||
| 447 | |||
| 448 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
| 449 | data->fan[attr->index] == 0xffff); | ||
| 450 | } | ||
| 451 | |||
| 452 | static ssize_t show_fan_min(struct device *dev, struct device_attribute | ||
| 453 | *devattr, char *buf) | ||
| 454 | { | ||
| 455 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 456 | struct sch5627_data *data = dev_get_drvdata(dev); | ||
| 457 | int val = reg_to_rpm(data->fan_min[attr->index]); | ||
| 458 | if (val < 0) | ||
| 459 | return val; | ||
| 460 | |||
| 461 | return snprintf(buf, PAGE_SIZE, "%d\n", val); | ||
| 462 | } | ||
| 463 | |||
| 464 | static ssize_t show_in(struct device *dev, struct device_attribute | ||
| 465 | *devattr, char *buf) | ||
| 466 | { | ||
| 467 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 468 | struct sch5627_data *data = sch5627_update_device(dev); | ||
| 469 | int val; | ||
| 470 | |||
| 471 | if (IS_ERR(data)) | ||
| 472 | return PTR_ERR(data); | ||
| 473 | |||
| 474 | val = DIV_ROUND_CLOSEST( | ||
| 475 | data->in[attr->index] * SCH5627_REG_IN_FACTOR[attr->index], | ||
| 476 | 10000); | ||
| 477 | return snprintf(buf, PAGE_SIZE, "%d\n", val); | ||
| 478 | } | ||
| 479 | |||
| 480 | static ssize_t show_in_label(struct device *dev, struct device_attribute | ||
| 481 | *devattr, char *buf) | ||
| 482 | { | ||
| 483 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 484 | |||
| 485 | return snprintf(buf, PAGE_SIZE, "%s\n", | ||
| 486 | SCH5627_IN_LABELS[attr->index]); | ||
| 487 | } | ||
| 488 | |||
| 489 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
| 490 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); | ||
| 491 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); | ||
| 492 | static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); | ||
| 493 | static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3); | ||
| 494 | static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, show_temp, NULL, 4); | ||
| 495 | static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, show_temp, NULL, 5); | ||
| 496 | static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, show_temp, NULL, 6); | ||
| 497 | static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, show_temp, NULL, 7); | ||
| 498 | static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0); | ||
| 499 | static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_temp_fault, NULL, 1); | ||
| 500 | static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_temp_fault, NULL, 2); | ||
| 501 | static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_temp_fault, NULL, 3); | ||
| 502 | static SENSOR_DEVICE_ATTR(temp5_fault, S_IRUGO, show_temp_fault, NULL, 4); | ||
| 503 | static SENSOR_DEVICE_ATTR(temp6_fault, S_IRUGO, show_temp_fault, NULL, 5); | ||
| 504 | static SENSOR_DEVICE_ATTR(temp7_fault, S_IRUGO, show_temp_fault, NULL, 6); | ||
| 505 | static SENSOR_DEVICE_ATTR(temp8_fault, S_IRUGO, show_temp_fault, NULL, 7); | ||
| 506 | static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_max, NULL, 0); | ||
| 507 | static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO, show_temp_max, NULL, 1); | ||
| 508 | static SENSOR_DEVICE_ATTR(temp3_max, S_IRUGO, show_temp_max, NULL, 2); | ||
| 509 | static SENSOR_DEVICE_ATTR(temp4_max, S_IRUGO, show_temp_max, NULL, 3); | ||
| 510 | static SENSOR_DEVICE_ATTR(temp5_max, S_IRUGO, show_temp_max, NULL, 4); | ||
| 511 | static SENSOR_DEVICE_ATTR(temp6_max, S_IRUGO, show_temp_max, NULL, 5); | ||
| 512 | static SENSOR_DEVICE_ATTR(temp7_max, S_IRUGO, show_temp_max, NULL, 6); | ||
| 513 | static SENSOR_DEVICE_ATTR(temp8_max, S_IRUGO, show_temp_max, NULL, 7); | ||
| 514 | static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp_crit, NULL, 0); | ||
| 515 | static SENSOR_DEVICE_ATTR(temp2_crit, S_IRUGO, show_temp_crit, NULL, 1); | ||
| 516 | static SENSOR_DEVICE_ATTR(temp3_crit, S_IRUGO, show_temp_crit, NULL, 2); | ||
| 517 | static SENSOR_DEVICE_ATTR(temp4_crit, S_IRUGO, show_temp_crit, NULL, 3); | ||
| 518 | static SENSOR_DEVICE_ATTR(temp5_crit, S_IRUGO, show_temp_crit, NULL, 4); | ||
| 519 | static SENSOR_DEVICE_ATTR(temp6_crit, S_IRUGO, show_temp_crit, NULL, 5); | ||
| 520 | static SENSOR_DEVICE_ATTR(temp7_crit, S_IRUGO, show_temp_crit, NULL, 6); | ||
| 521 | static SENSOR_DEVICE_ATTR(temp8_crit, S_IRUGO, show_temp_crit, NULL, 7); | ||
| 522 | |||
| 523 | static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); | ||
| 524 | static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); | ||
| 525 | static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); | ||
| 526 | static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3); | ||
| 527 | static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, show_fan_fault, NULL, 0); | ||
| 528 | static SENSOR_DEVICE_ATTR(fan2_fault, S_IRUGO, show_fan_fault, NULL, 1); | ||
| 529 | static SENSOR_DEVICE_ATTR(fan3_fault, S_IRUGO, show_fan_fault, NULL, 2); | ||
| 530 | static SENSOR_DEVICE_ATTR(fan4_fault, S_IRUGO, show_fan_fault, NULL, 3); | ||
| 531 | static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO, show_fan_min, NULL, 0); | ||
| 532 | static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO, show_fan_min, NULL, 1); | ||
| 533 | static SENSOR_DEVICE_ATTR(fan3_min, S_IRUGO, show_fan_min, NULL, 2); | ||
| 534 | static SENSOR_DEVICE_ATTR(fan4_min, S_IRUGO, show_fan_min, NULL, 3); | ||
| 535 | |||
| 536 | static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_in, NULL, 0); | ||
| 537 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_in, NULL, 1); | ||
| 538 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_in, NULL, 2); | ||
| 539 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_in, NULL, 3); | ||
| 540 | static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_in, NULL, 4); | ||
| 541 | static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, show_in_label, NULL, 0); | ||
| 542 | static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, show_in_label, NULL, 1); | ||
| 543 | static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, show_in_label, NULL, 2); | ||
| 544 | static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_in_label, NULL, 3); | ||
| 545 | |||
| 546 | static struct attribute *sch5627_attributes[] = { | ||
| 547 | &dev_attr_name.attr, | ||
| 548 | |||
| 549 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
| 550 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
| 551 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
| 552 | &sensor_dev_attr_temp4_input.dev_attr.attr, | ||
| 553 | &sensor_dev_attr_temp5_input.dev_attr.attr, | ||
| 554 | &sensor_dev_attr_temp6_input.dev_attr.attr, | ||
| 555 | &sensor_dev_attr_temp7_input.dev_attr.attr, | ||
| 556 | &sensor_dev_attr_temp8_input.dev_attr.attr, | ||
| 557 | &sensor_dev_attr_temp1_fault.dev_attr.attr, | ||
| 558 | &sensor_dev_attr_temp2_fault.dev_attr.attr, | ||
| 559 | &sensor_dev_attr_temp3_fault.dev_attr.attr, | ||
| 560 | &sensor_dev_attr_temp4_fault.dev_attr.attr, | ||
| 561 | &sensor_dev_attr_temp5_fault.dev_attr.attr, | ||
| 562 | &sensor_dev_attr_temp6_fault.dev_attr.attr, | ||
| 563 | &sensor_dev_attr_temp7_fault.dev_attr.attr, | ||
| 564 | &sensor_dev_attr_temp8_fault.dev_attr.attr, | ||
| 565 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
| 566 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
| 567 | &sensor_dev_attr_temp3_max.dev_attr.attr, | ||
| 568 | &sensor_dev_attr_temp4_max.dev_attr.attr, | ||
| 569 | &sensor_dev_attr_temp5_max.dev_attr.attr, | ||
| 570 | &sensor_dev_attr_temp6_max.dev_attr.attr, | ||
| 571 | &sensor_dev_attr_temp7_max.dev_attr.attr, | ||
| 572 | &sensor_dev_attr_temp8_max.dev_attr.attr, | ||
| 573 | &sensor_dev_attr_temp1_crit.dev_attr.attr, | ||
| 574 | &sensor_dev_attr_temp2_crit.dev_attr.attr, | ||
| 575 | &sensor_dev_attr_temp3_crit.dev_attr.attr, | ||
| 576 | &sensor_dev_attr_temp4_crit.dev_attr.attr, | ||
| 577 | &sensor_dev_attr_temp5_crit.dev_attr.attr, | ||
| 578 | &sensor_dev_attr_temp6_crit.dev_attr.attr, | ||
| 579 | &sensor_dev_attr_temp7_crit.dev_attr.attr, | ||
| 580 | &sensor_dev_attr_temp8_crit.dev_attr.attr, | ||
| 581 | |||
| 582 | &sensor_dev_attr_fan1_input.dev_attr.attr, | ||
| 583 | &sensor_dev_attr_fan2_input.dev_attr.attr, | ||
| 584 | &sensor_dev_attr_fan3_input.dev_attr.attr, | ||
| 585 | &sensor_dev_attr_fan4_input.dev_attr.attr, | ||
| 586 | &sensor_dev_attr_fan1_fault.dev_attr.attr, | ||
| 587 | &sensor_dev_attr_fan2_fault.dev_attr.attr, | ||
| 588 | &sensor_dev_attr_fan3_fault.dev_attr.attr, | ||
| 589 | &sensor_dev_attr_fan4_fault.dev_attr.attr, | ||
| 590 | &sensor_dev_attr_fan1_min.dev_attr.attr, | ||
| 591 | &sensor_dev_attr_fan2_min.dev_attr.attr, | ||
| 592 | &sensor_dev_attr_fan3_min.dev_attr.attr, | ||
| 593 | &sensor_dev_attr_fan4_min.dev_attr.attr, | ||
| 594 | |||
| 595 | &sensor_dev_attr_in0_input.dev_attr.attr, | ||
| 596 | &sensor_dev_attr_in1_input.dev_attr.attr, | ||
| 597 | &sensor_dev_attr_in2_input.dev_attr.attr, | ||
| 598 | &sensor_dev_attr_in3_input.dev_attr.attr, | ||
| 599 | &sensor_dev_attr_in4_input.dev_attr.attr, | ||
| 600 | &sensor_dev_attr_in0_label.dev_attr.attr, | ||
| 601 | &sensor_dev_attr_in1_label.dev_attr.attr, | ||
| 602 | &sensor_dev_attr_in2_label.dev_attr.attr, | ||
| 603 | &sensor_dev_attr_in3_label.dev_attr.attr, | ||
| 604 | /* No in4_label as in4 is a generic input pin */ | ||
| 605 | |||
| 606 | NULL | ||
| 607 | }; | ||
| 608 | |||
| 609 | static const struct attribute_group sch5627_group = { | ||
| 610 | .attrs = sch5627_attributes, | ||
| 611 | }; | ||
| 612 | |||
| 613 | static int sch5627_remove(struct platform_device *pdev) | ||
| 614 | { | ||
| 615 | struct sch5627_data *data = platform_get_drvdata(pdev); | ||
| 616 | |||
| 617 | if (data->hwmon_dev) | ||
| 618 | hwmon_device_unregister(data->hwmon_dev); | ||
| 619 | |||
| 620 | sysfs_remove_group(&pdev->dev.kobj, &sch5627_group); | ||
| 621 | platform_set_drvdata(pdev, NULL); | ||
| 622 | kfree(data); | ||
| 623 | |||
| 624 | return 0; | ||
| 625 | } | ||
| 626 | |||
| 627 | static int __devinit sch5627_probe(struct platform_device *pdev) | ||
| 628 | { | ||
| 629 | struct sch5627_data *data; | ||
| 630 | int err, build_code, build_id, hwmon_rev, val; | ||
| 631 | |||
| 632 | data = kzalloc(sizeof(struct sch5627_data), GFP_KERNEL); | ||
| 633 | if (!data) | ||
| 634 | return -ENOMEM; | ||
| 635 | |||
| 636 | data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; | ||
| 637 | mutex_init(&data->update_lock); | ||
| 638 | platform_set_drvdata(pdev, data); | ||
| 639 | |||
| 640 | val = sch5627_read_virtual_reg(data, SCH5627_REG_HWMON_ID); | ||
| 641 | if (val < 0) { | ||
| 642 | err = val; | ||
| 643 | goto error; | ||
| 644 | } | ||
| 645 | if (val != SCH5627_HWMON_ID) { | ||
| 646 | pr_err("invalid %s id: 0x%02X (expected 0x%02X)\n", "hwmon", | ||
| 647 | val, SCH5627_HWMON_ID); | ||
| 648 | err = -ENODEV; | ||
| 649 | goto error; | ||
| 650 | } | ||
| 651 | |||
| 652 | val = sch5627_read_virtual_reg(data, SCH5627_REG_COMPANY_ID); | ||
| 653 | if (val < 0) { | ||
| 654 | err = val; | ||
| 655 | goto error; | ||
| 656 | } | ||
| 657 | if (val != SCH5627_COMPANY_ID) { | ||
| 658 | pr_err("invalid %s id: 0x%02X (expected 0x%02X)\n", "company", | ||
| 659 | val, SCH5627_COMPANY_ID); | ||
| 660 | err = -ENODEV; | ||
| 661 | goto error; | ||
| 662 | } | ||
| 663 | |||
| 664 | val = sch5627_read_virtual_reg(data, SCH5627_REG_PRIMARY_ID); | ||
| 665 | if (val < 0) { | ||
| 666 | err = val; | ||
| 667 | goto error; | ||
| 668 | } | ||
| 669 | if (val != SCH5627_PRIMARY_ID) { | ||
| 670 | pr_err("invalid %s id: 0x%02X (expected 0x%02X)\n", "primary", | ||
| 671 | val, SCH5627_PRIMARY_ID); | ||
| 672 | err = -ENODEV; | ||
| 673 | goto error; | ||
| 674 | } | ||
| 675 | |||
| 676 | build_code = sch5627_read_virtual_reg(data, SCH5627_REG_BUILD_CODE); | ||
| 677 | if (build_code < 0) { | ||
| 678 | err = build_code; | ||
| 679 | goto error; | ||
| 680 | } | ||
| 681 | |||
| 682 | build_id = sch5627_read_virtual_reg16(data, SCH5627_REG_BUILD_ID); | ||
| 683 | if (build_id < 0) { | ||
| 684 | err = build_id; | ||
| 685 | goto error; | ||
| 686 | } | ||
| 687 | |||
| 688 | hwmon_rev = sch5627_read_virtual_reg(data, SCH5627_REG_HWMON_REV); | ||
| 689 | if (hwmon_rev < 0) { | ||
| 690 | err = hwmon_rev; | ||
| 691 | goto error; | ||
| 692 | } | ||
| 693 | |||
| 694 | val = sch5627_read_virtual_reg(data, SCH5627_REG_CTRL); | ||
| 695 | if (val < 0) { | ||
| 696 | err = val; | ||
| 697 | goto error; | ||
| 698 | } | ||
| 699 | if (!(val & 0x01)) { | ||
| 700 | pr_err("hardware monitoring not enabled\n"); | ||
| 701 | err = -ENODEV; | ||
| 702 | goto error; | ||
| 703 | } | ||
| 704 | |||
| 705 | /* | ||
| 706 | * Read limits, we do this only once as reading a register on | ||
| 707 | * the sch5627 is quite expensive (and they don't change). | ||
| 708 | */ | ||
| 709 | err = sch5627_read_limits(data); | ||
| 710 | if (err) | ||
| 711 | goto error; | ||
| 712 | |||
| 713 | pr_info("firmware build: code 0x%02X, id 0x%04X, hwmon: rev 0x%02X\n", | ||
| 714 | build_code, build_id, hwmon_rev); | ||
| 715 | |||
| 716 | /* Register sysfs interface files */ | ||
| 717 | err = sysfs_create_group(&pdev->dev.kobj, &sch5627_group); | ||
| 718 | if (err) | ||
| 719 | goto error; | ||
| 720 | |||
| 721 | data->hwmon_dev = hwmon_device_register(&pdev->dev); | ||
| 722 | if (IS_ERR(data->hwmon_dev)) { | ||
| 723 | err = PTR_ERR(data->hwmon_dev); | ||
| 724 | data->hwmon_dev = NULL; | ||
| 725 | goto error; | ||
| 726 | } | ||
| 727 | |||
| 728 | return 0; | ||
| 729 | |||
| 730 | error: | ||
| 731 | sch5627_remove(pdev); | ||
| 732 | return err; | ||
| 733 | } | ||
| 734 | |||
| 735 | static int __init sch5627_find(int sioaddr, unsigned short *address) | ||
| 736 | { | ||
| 737 | u8 devid; | ||
| 738 | int err = superio_enter(sioaddr); | ||
| 739 | if (err) | ||
| 740 | return err; | ||
| 741 | |||
| 742 | devid = superio_inb(sioaddr, SIO_REG_DEVID); | ||
| 743 | if (devid != SIO_SCH5627_ID) { | ||
| 744 | pr_debug("Unsupported device id: 0x%02x\n", | ||
| 745 | (unsigned int)devid); | ||
| 746 | err = -ENODEV; | ||
| 747 | goto exit; | ||
| 748 | } | ||
| 749 | |||
| 750 | superio_select(sioaddr, SIO_SCH5627_EM_LD); | ||
| 751 | |||
| 752 | if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { | ||
| 753 | pr_warn("Device not activated\n"); | ||
| 754 | err = -ENODEV; | ||
| 755 | goto exit; | ||
| 756 | } | ||
| 757 | |||
| 758 | /* | ||
| 759 | * Warning the order of the low / high byte is the other way around | ||
| 760 | * as on most other superio devices!! | ||
| 761 | */ | ||
| 762 | *address = superio_inb(sioaddr, SIO_REG_ADDR) | | ||
| 763 | superio_inb(sioaddr, SIO_REG_ADDR + 1) << 8; | ||
| 764 | if (*address == 0) { | ||
| 765 | pr_warn("Base address not set\n"); | ||
| 766 | err = -ENODEV; | ||
| 767 | goto exit; | ||
| 768 | } | ||
| 769 | |||
| 770 | pr_info("Found %s chip at %#hx\n", DEVNAME, *address); | ||
| 771 | exit: | ||
| 772 | superio_exit(sioaddr); | ||
| 773 | return err; | ||
| 774 | } | ||
| 775 | |||
| 776 | static int __init sch5627_device_add(unsigned short address) | ||
| 777 | { | ||
| 778 | struct resource res = { | ||
| 779 | .start = address, | ||
| 780 | .end = address + REGION_LENGTH - 1, | ||
| 781 | .flags = IORESOURCE_IO, | ||
| 782 | }; | ||
| 783 | int err; | ||
| 784 | |||
| 785 | sch5627_pdev = platform_device_alloc(DRVNAME, address); | ||
| 786 | if (!sch5627_pdev) | ||
| 787 | return -ENOMEM; | ||
| 788 | |||
| 789 | res.name = sch5627_pdev->name; | ||
| 790 | err = acpi_check_resource_conflict(&res); | ||
| 791 | if (err) | ||
| 792 | goto exit_device_put; | ||
| 793 | |||
| 794 | err = platform_device_add_resources(sch5627_pdev, &res, 1); | ||
| 795 | if (err) { | ||
| 796 | pr_err("Device resource addition failed\n"); | ||
| 797 | goto exit_device_put; | ||
| 798 | } | ||
| 799 | |||
| 800 | err = platform_device_add(sch5627_pdev); | ||
| 801 | if (err) { | ||
| 802 | pr_err("Device addition failed\n"); | ||
| 803 | goto exit_device_put; | ||
| 804 | } | ||
| 805 | |||
| 806 | return 0; | ||
| 807 | |||
| 808 | exit_device_put: | ||
| 809 | platform_device_put(sch5627_pdev); | ||
| 810 | |||
| 811 | return err; | ||
| 812 | } | ||
| 813 | |||
| 814 | static struct platform_driver sch5627_driver = { | ||
| 815 | .driver = { | ||
| 816 | .owner = THIS_MODULE, | ||
| 817 | .name = DRVNAME, | ||
| 818 | }, | ||
| 819 | .probe = sch5627_probe, | ||
| 820 | .remove = sch5627_remove, | ||
| 821 | }; | ||
| 822 | |||
| 823 | static int __init sch5627_init(void) | ||
| 824 | { | ||
| 825 | int err = -ENODEV; | ||
| 826 | unsigned short address; | ||
| 827 | |||
| 828 | if (sch5627_find(0x4e, &address) && sch5627_find(0x2e, &address)) | ||
| 829 | goto exit; | ||
| 830 | |||
| 831 | err = platform_driver_register(&sch5627_driver); | ||
| 832 | if (err) | ||
| 833 | goto exit; | ||
| 834 | |||
| 835 | err = sch5627_device_add(address); | ||
| 836 | if (err) | ||
| 837 | goto exit_driver; | ||
| 838 | |||
| 839 | return 0; | ||
| 840 | |||
| 841 | exit_driver: | ||
| 842 | platform_driver_unregister(&sch5627_driver); | ||
| 843 | exit: | ||
| 844 | return err; | ||
| 845 | } | ||
| 846 | |||
| 847 | static void __exit sch5627_exit(void) | ||
| 848 | { | ||
| 849 | platform_device_unregister(sch5627_pdev); | ||
| 850 | platform_driver_unregister(&sch5627_driver); | ||
| 851 | } | ||
| 852 | |||
| 853 | MODULE_DESCRIPTION("SMSC SCH5627 Hardware Monitoring Driver"); | ||
| 854 | MODULE_AUTHOR("Hans de Goede (hdegoede@redhat.com)"); | ||
| 855 | MODULE_LICENSE("GPL"); | ||
| 856 | |||
| 857 | module_init(sch5627_init); | ||
| 858 | module_exit(sch5627_exit); | ||
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index a610e7880fb3..1a9c32d6893a 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c | |||
| @@ -333,11 +333,11 @@ static inline int sht15_calc_humid(struct sht15_data *data) | |||
| 333 | 333 | ||
| 334 | const int c1 = -4; | 334 | const int c1 = -4; |
| 335 | const int c2 = 40500; /* x 10 ^ -6 */ | 335 | const int c2 = 40500; /* x 10 ^ -6 */ |
| 336 | const int c3 = -2800; /* x10 ^ -9 */ | 336 | const int c3 = -28; /* x 10 ^ -7 */ |
| 337 | 337 | ||
| 338 | RHlinear = c1*1000 | 338 | RHlinear = c1*1000 |
| 339 | + c2 * data->val_humid/1000 | 339 | + c2 * data->val_humid/1000 |
| 340 | + (data->val_humid * data->val_humid * c3)/1000000; | 340 | + (data->val_humid * data->val_humid * c3) / 10000; |
| 341 | return (temp - 25000) * (10000 + 80 * data->val_humid) | 341 | return (temp - 25000) * (10000 + 80 * data->val_humid) |
| 342 | / 1000000 + RHlinear; | 342 | / 1000000 + RHlinear; |
| 343 | } | 343 | } |
| @@ -610,7 +610,7 @@ static int __devexit sht15_remove(struct platform_device *pdev) | |||
| 610 | struct sht15_data *data = platform_get_drvdata(pdev); | 610 | struct sht15_data *data = platform_get_drvdata(pdev); |
| 611 | 611 | ||
| 612 | /* Make sure any reads from the device are done and | 612 | /* Make sure any reads from the device are done and |
| 613 | * prevent new ones beginnning */ | 613 | * prevent new ones from beginning */ |
| 614 | mutex_lock(&data->read_lock); | 614 | mutex_lock(&data->read_lock); |
| 615 | hwmon_device_unregister(data->hwmon_dev); | 615 | hwmon_device_unregister(data->hwmon_dev); |
| 616 | sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group); | 616 | sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group); |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b7d5ef234ac9..203500d9b848 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
| @@ -2,6 +2,14 @@ | |||
| 2 | # Misc strange devices | 2 | # Misc strange devices |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | # This one has to live outside of the MISC_DEVICES conditional, | ||
| 6 | # because it may be selected by drivers/platform/x86/hp_accel. | ||
| 7 | config SENSORS_LIS3LV02D | ||
| 8 | tristate | ||
| 9 | depends on INPUT | ||
| 10 | select INPUT_POLLDEV | ||
| 11 | default n | ||
| 12 | |||
| 5 | menuconfig MISC_DEVICES | 13 | menuconfig MISC_DEVICES |
| 6 | bool "Misc devices" | 14 | bool "Misc devices" |
| 7 | ---help--- | 15 | ---help--- |
| @@ -462,5 +470,6 @@ source "drivers/misc/eeprom/Kconfig" | |||
| 462 | source "drivers/misc/cb710/Kconfig" | 470 | source "drivers/misc/cb710/Kconfig" |
| 463 | source "drivers/misc/iwmc3200top/Kconfig" | 471 | source "drivers/misc/iwmc3200top/Kconfig" |
| 464 | source "drivers/misc/ti-st/Kconfig" | 472 | source "drivers/misc/ti-st/Kconfig" |
| 473 | source "drivers/misc/lis3lv02d/Kconfig" | ||
| 465 | 474 | ||
| 466 | endif # MISC_DEVICES | 475 | endif # MISC_DEVICES |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 98009cc20cb9..804f421bc079 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
| @@ -42,3 +42,4 @@ obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o | |||
| 42 | obj-$(CONFIG_PCH_PHUB) += pch_phub.o | 42 | obj-$(CONFIG_PCH_PHUB) += pch_phub.o |
| 43 | obj-y += ti-st/ | 43 | obj-y += ti-st/ |
| 44 | obj-$(CONFIG_AB8500_PWM) += ab8500-pwm.o | 44 | obj-$(CONFIG_AB8500_PWM) += ab8500-pwm.o |
| 45 | obj-y += lis3lv02d/ | ||
diff --git a/drivers/misc/lis3lv02d/Kconfig b/drivers/misc/lis3lv02d/Kconfig new file mode 100644 index 000000000000..8f474e6fc7b4 --- /dev/null +++ b/drivers/misc/lis3lv02d/Kconfig | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | # | ||
| 2 | # STMicroelectonics LIS3LV02D and similar accelerometers | ||
| 3 | # | ||
| 4 | |||
| 5 | config SENSORS_LIS3_SPI | ||
| 6 | tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)" | ||
| 7 | depends on !ACPI && SPI_MASTER && INPUT | ||
| 8 | select SENSORS_LIS3LV02D | ||
| 9 | default n | ||
| 10 | help | ||
| 11 | This driver provides support for the LIS3LV02Dx accelerometer connected | ||
| 12 | via SPI. The accelerometer data is readable via | ||
| 13 | /sys/devices/platform/lis3lv02d. | ||
| 14 | |||
| 15 | This driver also provides an absolute input class device, allowing | ||
| 16 | the laptop to act as a pinball machine-esque joystick. | ||
| 17 | |||
| 18 | This driver can also be built as modules. If so, the core module | ||
| 19 | will be called lis3lv02d and a specific module for the SPI transport | ||
| 20 | is called lis3lv02d_spi. | ||
| 21 | |||
| 22 | config SENSORS_LIS3_I2C | ||
| 23 | tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (I2C)" | ||
| 24 | depends on I2C && INPUT | ||
| 25 | select SENSORS_LIS3LV02D | ||
| 26 | default n | ||
| 27 | help | ||
| 28 | This driver provides support for the LIS3LV02Dx accelerometer connected | ||
| 29 | via I2C. The accelerometer data is readable via | ||
| 30 | /sys/devices/platform/lis3lv02d. | ||
| 31 | |||
| 32 | This driver also provides an absolute input class device, allowing | ||
| 33 | the device to act as a pinball machine-esque joystick. | ||
| 34 | |||
| 35 | This driver can also be built as modules. If so, the core module | ||
| 36 | will be called lis3lv02d and a specific module for the I2C transport | ||
| 37 | is called lis3lv02d_i2c. | ||
diff --git a/drivers/misc/lis3lv02d/Makefile b/drivers/misc/lis3lv02d/Makefile new file mode 100644 index 000000000000..4bf58b16fcf8 --- /dev/null +++ b/drivers/misc/lis3lv02d/Makefile | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | # | ||
| 2 | # STMicroelectonics LIS3LV02D and similar accelerometers | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o | ||
| 6 | obj-$(CONFIG_SENSORS_LIS3_SPI) += lis3lv02d_spi.o | ||
| 7 | obj-$(CONFIG_SENSORS_LIS3_I2C) += lis3lv02d_i2c.o | ||
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c index d805e8e57967..b928bc14e97b 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/misc/lis3lv02d/lis3lv02d.c | |||
| @@ -38,7 +38,7 @@ | |||
| 38 | #include <linux/uaccess.h> | 38 | #include <linux/uaccess.h> |
| 39 | #include <linux/miscdevice.h> | 39 | #include <linux/miscdevice.h> |
| 40 | #include <linux/pm_runtime.h> | 40 | #include <linux/pm_runtime.h> |
| 41 | #include <asm/atomic.h> | 41 | #include <linux/atomic.h> |
| 42 | #include "lis3lv02d.h" | 42 | #include "lis3lv02d.h" |
| 43 | 43 | ||
| 44 | #define DRIVER_NAME "lis3lv02d" | 44 | #define DRIVER_NAME "lis3lv02d" |
| @@ -88,7 +88,6 @@ | |||
| 88 | struct lis3lv02d lis3_dev = { | 88 | struct lis3lv02d lis3_dev = { |
| 89 | .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait), | 89 | .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait), |
| 90 | }; | 90 | }; |
| 91 | |||
| 92 | EXPORT_SYMBOL_GPL(lis3_dev); | 91 | EXPORT_SYMBOL_GPL(lis3_dev); |
| 93 | 92 | ||
| 94 | /* just like param_set_int() but does sanity-check so that it won't point | 93 | /* just like param_set_int() but does sanity-check so that it won't point |
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/misc/lis3lv02d/lis3lv02d.h index a1939589eb2c..a1939589eb2c 100644 --- a/drivers/hwmon/lis3lv02d.h +++ b/drivers/misc/lis3lv02d/lis3lv02d.h | |||
diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c index 8853afce85ce..b20dfb4522d2 100644 --- a/drivers/hwmon/lis3lv02d_i2c.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c | |||
| @@ -33,7 +33,7 @@ | |||
| 33 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
| 34 | #include "lis3lv02d.h" | 34 | #include "lis3lv02d.h" |
| 35 | 35 | ||
| 36 | #define DRV_NAME "lis3lv02d_i2c" | 36 | #define DRV_NAME "lis3lv02d_i2c" |
| 37 | 37 | ||
| 38 | static const char reg_vdd[] = "Vdd"; | 38 | static const char reg_vdd[] = "Vdd"; |
| 39 | static const char reg_vdd_io[] = "Vdd_IO"; | 39 | static const char reg_vdd_io[] = "Vdd_IO"; |
diff --git a/drivers/hwmon/lis3lv02d_spi.c b/drivers/misc/lis3lv02d/lis3lv02d_spi.c index c1f8a8fbf694..c1f8a8fbf694 100644 --- a/drivers/hwmon/lis3lv02d_spi.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_spi.c | |||
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index a59af5b24f0a..222dfb737b11 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
| @@ -138,6 +138,24 @@ config TC1100_WMI | |||
| 138 | This is a driver for the WMI extensions (wireless and bluetooth power | 138 | This is a driver for the WMI extensions (wireless and bluetooth power |
| 139 | control) of the HP Compaq TC1100 tablet. | 139 | control) of the HP Compaq TC1100 tablet. |
| 140 | 140 | ||
| 141 | config HP_ACCEL | ||
| 142 | tristate "HP laptop accelerometer" | ||
| 143 | depends on INPUT && ACPI | ||
| 144 | select SENSORS_LIS3LV02D | ||
| 145 | select NEW_LEDS | ||
| 146 | select LEDS_CLASS | ||
| 147 | help | ||
| 148 | This driver provides support for the "Mobile Data Protection System 3D" | ||
| 149 | or "3D DriveGuard" feature of HP laptops. On such systems the driver | ||
| 150 | should load automatically (via ACPI alias). | ||
| 151 | |||
| 152 | Support for a led indicating disk protection will be provided as | ||
| 153 | hp::hddprotect. For more information on the feature, refer to | ||
| 154 | Documentation/hwmon/lis3lv02d. | ||
| 155 | |||
| 156 | To compile this driver as a module, choose M here: the module will | ||
| 157 | be called hp_accel. | ||
| 158 | |||
| 141 | config HP_WMI | 159 | config HP_WMI |
| 142 | tristate "HP WMI extras" | 160 | tristate "HP WMI extras" |
| 143 | depends on ACPI_WMI | 161 | depends on ACPI_WMI |
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 4ec4ff8f9182..299aefb3e74c 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile | |||
| @@ -12,6 +12,7 @@ obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o | |||
| 12 | obj-$(CONFIG_DELL_WMI) += dell-wmi.o | 12 | obj-$(CONFIG_DELL_WMI) += dell-wmi.o |
| 13 | obj-$(CONFIG_ACER_WMI) += acer-wmi.o | 13 | obj-$(CONFIG_ACER_WMI) += acer-wmi.o |
| 14 | obj-$(CONFIG_ACERHDF) += acerhdf.o | 14 | obj-$(CONFIG_ACERHDF) += acerhdf.o |
| 15 | obj-$(CONFIG_HP_ACCEL) += hp_accel.o | ||
| 15 | obj-$(CONFIG_HP_WMI) += hp-wmi.o | 16 | obj-$(CONFIG_HP_WMI) += hp-wmi.o |
| 16 | obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o | 17 | obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o |
| 17 | obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o | 18 | obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o |
diff --git a/drivers/hwmon/hp_accel.c b/drivers/platform/x86/hp_accel.c index 3d21fa2b97cd..1b52d00e2f90 100644 --- a/drivers/hwmon/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c | |||
| @@ -35,11 +35,11 @@ | |||
| 35 | #include <linux/freezer.h> | 35 | #include <linux/freezer.h> |
| 36 | #include <linux/uaccess.h> | 36 | #include <linux/uaccess.h> |
| 37 | #include <linux/leds.h> | 37 | #include <linux/leds.h> |
| 38 | #include <linux/atomic.h> | ||
| 38 | #include <acpi/acpi_drivers.h> | 39 | #include <acpi/acpi_drivers.h> |
| 39 | #include <asm/atomic.h> | 40 | #include "../../misc/lis3lv02d/lis3lv02d.h" |
| 40 | #include "lis3lv02d.h" | ||
| 41 | 41 | ||
| 42 | #define DRIVER_NAME "lis3lv02d" | 42 | #define DRIVER_NAME "hp_accel" |
| 43 | #define ACPI_MDPS_CLASS "accelerometer" | 43 | #define ACPI_MDPS_CLASS "accelerometer" |
| 44 | 44 | ||
| 45 | /* Delayed LEDs infrastructure ------------------------------------ */ | 45 | /* Delayed LEDs infrastructure ------------------------------------ */ |
| @@ -402,4 +402,3 @@ MODULE_LICENSE("GPL"); | |||
| 402 | 402 | ||
| 403 | module_init(lis3lv02d_init_module); | 403 | module_init(lis3lv02d_init_module); |
| 404 | module_exit(lis3lv02d_exit_module); | 404 | module_exit(lis3lv02d_exit_module); |
| 405 | |||
diff --git a/include/linux/i2c/ads1015.h b/include/linux/i2c/ads1015.h new file mode 100644 index 000000000000..d5aa2a045669 --- /dev/null +++ b/include/linux/i2c/ads1015.h | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | /* | ||
| 2 | * Platform Data for ADS1015 12-bit 4-input ADC | ||
| 3 | * (C) Copyright 2010 | ||
| 4 | * Dirk Eibach, Guntermann & Drunck GmbH <eibach@gdsys.de> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #ifndef LINUX_ADS1015_H | ||
| 22 | #define LINUX_ADS1015_H | ||
| 23 | |||
| 24 | #define ADS1015_CHANNELS 8 | ||
| 25 | |||
| 26 | struct ads1015_channel_data { | ||
| 27 | bool enabled; | ||
| 28 | unsigned int pga; | ||
| 29 | unsigned int data_rate; | ||
| 30 | }; | ||
| 31 | |||
| 32 | struct ads1015_platform_data { | ||
| 33 | struct ads1015_channel_data channel_data[ADS1015_CHANNELS]; | ||
| 34 | }; | ||
| 35 | |||
| 36 | #endif /* LINUX_ADS1015_H */ | ||
