aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/hwmon/ltc426163
-rw-r--r--MAINTAINERS7
-rw-r--r--arch/arm/mach-kirkwood/netspace_v2-setup.c43
-rw-r--r--drivers/hwmon/Kconfig20
-rw-r--r--drivers/hwmon/Makefile2
-rw-r--r--drivers/hwmon/coretemp.c28
-rw-r--r--drivers/hwmon/gpio-fan.c558
-rw-r--r--drivers/hwmon/hp_accel.c32
-rw-r--r--drivers/hwmon/lis3lv02d.c364
-rw-r--r--drivers/hwmon/lis3lv02d.h47
-rw-r--r--drivers/hwmon/lis3lv02d_i2c.c132
-rw-r--r--drivers/hwmon/lis3lv02d_spi.c5
-rw-r--r--drivers/hwmon/ltc4261.c315
-rw-r--r--drivers/hwmon/pkgtemp.c32
-rw-r--r--drivers/hwmon/via-cputemp.c11
-rw-r--r--include/linux/gpio-fan.h36
-rw-r--r--include/linux/lis3lv02d.h55
17 files changed, 1619 insertions, 131 deletions
diff --git a/Documentation/hwmon/ltc4261 b/Documentation/hwmon/ltc4261
new file mode 100644
index 000000000000..eba2e2c4b94d
--- /dev/null
+++ b/Documentation/hwmon/ltc4261
@@ -0,0 +1,63 @@
1Kernel driver ltc4261
2=====================
3
4Supported chips:
5 * Linear Technology LTC4261
6 Prefix: 'ltc4261'
7 Addresses scanned: -
8 Datasheet:
9 http://cds.linear.com/docs/Datasheet/42612fb.pdf
10
11Author: Guenter Roeck <guenter.roeck@ericsson.com>
12
13
14Description
15-----------
16
17The LTC4261/LTC4261-2 negative voltage Hot Swap controllers allow a board
18to be safely inserted and removed from a live backplane.
19
20
21Usage Notes
22-----------
23
24This driver does not probe for LTC4261 devices, since there is no register
25which can be safely used to identify the chip. You will have to instantiate
26the devices explicitly.
27
28Example: the following will load the driver for an LTC4261 at address 0x10
29on I2C bus #1:
30$ modprobe ltc4261
31$ echo ltc4261 0x10 > /sys/bus/i2c/devices/i2c-1/new_device
32
33
34Sysfs entries
35-------------
36
37Voltage readings provided by this driver are reported as obtained from the ADC
38registers. If a set of voltage divider resistors is installed, calculate the
39real voltage by multiplying the reported value with (R1+R2)/R2, where R1 is the
40value of the divider resistor against the measured voltage and R2 is the value
41of the divider resistor against Ground.
42
43Current reading provided by this driver is reported as obtained from the ADC
44Current Sense register. The reported value assumes that a 1 mOhm sense resistor
45is installed. If a different sense resistor is installed, calculate the real
46current by dividing the reported value by the sense resistor value in mOhm.
47
48The chip has two voltage sensors, but only one set of voltage alarm status bits.
49In many many designs, those alarms are associated with the ADIN2 sensor, due to
50the proximity of the ADIN2 pin to the OV pin. ADIN2 is, however, not available
51on all chip variants. To ensure that the alarm condition is reported to the user,
52report it with both voltage sensors.
53
54in1_input ADIN2 voltage (mV)
55in1_min_alarm ADIN/ADIN2 Undervoltage alarm
56in1_max_alarm ADIN/ADIN2 Overvoltage alarm
57
58in2_input ADIN voltage (mV)
59in2_min_alarm ADIN/ADIN2 Undervoltage alarm
60in2_max_alarm ADIN/ADIN2 Overvoltage alarm
61
62curr1_input SENSE current (mA)
63curr1_alarm SENSE overcurrent alarm
diff --git a/MAINTAINERS b/MAINTAINERS
index 541451050b36..146b8a068a4e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3765,6 +3765,13 @@ L: linux-scsi@vger.kernel.org
3765S: Maintained 3765S: Maintained
3766F: drivers/scsi/sym53c8xx_2/ 3766F: drivers/scsi/sym53c8xx_2/
3767 3767
3768LTC4261 HARDWARE MONITOR DRIVER
3769M: Guenter Roeck <linux@roeck-us.net>
3770L: lm-sensors@lm-sensors.org
3771S: Maintained
3772F: Documentation/hwmon/ltc4261
3773F: drivers/hwmon/ltc4261.c
3774
3768LTP (Linux Test Project) 3775LTP (Linux Test Project)
3769M: Rishikesh K Rajak <risrajak@linux.vnet.ibm.com> 3776M: Rishikesh K Rajak <risrajak@linux.vnet.ibm.com>
3770M: Garrett Cooper <yanegomi@gmail.com> 3777M: Garrett Cooper <yanegomi@gmail.com>
diff --git a/arch/arm/mach-kirkwood/netspace_v2-setup.c b/arch/arm/mach-kirkwood/netspace_v2-setup.c
index 5e286441b8f4..5ea66f1f4178 100644
--- a/arch/arm/mach-kirkwood/netspace_v2-setup.c
+++ b/arch/arm/mach-kirkwood/netspace_v2-setup.c
@@ -30,6 +30,7 @@
30#include <linux/gpio.h> 30#include <linux/gpio.h>
31#include <linux/gpio_keys.h> 31#include <linux/gpio_keys.h>
32#include <linux/leds.h> 32#include <linux/leds.h>
33#include <linux/gpio-fan.h>
33#include <asm/mach-types.h> 34#include <asm/mach-types.h>
34#include <asm/mach/arch.h> 35#include <asm/mach/arch.h>
35#include <mach/kirkwood.h> 36#include <mach/kirkwood.h>
@@ -137,6 +138,46 @@ static struct platform_device netspace_v2_leds = {
137}; 138};
138 139
139/***************************************************************************** 140/*****************************************************************************
141 * GPIO fan
142 ****************************************************************************/
143
144/* Designed for fan 40x40x16: ADDA AD0412LB-D50 6000rpm@12v */
145static struct gpio_fan_speed netspace_max_v2_fan_speed[] = {
146 { 0, 0 },
147 { 1500, 15 },
148 { 1700, 14 },
149 { 1800, 13 },
150 { 2100, 12 },
151 { 3100, 11 },
152 { 3300, 10 },
153 { 4300, 9 },
154 { 5500, 8 },
155};
156
157static unsigned netspace_max_v2_fan_ctrl[] = { 22, 7, 33, 23 };
158
159static struct gpio_fan_alarm netspace_max_v2_fan_alarm = {
160 .gpio = 25,
161 .active_low = 1,
162};
163
164static struct gpio_fan_platform_data netspace_max_v2_fan_data = {
165 .num_ctrl = ARRAY_SIZE(netspace_max_v2_fan_ctrl),
166 .ctrl = netspace_max_v2_fan_ctrl,
167 .alarm = &netspace_max_v2_fan_alarm,
168 .num_speed = ARRAY_SIZE(netspace_max_v2_fan_speed),
169 .speed = netspace_max_v2_fan_speed,
170};
171
172static struct platform_device netspace_max_v2_gpio_fan = {
173 .name = "gpio-fan",
174 .id = -1,
175 .dev = {
176 .platform_data = &netspace_max_v2_fan_data,
177 },
178};
179
180/*****************************************************************************
140 * General Setup 181 * General Setup
141 ****************************************************************************/ 182 ****************************************************************************/
142 183
@@ -205,6 +246,8 @@ static void __init netspace_v2_init(void)
205 platform_device_register(&netspace_v2_leds); 246 platform_device_register(&netspace_v2_leds);
206 platform_device_register(&netspace_v2_gpio_leds); 247 platform_device_register(&netspace_v2_gpio_leds);
207 platform_device_register(&netspace_v2_gpio_buttons); 248 platform_device_register(&netspace_v2_gpio_buttons);
249 if (machine_is_netspace_max_v2())
250 platform_device_register(&netspace_max_v2_gpio_fan);
208 251
209 if (gpio_request(NETSPACE_V2_GPIO_POWER_OFF, "power-off") == 0 && 252 if (gpio_request(NETSPACE_V2_GPIO_POWER_OFF, "power-off") == 0 &&
210 gpio_direction_output(NETSPACE_V2_GPIO_POWER_OFF, 0) == 0) 253 gpio_direction_output(NETSPACE_V2_GPIO_POWER_OFF, 0) == 0)
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index e382da3122b7..c357c835eb1e 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -399,6 +399,15 @@ config SENSORS_GL520SM
399 This driver can also be built as a module. If so, the module 399 This driver can also be built as a module. If so, the module
400 will be called gl520sm. 400 will be called gl520sm.
401 401
402config SENSORS_GPIO_FAN
403 tristate "GPIO fan"
404 depends on GENERIC_GPIO
405 help
406 If you say yes here you get support for fans connected to GPIO lines.
407
408 This driver can also be built as a module. If so, the module
409 will be called gpio-fan.
410
402config SENSORS_CORETEMP 411config SENSORS_CORETEMP
403 tristate "Intel Core/Core2/Atom temperature sensor" 412 tristate "Intel Core/Core2/Atom temperature sensor"
404 depends on X86 && PCI && EXPERIMENTAL 413 depends on X86 && PCI && EXPERIMENTAL
@@ -654,6 +663,17 @@ config SENSORS_LTC4245
654 This driver can also be built as a module. If so, the module will 663 This driver can also be built as a module. If so, the module will
655 be called ltc4245. 664 be called ltc4245.
656 665
666config SENSORS_LTC4261
667 tristate "Linear Technology LTC4261"
668 depends on I2C && EXPERIMENTAL
669 default n
670 help
671 If you say yes here you get support for Linear Technology LTC4261
672 Negative Voltage Hot Swap Controller I2C interface.
673
674 This driver can also be built as a module. If so, the module will
675 be called ltc4261.
676
657config SENSORS_LM95241 677config SENSORS_LM95241
658 tristate "National Semiconductor LM95241 sensor chip" 678 tristate "National Semiconductor LM95241 sensor chip"
659 depends on I2C 679 depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index ec9cb735c898..d30f0f6870e0 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_SENSORS_FSCHMD) += fschmd.o
51obj-$(CONFIG_SENSORS_G760A) += g760a.o 51obj-$(CONFIG_SENSORS_G760A) += g760a.o
52obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o 52obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o
53obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o 53obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o
54obj-$(CONFIG_SENSORS_GPIO_FAN) += gpio-fan.o
54obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o 55obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o
55obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o 56obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o
56obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o 57obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o
@@ -79,6 +80,7 @@ obj-$(CONFIG_SENSORS_LM93) += lm93.o
79obj-$(CONFIG_SENSORS_LM95241) += lm95241.o 80obj-$(CONFIG_SENSORS_LM95241) += lm95241.o
80obj-$(CONFIG_SENSORS_LTC4215) += ltc4215.o 81obj-$(CONFIG_SENSORS_LTC4215) += ltc4215.o
81obj-$(CONFIG_SENSORS_LTC4245) += ltc4245.o 82obj-$(CONFIG_SENSORS_LTC4245) += ltc4245.o
83obj-$(CONFIG_SENSORS_LTC4261) += ltc4261.o
82obj-$(CONFIG_SENSORS_MAX1111) += max1111.o 84obj-$(CONFIG_SENSORS_MAX1111) += max1111.o
83obj-$(CONFIG_SENSORS_MAX1619) += max1619.o 85obj-$(CONFIG_SENSORS_MAX1619) += max1619.o
84obj-$(CONFIG_SENSORS_MAX6650) += max6650.o 86obj-$(CONFIG_SENSORS_MAX6650) += max6650.o
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index a23b17a78ace..42de98d73ff5 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -21,7 +21,6 @@
21 */ 21 */
22 22
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/delay.h>
25#include <linux/init.h> 24#include <linux/init.h>
26#include <linux/slab.h> 25#include <linux/slab.h>
27#include <linux/jiffies.h> 26#include <linux/jiffies.h>
@@ -280,11 +279,9 @@ static int __devinit get_tjmax(struct cpuinfo_x86 *c, u32 id,
280 case 0x1a: 279 case 0x1a:
281 dev_warn(dev, "TjMax is assumed as 100 C!\n"); 280 dev_warn(dev, "TjMax is assumed as 100 C!\n");
282 return 100000; 281 return 100000;
283 break;
284 case 0x17: 282 case 0x17:
285 case 0x1c: /* Atom CPUs */ 283 case 0x1c: /* Atom CPUs */
286 return adjust_tjmax(c, id, dev); 284 return adjust_tjmax(c, id, dev);
287 break;
288 default: 285 default:
289 dev_warn(dev, "CPU (model=0x%x) is not supported yet," 286 dev_warn(dev, "CPU (model=0x%x) is not supported yet,"
290 " using default TjMax of 100C.\n", c->x86_model); 287 " using default TjMax of 100C.\n", c->x86_model);
@@ -292,6 +289,15 @@ static int __devinit get_tjmax(struct cpuinfo_x86 *c, u32 id,
292 } 289 }
293} 290}
294 291
292static void __devinit get_ucode_rev_on_cpu(void *edx)
293{
294 u32 eax;
295
296 wrmsr(MSR_IA32_UCODE_REV, 0, 0);
297 sync_core();
298 rdmsr(MSR_IA32_UCODE_REV, eax, *(u32 *)edx);
299}
300
295static int __devinit coretemp_probe(struct platform_device *pdev) 301static int __devinit coretemp_probe(struct platform_device *pdev)
296{ 302{
297 struct coretemp_data *data; 303 struct coretemp_data *data;
@@ -327,8 +333,15 @@ static int __devinit coretemp_probe(struct platform_device *pdev)
327 333
328 if ((c->x86_model == 0xe) && (c->x86_mask < 0xc)) { 334 if ((c->x86_model == 0xe) && (c->x86_mask < 0xc)) {
329 /* check for microcode update */ 335 /* check for microcode update */
330 rdmsr_on_cpu(data->id, MSR_IA32_UCODE_REV, &eax, &edx); 336 err = smp_call_function_single(data->id, get_ucode_rev_on_cpu,
331 if (edx < 0x39) { 337 &edx, 1);
338 if (err) {
339 dev_err(&pdev->dev,
340 "Cannot determine microcode revision of "
341 "CPU#%u (%d)!\n", data->id, err);
342 err = -ENODEV;
343 goto exit_free;
344 } else if (edx < 0x39) {
332 err = -ENODEV; 345 err = -ENODEV;
333 dev_err(&pdev->dev, 346 dev_err(&pdev->dev,
334 "Errata AE18 not fixed, update BIOS or " 347 "Errata AE18 not fixed, update BIOS or "
@@ -490,7 +503,7 @@ exit:
490 return err; 503 return err;
491} 504}
492 505
493static void coretemp_device_remove(unsigned int cpu) 506static void __cpuinit coretemp_device_remove(unsigned int cpu)
494{ 507{
495 struct pdev_entry *p; 508 struct pdev_entry *p;
496 unsigned int i; 509 unsigned int i;
@@ -569,9 +582,8 @@ exit:
569static void __exit coretemp_exit(void) 582static void __exit coretemp_exit(void)
570{ 583{
571 struct pdev_entry *p, *n; 584 struct pdev_entry *p, *n;
572#ifdef CONFIG_HOTPLUG_CPU 585
573 unregister_hotcpu_notifier(&coretemp_cpu_notifier); 586 unregister_hotcpu_notifier(&coretemp_cpu_notifier);
574#endif
575 mutex_lock(&pdev_list_mutex); 587 mutex_lock(&pdev_list_mutex);
576 list_for_each_entry_safe(p, n, &pdev_list, list) { 588 list_for_each_entry_safe(p, n, &pdev_list, list) {
577 platform_device_unregister(p->pdev); 589 platform_device_unregister(p->pdev);
diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c
new file mode 100644
index 000000000000..aa701a183707
--- /dev/null
+++ b/drivers/hwmon/gpio-fan.c
@@ -0,0 +1,558 @@
1/*
2 * gpio-fan.c - Hwmon driver for fans connected to GPIO lines.
3 *
4 * Copyright (C) 2010 LaCie
5 *
6 * Author: Simon Guinot <sguinot@lacie.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/slab.h>
26#include <linux/interrupt.h>
27#include <linux/irq.h>
28#include <linux/platform_device.h>
29#include <linux/err.h>
30#include <linux/mutex.h>
31#include <linux/hwmon.h>
32#include <linux/gpio.h>
33#include <linux/gpio-fan.h>
34
35struct gpio_fan_data {
36 struct platform_device *pdev;
37 struct device *hwmon_dev;
38 struct mutex lock; /* lock GPIOs operations. */
39 int num_ctrl;
40 unsigned *ctrl;
41 int num_speed;
42 struct gpio_fan_speed *speed;
43 int speed_index;
44#ifdef CONFIG_PM
45 int resume_speed;
46#endif
47 bool pwm_enable;
48 struct gpio_fan_alarm *alarm;
49 struct work_struct alarm_work;
50};
51
52/*
53 * Alarm GPIO.
54 */
55
56static void fan_alarm_notify(struct work_struct *ws)
57{
58 struct gpio_fan_data *fan_data =
59 container_of(ws, struct gpio_fan_data, alarm_work);
60
61 sysfs_notify(&fan_data->pdev->dev.kobj, NULL, "fan1_alarm");
62 kobject_uevent(&fan_data->pdev->dev.kobj, KOBJ_CHANGE);
63}
64
65static irqreturn_t fan_alarm_irq_handler(int irq, void *dev_id)
66{
67 struct gpio_fan_data *fan_data = dev_id;
68
69 schedule_work(&fan_data->alarm_work);
70
71 return IRQ_NONE;
72}
73
74static ssize_t show_fan_alarm(struct device *dev,
75 struct device_attribute *attr, char *buf)
76{
77 struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
78 struct gpio_fan_alarm *alarm = fan_data->alarm;
79 int value = gpio_get_value(alarm->gpio);
80
81 if (alarm->active_low)
82 value = !value;
83
84 return sprintf(buf, "%d\n", value);
85}
86
87static DEVICE_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL);
88
89static int fan_alarm_init(struct gpio_fan_data *fan_data,
90 struct gpio_fan_alarm *alarm)
91{
92 int err;
93 int alarm_irq;
94 struct platform_device *pdev = fan_data->pdev;
95
96 fan_data->alarm = alarm;
97
98 err = gpio_request(alarm->gpio, "GPIO fan alarm");
99 if (err)
100 return err;
101
102 err = gpio_direction_input(alarm->gpio);
103 if (err)
104 goto err_free_gpio;
105
106 err = device_create_file(&pdev->dev, &dev_attr_fan1_alarm);
107 if (err)
108 goto err_free_gpio;
109
110 /*
111 * If the alarm GPIO don't support interrupts, just leave
112 * without initializing the fail notification support.
113 */
114 alarm_irq = gpio_to_irq(alarm->gpio);
115 if (alarm_irq < 0)
116 return 0;
117
118 INIT_WORK(&fan_data->alarm_work, fan_alarm_notify);
119 set_irq_type(alarm_irq, IRQ_TYPE_EDGE_BOTH);
120 err = request_irq(alarm_irq, fan_alarm_irq_handler, IRQF_SHARED,
121 "GPIO fan alarm", fan_data);
122 if (err)
123 goto err_free_sysfs;
124
125 return 0;
126
127err_free_sysfs:
128 device_remove_file(&pdev->dev, &dev_attr_fan1_alarm);
129err_free_gpio:
130 gpio_free(alarm->gpio);
131
132 return err;
133}
134
135static void fan_alarm_free(struct gpio_fan_data *fan_data)
136{
137 struct platform_device *pdev = fan_data->pdev;
138 int alarm_irq = gpio_to_irq(fan_data->alarm->gpio);
139
140 if (alarm_irq >= 0)
141 free_irq(alarm_irq, fan_data);
142 device_remove_file(&pdev->dev, &dev_attr_fan1_alarm);
143 gpio_free(fan_data->alarm->gpio);
144}
145
146/*
147 * Control GPIOs.
148 */
149
150/* Must be called with fan_data->lock held, except during initialization. */
151static void __set_fan_ctrl(struct gpio_fan_data *fan_data, int ctrl_val)
152{
153 int i;
154
155 for (i = 0; i < fan_data->num_ctrl; i++)
156 gpio_set_value(fan_data->ctrl[i], (ctrl_val >> i) & 1);
157}
158
159static int __get_fan_ctrl(struct gpio_fan_data *fan_data)
160{
161 int i;
162 int ctrl_val = 0;
163
164 for (i = 0; i < fan_data->num_ctrl; i++) {
165 int value;
166
167 value = gpio_get_value(fan_data->ctrl[i]);
168 ctrl_val |= (value << i);
169 }
170 return ctrl_val;
171}
172
173/* Must be called with fan_data->lock held, except during initialization. */
174static void set_fan_speed(struct gpio_fan_data *fan_data, int speed_index)
175{
176 if (fan_data->speed_index == speed_index)
177 return;
178
179 __set_fan_ctrl(fan_data, fan_data->speed[speed_index].ctrl_val);
180 fan_data->speed_index = speed_index;
181}
182
183static int get_fan_speed_index(struct gpio_fan_data *fan_data)
184{
185 int ctrl_val = __get_fan_ctrl(fan_data);
186 int i;
187
188 for (i = 0; i < fan_data->num_speed; i++)
189 if (fan_data->speed[i].ctrl_val == ctrl_val)
190 return i;
191
192 dev_warn(&fan_data->pdev->dev,
193 "missing speed array entry for GPIO value 0x%x\n", ctrl_val);
194
195 return -EINVAL;
196}
197
198static int rpm_to_speed_index(struct gpio_fan_data *fan_data, int rpm)
199{
200 struct gpio_fan_speed *speed = fan_data->speed;
201 int i;
202
203 for (i = 0; i < fan_data->num_speed; i++)
204 if (speed[i].rpm >= rpm)
205 return i;
206
207 return fan_data->num_speed - 1;
208}
209
210static ssize_t show_pwm(struct device *dev,
211 struct device_attribute *attr, char *buf)
212{
213 struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
214 u8 pwm = fan_data->speed_index * 255 / (fan_data->num_speed - 1);
215
216 return sprintf(buf, "%d\n", pwm);
217}
218
219static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
220 const char *buf, size_t count)
221{
222 struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
223 unsigned long pwm;
224 int speed_index;
225 int ret = count;
226
227 if (strict_strtoul(buf, 10, &pwm) || pwm > 255)
228 return -EINVAL;
229
230 mutex_lock(&fan_data->lock);
231
232 if (!fan_data->pwm_enable) {
233 ret = -EPERM;
234 goto exit_unlock;
235 }
236
237 speed_index = DIV_ROUND_UP(pwm * (fan_data->num_speed - 1), 255);
238 set_fan_speed(fan_data, speed_index);
239
240exit_unlock:
241 mutex_unlock(&fan_data->lock);
242
243 return ret;
244}
245
246static ssize_t show_pwm_enable(struct device *dev,
247 struct device_attribute *attr, char *buf)
248{
249 struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
250
251 return sprintf(buf, "%d\n", fan_data->pwm_enable);
252}
253
254static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
255 const char *buf, size_t count)
256{
257 struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
258 unsigned long val;
259
260 if (strict_strtoul(buf, 10, &val) || val > 1)
261 return -EINVAL;
262
263 if (fan_data->pwm_enable == val)
264 return count;
265
266 mutex_lock(&fan_data->lock);
267
268 fan_data->pwm_enable = val;
269
270 /* Disable manual control mode: set fan at full speed. */
271 if (val == 0)
272 set_fan_speed(fan_data, fan_data->num_speed - 1);
273
274 mutex_unlock(&fan_data->lock);
275
276 return count;
277}
278
279static ssize_t show_pwm_mode(struct device *dev,
280 struct device_attribute *attr, char *buf)
281{
282 return sprintf(buf, "0\n");
283}
284
285static ssize_t show_rpm_min(struct device *dev,
286 struct device_attribute *attr, char *buf)
287{
288 struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
289
290 return sprintf(buf, "%d\n", fan_data->speed[0].rpm);
291}
292
293static ssize_t show_rpm_max(struct device *dev,
294 struct device_attribute *attr, char *buf)
295{
296 struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
297
298 return sprintf(buf, "%d\n",
299 fan_data->speed[fan_data->num_speed - 1].rpm);
300}
301
302static ssize_t show_rpm(struct device *dev,
303 struct device_attribute *attr, char *buf)
304{
305 struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
306
307 return sprintf(buf, "%d\n", fan_data->speed[fan_data->speed_index].rpm);
308}
309
310static ssize_t set_rpm(struct device *dev, struct device_attribute *attr,
311 const char *buf, size_t count)
312{
313 struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
314 unsigned long rpm;
315 int ret = count;
316
317 if (strict_strtoul(buf, 10, &rpm))
318 return -EINVAL;
319
320 mutex_lock(&fan_data->lock);
321
322 if (!fan_data->pwm_enable) {
323 ret = -EPERM;
324 goto exit_unlock;
325 }
326
327 set_fan_speed(fan_data, rpm_to_speed_index(fan_data, rpm));
328
329exit_unlock:
330 mutex_unlock(&fan_data->lock);
331
332 return ret;
333}
334
335static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm);
336static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR,
337 show_pwm_enable, set_pwm_enable);
338static DEVICE_ATTR(pwm1_mode, S_IRUGO, show_pwm_mode, NULL);
339static DEVICE_ATTR(fan1_min, S_IRUGO, show_rpm_min, NULL);
340static DEVICE_ATTR(fan1_max, S_IRUGO, show_rpm_max, NULL);
341static DEVICE_ATTR(fan1_input, S_IRUGO, show_rpm, NULL);
342static DEVICE_ATTR(fan1_target, S_IRUGO | S_IWUSR, show_rpm, set_rpm);
343
344static struct attribute *gpio_fan_ctrl_attributes[] = {
345 &dev_attr_pwm1.attr,
346 &dev_attr_pwm1_enable.attr,
347 &dev_attr_pwm1_mode.attr,
348 &dev_attr_fan1_input.attr,
349 &dev_attr_fan1_target.attr,
350 &dev_attr_fan1_min.attr,
351 &dev_attr_fan1_max.attr,
352 NULL
353};
354
355static const struct attribute_group gpio_fan_ctrl_group = {
356 .attrs = gpio_fan_ctrl_attributes,
357};
358
359static int fan_ctrl_init(struct gpio_fan_data *fan_data,
360 struct gpio_fan_platform_data *pdata)
361{
362 struct platform_device *pdev = fan_data->pdev;
363 int num_ctrl = pdata->num_ctrl;
364 unsigned *ctrl = pdata->ctrl;
365 int i, err;
366
367 for (i = 0; i < num_ctrl; i++) {
368 err = gpio_request(ctrl[i], "GPIO fan control");
369 if (err)
370 goto err_free_gpio;
371
372 err = gpio_direction_output(ctrl[i], gpio_get_value(ctrl[i]));
373 if (err) {
374 gpio_free(ctrl[i]);
375 goto err_free_gpio;
376 }
377 }
378
379 err = sysfs_create_group(&pdev->dev.kobj, &gpio_fan_ctrl_group);
380 if (err)
381 goto err_free_gpio;
382
383 fan_data->num_ctrl = num_ctrl;
384 fan_data->ctrl = ctrl;
385 fan_data->num_speed = pdata->num_speed;
386 fan_data->speed = pdata->speed;
387 fan_data->pwm_enable = true; /* Enable manual fan speed control. */
388 fan_data->speed_index = get_fan_speed_index(fan_data);
389 if (fan_data->speed_index < 0) {
390 err = -ENODEV;
391 goto err_free_gpio;
392 }
393
394 return 0;
395
396err_free_gpio:
397 for (i = i - 1; i >= 0; i--)
398 gpio_free(ctrl[i]);
399
400 return err;
401}
402
403static void fan_ctrl_free(struct gpio_fan_data *fan_data)
404{
405 struct platform_device *pdev = fan_data->pdev;
406 int i;
407
408 sysfs_remove_group(&pdev->dev.kobj, &gpio_fan_ctrl_group);
409 for (i = 0; i < fan_data->num_ctrl; i++)
410 gpio_free(fan_data->ctrl[i]);
411}
412
413/*
414 * Platform driver.
415 */
416
417static ssize_t show_name(struct device *dev,
418 struct device_attribute *attr, char *buf)
419{
420 return sprintf(buf, "gpio-fan\n");
421}
422
423static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
424
425static int __devinit gpio_fan_probe(struct platform_device *pdev)
426{
427 int err;
428 struct gpio_fan_data *fan_data;
429 struct gpio_fan_platform_data *pdata = pdev->dev.platform_data;
430
431 if (!pdata)
432 return -EINVAL;
433
434 fan_data = kzalloc(sizeof(struct gpio_fan_data), GFP_KERNEL);
435 if (!fan_data)
436 return -ENOMEM;
437
438 fan_data->pdev = pdev;
439 platform_set_drvdata(pdev, fan_data);
440 mutex_init(&fan_data->lock);
441
442 /* Configure alarm GPIO if available. */
443 if (pdata->alarm) {
444 err = fan_alarm_init(fan_data, pdata->alarm);
445 if (err)
446 goto err_free_data;
447 }
448
449 /* Configure control GPIOs if available. */
450 if (pdata->ctrl && pdata->num_ctrl > 0) {
451 if (!pdata->speed || pdata->num_speed <= 1) {
452 err = -EINVAL;
453 goto err_free_alarm;
454 }
455 err = fan_ctrl_init(fan_data, pdata);
456 if (err)
457 goto err_free_alarm;
458 }
459
460 err = device_create_file(&pdev->dev, &dev_attr_name);
461 if (err)
462 goto err_free_ctrl;
463
464 /* Make this driver part of hwmon class. */
465 fan_data->hwmon_dev = hwmon_device_register(&pdev->dev);
466 if (IS_ERR(fan_data->hwmon_dev)) {
467 err = PTR_ERR(fan_data->hwmon_dev);
468 goto err_remove_name;
469 }
470
471 dev_info(&pdev->dev, "GPIO fan initialized\n");
472
473 return 0;
474
475err_remove_name:
476 device_remove_file(&pdev->dev, &dev_attr_name);
477err_free_ctrl:
478 if (fan_data->ctrl)
479 fan_ctrl_free(fan_data);
480err_free_alarm:
481 if (fan_data->alarm)
482 fan_alarm_free(fan_data);
483err_free_data:
484 platform_set_drvdata(pdev, NULL);
485 kfree(fan_data);
486
487 return err;
488}
489
490static int __devexit gpio_fan_remove(struct platform_device *pdev)
491{
492 struct gpio_fan_data *fan_data = platform_get_drvdata(pdev);
493
494 hwmon_device_unregister(fan_data->hwmon_dev);
495 device_remove_file(&pdev->dev, &dev_attr_name);
496 if (fan_data->alarm)
497 fan_alarm_free(fan_data);
498 if (fan_data->ctrl)
499 fan_ctrl_free(fan_data);
500 kfree(fan_data);
501
502 return 0;
503}
504
505#ifdef CONFIG_PM
506static int gpio_fan_suspend(struct platform_device *pdev, pm_message_t state)
507{
508 struct gpio_fan_data *fan_data = platform_get_drvdata(pdev);
509
510 if (fan_data->ctrl) {
511 fan_data->resume_speed = fan_data->speed_index;
512 set_fan_speed(fan_data, 0);
513 }
514
515 return 0;
516}
517
518static int gpio_fan_resume(struct platform_device *pdev)
519{
520 struct gpio_fan_data *fan_data = platform_get_drvdata(pdev);
521
522 if (fan_data->ctrl)
523 set_fan_speed(fan_data, fan_data->resume_speed);
524
525 return 0;
526}
527#else
528#define gpio_fan_suspend NULL
529#define gpio_fan_resume NULL
530#endif
531
532static struct platform_driver gpio_fan_driver = {
533 .probe = gpio_fan_probe,
534 .remove = __devexit_p(gpio_fan_remove),
535 .suspend = gpio_fan_suspend,
536 .resume = gpio_fan_resume,
537 .driver = {
538 .name = "gpio-fan",
539 },
540};
541
542static int __init gpio_fan_init(void)
543{
544 return platform_driver_register(&gpio_fan_driver);
545}
546
547static void __exit gpio_fan_exit(void)
548{
549 platform_driver_unregister(&gpio_fan_driver);
550}
551
552module_init(gpio_fan_init);
553module_exit(gpio_fan_exit);
554
555MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>");
556MODULE_DESCRIPTION("GPIO FAN driver");
557MODULE_LICENSE("GPL");
558MODULE_ALIAS("platform:gpio-fan");
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c
index 36e957532230..a56a78412fcb 100644
--- a/drivers/hwmon/hp_accel.c
+++ b/drivers/hwmon/hp_accel.c
@@ -146,7 +146,7 @@ int lis3lv02d_acpi_write(struct lis3lv02d *lis3, int reg, u8 val)
146 146
147static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi) 147static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi)
148{ 148{
149 lis3_dev.ac = *((struct axis_conversion *)dmi->driver_data); 149 lis3_dev.ac = *((union axis_conversion *)dmi->driver_data);
150 printk(KERN_INFO DRIVER_NAME ": hardware type %s found.\n", dmi->ident); 150 printk(KERN_INFO DRIVER_NAME ": hardware type %s found.\n", dmi->ident);
151 151
152 return 1; 152 return 1;
@@ -154,16 +154,19 @@ static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi)
154 154
155/* Represents, for each axis seen by userspace, the corresponding hw axis (+1). 155/* Represents, for each axis seen by userspace, the corresponding hw axis (+1).
156 * If the value is negative, the opposite of the hw value is used. */ 156 * If the value is negative, the opposite of the hw value is used. */
157static struct axis_conversion lis3lv02d_axis_normal = {1, 2, 3}; 157#define DEFINE_CONV(name, x, y, z) \
158static struct axis_conversion lis3lv02d_axis_y_inverted = {1, -2, 3}; 158 static union axis_conversion lis3lv02d_axis_##name = \
159static struct axis_conversion lis3lv02d_axis_x_inverted = {-1, 2, 3}; 159 { .as_array = { x, y, z } }
160static struct axis_conversion lis3lv02d_axis_z_inverted = {1, 2, -3}; 160DEFINE_CONV(normal, 1, 2, 3);
161static struct axis_conversion lis3lv02d_axis_xy_swap = {2, 1, 3}; 161DEFINE_CONV(y_inverted, 1, -2, 3);
162static struct axis_conversion lis3lv02d_axis_xy_rotated_left = {-2, 1, 3}; 162DEFINE_CONV(x_inverted, -1, 2, 3);
163static struct axis_conversion lis3lv02d_axis_xy_rotated_left_usd = {-2, 1, -3}; 163DEFINE_CONV(z_inverted, 1, 2, -3);
164static struct axis_conversion lis3lv02d_axis_xy_swap_inverted = {-2, -1, 3}; 164DEFINE_CONV(xy_swap, 2, 1, 3);
165static struct axis_conversion lis3lv02d_axis_xy_rotated_right = {2, -1, 3}; 165DEFINE_CONV(xy_rotated_left, -2, 1, 3);
166static struct axis_conversion lis3lv02d_axis_xy_swap_yz_inverted = {2, -1, -3}; 166DEFINE_CONV(xy_rotated_left_usd, -2, 1, -3);
167DEFINE_CONV(xy_swap_inverted, -2, -1, 3);
168DEFINE_CONV(xy_rotated_right, 2, -1, 3);
169DEFINE_CONV(xy_swap_yz_inverted, 2, -1, -3);
167 170
168#define AXIS_DMI_MATCH(_ident, _name, _axis) { \ 171#define AXIS_DMI_MATCH(_ident, _name, _axis) { \
169 .ident = _ident, \ 172 .ident = _ident, \
@@ -222,7 +225,7 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
222 AXIS_DMI_MATCH("HPB452x", "HP ProBook 452", y_inverted), 225 AXIS_DMI_MATCH("HPB452x", "HP ProBook 452", y_inverted),
223 AXIS_DMI_MATCH("HPB522x", "HP ProBook 522", xy_swap), 226 AXIS_DMI_MATCH("HPB522x", "HP ProBook 522", xy_swap),
224 AXIS_DMI_MATCH("HPB532x", "HP ProBook 532", y_inverted), 227 AXIS_DMI_MATCH("HPB532x", "HP ProBook 532", y_inverted),
225 AXIS_DMI_MATCH("Mini5102", "HP Mini 5102", xy_rotated_left_usd), 228 AXIS_DMI_MATCH("Mini510x", "HP Mini 510", xy_rotated_left_usd),
226 { NULL, } 229 { NULL, }
227/* Laptop models without axis info (yet): 230/* Laptop models without axis info (yet):
228 * "NC6910" "HP Compaq 6910" 231 * "NC6910" "HP Compaq 6910"
@@ -299,7 +302,10 @@ static int lis3lv02d_add(struct acpi_device *device)
299 lis3lv02d_enum_resources(device); 302 lis3lv02d_enum_resources(device);
300 303
301 /* If possible use a "standard" axes order */ 304 /* If possible use a "standard" axes order */
302 if (dmi_check_system(lis3lv02d_dmi_ids) == 0) { 305 if (lis3_dev.ac.x && lis3_dev.ac.y && lis3_dev.ac.z) {
306 printk(KERN_INFO DRIVER_NAME ": Using custom axes %d,%d,%d\n",
307 lis3_dev.ac.x, lis3_dev.ac.y, lis3_dev.ac.z);
308 } else if (dmi_check_system(lis3lv02d_dmi_ids) == 0) {
303 printk(KERN_INFO DRIVER_NAME ": laptop model unknown, " 309 printk(KERN_INFO DRIVER_NAME ": laptop model unknown, "
304 "using default axes configuration\n"); 310 "using default axes configuration\n");
305 lis3_dev.ac = lis3lv02d_axis_normal; 311 lis3_dev.ac = lis3lv02d_axis_normal;
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index fc591ae53107..0cee73a6124e 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -31,9 +31,11 @@
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/wait.h> 32#include <linux/wait.h>
33#include <linux/poll.h> 33#include <linux/poll.h>
34#include <linux/slab.h>
34#include <linux/freezer.h> 35#include <linux/freezer.h>
35#include <linux/uaccess.h> 36#include <linux/uaccess.h>
36#include <linux/miscdevice.h> 37#include <linux/miscdevice.h>
38#include <linux/pm_runtime.h>
37#include <asm/atomic.h> 39#include <asm/atomic.h>
38#include "lis3lv02d.h" 40#include "lis3lv02d.h"
39 41
@@ -43,6 +45,16 @@
43#define MDPS_POLL_INTERVAL 50 45#define MDPS_POLL_INTERVAL 50
44#define MDPS_POLL_MIN 0 46#define MDPS_POLL_MIN 0
45#define MDPS_POLL_MAX 2000 47#define MDPS_POLL_MAX 2000
48
49#define LIS3_SYSFS_POWERDOWN_DELAY 5000 /* In milliseconds */
50
51#define SELFTEST_OK 0
52#define SELFTEST_FAIL -1
53#define SELFTEST_IRQ -2
54
55#define IRQ_LINE0 0
56#define IRQ_LINE1 1
57
46/* 58/*
47 * The sensor can also generate interrupts (DRDY) but it's pretty pointless 59 * The sensor can also generate interrupts (DRDY) but it's pretty pointless
48 * because they are generated even if the data do not change. So it's better 60 * because they are generated even if the data do not change. So it's better
@@ -66,8 +78,10 @@
66#define LIS3_SENSITIVITY_12B ((LIS3_ACCURACY * 1000) / 1024) 78#define LIS3_SENSITIVITY_12B ((LIS3_ACCURACY * 1000) / 1024)
67#define LIS3_SENSITIVITY_8B (18 * LIS3_ACCURACY) 79#define LIS3_SENSITIVITY_8B (18 * LIS3_ACCURACY)
68 80
69#define LIS3_DEFAULT_FUZZ 3 81#define LIS3_DEFAULT_FUZZ_12B 3
70#define LIS3_DEFAULT_FLAT 3 82#define LIS3_DEFAULT_FLAT_12B 3
83#define LIS3_DEFAULT_FUZZ_8B 1
84#define LIS3_DEFAULT_FLAT_8B 1
71 85
72struct lis3lv02d lis3_dev = { 86struct lis3lv02d lis3_dev = {
73 .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait), 87 .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait),
@@ -75,6 +89,30 @@ struct lis3lv02d lis3_dev = {
75 89
76EXPORT_SYMBOL_GPL(lis3_dev); 90EXPORT_SYMBOL_GPL(lis3_dev);
77 91
92/* just like param_set_int() but does sanity-check so that it won't point
93 * over the axis array size
94 */
95static int param_set_axis(const char *val, const struct kernel_param *kp)
96{
97 int ret = param_set_int(val, kp);
98 if (!ret) {
99 int val = *(int *)kp->arg;
100 if (val < 0)
101 val = -val;
102 if (!val || val > 3)
103 return -EINVAL;
104 }
105 return ret;
106}
107
108static struct kernel_param_ops param_ops_axis = {
109 .set = param_set_axis,
110 .get = param_get_int,
111};
112
113module_param_array_named(axes, lis3_dev.ac.as_array, axis, NULL, 0644);
114MODULE_PARM_DESC(axes, "Axis-mapping for x,y,z directions");
115
78static s16 lis3lv02d_read_8(struct lis3lv02d *lis3, int reg) 116static s16 lis3lv02d_read_8(struct lis3lv02d *lis3, int reg)
79{ 117{
80 s8 lo; 118 s8 lo;
@@ -123,9 +161,24 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
123 int position[3]; 161 int position[3];
124 int i; 162 int i;
125 163
126 position[0] = lis3->read_data(lis3, OUTX); 164 if (lis3->blkread) {
127 position[1] = lis3->read_data(lis3, OUTY); 165 if (lis3_dev.whoami == WAI_12B) {
128 position[2] = lis3->read_data(lis3, OUTZ); 166 u16 data[3];
167 lis3->blkread(lis3, OUTX_L, 6, (u8 *)data);
168 for (i = 0; i < 3; i++)
169 position[i] = (s16)le16_to_cpu(data[i]);
170 } else {
171 u8 data[5];
172 /* Data: x, dummy, y, dummy, z */
173 lis3->blkread(lis3, OUTX, 5, data);
174 for (i = 0; i < 3; i++)
175 position[i] = (s8)data[i * 2];
176 }
177 } else {
178 position[0] = lis3->read_data(lis3, OUTX);
179 position[1] = lis3->read_data(lis3, OUTY);
180 position[2] = lis3->read_data(lis3, OUTZ);
181 }
129 182
130 for (i = 0; i < 3; i++) 183 for (i = 0; i < 3; i++)
131 position[i] = (position[i] * lis3->scale) / LIS3_ACCURACY; 184 position[i] = (position[i] * lis3->scale) / LIS3_ACCURACY;
@@ -138,6 +191,7 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
138/* conversion btw sampling rate and the register values */ 191/* conversion btw sampling rate and the register values */
139static int lis3_12_rates[4] = {40, 160, 640, 2560}; 192static int lis3_12_rates[4] = {40, 160, 640, 2560};
140static int lis3_8_rates[2] = {100, 400}; 193static int lis3_8_rates[2] = {100, 400};
194static int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000};
141 195
142/* ODR is Output Data Rate */ 196/* ODR is Output Data Rate */
143static int lis3lv02d_get_odr(void) 197static int lis3lv02d_get_odr(void)
@@ -156,6 +210,9 @@ static int lis3lv02d_set_odr(int rate)
156 u8 ctrl; 210 u8 ctrl;
157 int i, len, shift; 211 int i, len, shift;
158 212
213 if (!rate)
214 return -EINVAL;
215
159 lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl); 216 lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl);
160 ctrl &= ~lis3_dev.odr_mask; 217 ctrl &= ~lis3_dev.odr_mask;
161 len = 1 << hweight_long(lis3_dev.odr_mask); /* # of possible values */ 218 len = 1 << hweight_long(lis3_dev.odr_mask); /* # of possible values */
@@ -172,19 +229,42 @@ static int lis3lv02d_set_odr(int rate)
172 229
173static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) 230static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
174{ 231{
175 u8 reg; 232 u8 ctlreg, reg;
176 s16 x, y, z; 233 s16 x, y, z;
177 u8 selftest; 234 u8 selftest;
178 int ret; 235 int ret;
236 u8 ctrl_reg_data;
237 unsigned char irq_cfg;
179 238
180 mutex_lock(&lis3->mutex); 239 mutex_lock(&lis3->mutex);
181 if (lis3_dev.whoami == WAI_12B)
182 selftest = CTRL1_ST;
183 else
184 selftest = CTRL1_STP;
185 240
186 lis3->read(lis3, CTRL_REG1, &reg); 241 irq_cfg = lis3->irq_cfg;
187 lis3->write(lis3, CTRL_REG1, (reg | selftest)); 242 if (lis3_dev.whoami == WAI_8B) {
243 lis3->data_ready_count[IRQ_LINE0] = 0;
244 lis3->data_ready_count[IRQ_LINE1] = 0;
245
246 /* Change interrupt cfg to data ready for selftest */
247 atomic_inc(&lis3_dev.wake_thread);
248 lis3->irq_cfg = LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY;
249 lis3->read(lis3, CTRL_REG3, &ctrl_reg_data);
250 lis3->write(lis3, CTRL_REG3, (ctrl_reg_data &
251 ~(LIS3_IRQ1_MASK | LIS3_IRQ2_MASK)) |
252 (LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY));
253 }
254
255 if (lis3_dev.whoami == WAI_3DC) {
256 ctlreg = CTRL_REG4;
257 selftest = CTRL4_ST0;
258 } else {
259 ctlreg = CTRL_REG1;
260 if (lis3_dev.whoami == WAI_12B)
261 selftest = CTRL1_ST;
262 else
263 selftest = CTRL1_STP;
264 }
265
266 lis3->read(lis3, ctlreg, &reg);
267 lis3->write(lis3, ctlreg, (reg | selftest));
188 msleep(lis3->pwron_delay / lis3lv02d_get_odr()); 268 msleep(lis3->pwron_delay / lis3lv02d_get_odr());
189 269
190 /* Read directly to avoid axis remap */ 270 /* Read directly to avoid axis remap */
@@ -193,7 +273,7 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
193 z = lis3->read_data(lis3, OUTZ); 273 z = lis3->read_data(lis3, OUTZ);
194 274
195 /* back to normal settings */ 275 /* back to normal settings */
196 lis3->write(lis3, CTRL_REG1, reg); 276 lis3->write(lis3, ctlreg, reg);
197 msleep(lis3->pwron_delay / lis3lv02d_get_odr()); 277 msleep(lis3->pwron_delay / lis3lv02d_get_odr());
198 278
199 results[0] = x - lis3->read_data(lis3, OUTX); 279 results[0] = x - lis3->read_data(lis3, OUTX);
@@ -201,13 +281,33 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
201 results[2] = z - lis3->read_data(lis3, OUTZ); 281 results[2] = z - lis3->read_data(lis3, OUTZ);
202 282
203 ret = 0; 283 ret = 0;
284
285 if (lis3_dev.whoami == WAI_8B) {
286 /* Restore original interrupt configuration */
287 atomic_dec(&lis3_dev.wake_thread);
288 lis3->write(lis3, CTRL_REG3, ctrl_reg_data);
289 lis3->irq_cfg = irq_cfg;
290
291 if ((irq_cfg & LIS3_IRQ1_MASK) &&
292 lis3->data_ready_count[IRQ_LINE0] < 2) {
293 ret = SELFTEST_IRQ;
294 goto fail;
295 }
296
297 if ((irq_cfg & LIS3_IRQ2_MASK) &&
298 lis3->data_ready_count[IRQ_LINE1] < 2) {
299 ret = SELFTEST_IRQ;
300 goto fail;
301 }
302 }
303
204 if (lis3->pdata) { 304 if (lis3->pdata) {
205 int i; 305 int i;
206 for (i = 0; i < 3; i++) { 306 for (i = 0; i < 3; i++) {
207 /* Check against selftest acceptance limits */ 307 /* Check against selftest acceptance limits */
208 if ((results[i] < lis3->pdata->st_min_limits[i]) || 308 if ((results[i] < lis3->pdata->st_min_limits[i]) ||
209 (results[i] > lis3->pdata->st_max_limits[i])) { 309 (results[i] > lis3->pdata->st_max_limits[i])) {
210 ret = -EIO; 310 ret = SELFTEST_FAIL;
211 goto fail; 311 goto fail;
212 } 312 }
213 } 313 }
@@ -219,10 +319,46 @@ fail:
219 return ret; 319 return ret;
220} 320}
221 321
322/*
323 * Order of registers in the list affects to order of the restore process.
324 * Perhaps it is a good idea to set interrupt enable register as a last one
325 * after all other configurations
326 */
327static u8 lis3_wai8_regs[] = { FF_WU_CFG_1, FF_WU_THS_1, FF_WU_DURATION_1,
328 FF_WU_CFG_2, FF_WU_THS_2, FF_WU_DURATION_2,
329 CLICK_CFG, CLICK_SRC, CLICK_THSY_X, CLICK_THSZ,
330 CLICK_TIMELIMIT, CLICK_LATENCY, CLICK_WINDOW,
331 CTRL_REG1, CTRL_REG2, CTRL_REG3};
332
333static u8 lis3_wai12_regs[] = {FF_WU_CFG, FF_WU_THS_L, FF_WU_THS_H,
334 FF_WU_DURATION, DD_CFG, DD_THSI_L, DD_THSI_H,
335 DD_THSE_L, DD_THSE_H,
336 CTRL_REG1, CTRL_REG3, CTRL_REG2};
337
338static inline void lis3_context_save(struct lis3lv02d *lis3)
339{
340 int i;
341 for (i = 0; i < lis3->regs_size; i++)
342 lis3->read(lis3, lis3->regs[i], &lis3->reg_cache[i]);
343 lis3->regs_stored = true;
344}
345
346static inline void lis3_context_restore(struct lis3lv02d *lis3)
347{
348 int i;
349 if (lis3->regs_stored)
350 for (i = 0; i < lis3->regs_size; i++)
351 lis3->write(lis3, lis3->regs[i], lis3->reg_cache[i]);
352}
353
222void lis3lv02d_poweroff(struct lis3lv02d *lis3) 354void lis3lv02d_poweroff(struct lis3lv02d *lis3)
223{ 355{
356 if (lis3->reg_ctrl)
357 lis3_context_save(lis3);
224 /* disable X,Y,Z axis and power down */ 358 /* disable X,Y,Z axis and power down */
225 lis3->write(lis3, CTRL_REG1, 0x00); 359 lis3->write(lis3, CTRL_REG1, 0x00);
360 if (lis3->reg_ctrl)
361 lis3->reg_ctrl(lis3, LIS3_REG_OFF);
226} 362}
227EXPORT_SYMBOL_GPL(lis3lv02d_poweroff); 363EXPORT_SYMBOL_GPL(lis3lv02d_poweroff);
228 364
@@ -232,19 +368,24 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3)
232 368
233 lis3->init(lis3); 369 lis3->init(lis3);
234 370
235 /* LIS3 power on delay is quite long */
236 msleep(lis3->pwron_delay / lis3lv02d_get_odr());
237
238 /* 371 /*
239 * Common configuration 372 * Common configuration
240 * BDU: (12 bits sensors only) LSB and MSB values are not updated until 373 * BDU: (12 bits sensors only) LSB and MSB values are not updated until
241 * both have been read. So the value read will always be correct. 374 * both have been read. So the value read will always be correct.
375 * Set BOOT bit to refresh factory tuning values.
242 */ 376 */
243 if (lis3->whoami == WAI_12B) { 377 lis3->read(lis3, CTRL_REG2, &reg);
244 lis3->read(lis3, CTRL_REG2, &reg); 378 if (lis3->whoami == WAI_12B)
245 reg |= CTRL2_BDU; 379 reg |= CTRL2_BDU | CTRL2_BOOT;
246 lis3->write(lis3, CTRL_REG2, reg); 380 else
247 } 381 reg |= CTRL2_BOOT_8B;
382 lis3->write(lis3, CTRL_REG2, reg);
383
384 /* LIS3 power on delay is quite long */
385 msleep(lis3->pwron_delay / lis3lv02d_get_odr());
386
387 if (lis3->reg_ctrl)
388 lis3_context_restore(lis3);
248} 389}
249EXPORT_SYMBOL_GPL(lis3lv02d_poweron); 390EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
250 391
@@ -262,6 +403,27 @@ static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev)
262 mutex_unlock(&lis3_dev.mutex); 403 mutex_unlock(&lis3_dev.mutex);
263} 404}
264 405
406static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
407{
408 if (lis3_dev.pm_dev)
409 pm_runtime_get_sync(lis3_dev.pm_dev);
410
411 if (lis3_dev.pdata && lis3_dev.whoami == WAI_8B && lis3_dev.idev)
412 atomic_set(&lis3_dev.wake_thread, 1);
413 /*
414 * Update coordinates for the case where poll interval is 0 and
415 * the chip in running purely under interrupt control
416 */
417 lis3lv02d_joystick_poll(pidev);
418}
419
420static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
421{
422 atomic_set(&lis3_dev.wake_thread, 0);
423 if (lis3_dev.pm_dev)
424 pm_runtime_put(lis3_dev.pm_dev);
425}
426
265static irqreturn_t lis302dl_interrupt(int irq, void *dummy) 427static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
266{ 428{
267 if (!test_bit(0, &lis3_dev.misc_opened)) 429 if (!test_bit(0, &lis3_dev.misc_opened))
@@ -277,8 +439,7 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
277 wake_up_interruptible(&lis3_dev.misc_wait); 439 wake_up_interruptible(&lis3_dev.misc_wait);
278 kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN); 440 kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN);
279out: 441out:
280 if (lis3_dev.pdata && lis3_dev.whoami == WAI_8B && lis3_dev.idev && 442 if (atomic_read(&lis3_dev.wake_thread))
281 lis3_dev.idev->input->users)
282 return IRQ_WAKE_THREAD; 443 return IRQ_WAKE_THREAD;
283 return IRQ_HANDLED; 444 return IRQ_HANDLED;
284} 445}
@@ -309,44 +470,41 @@ static void lis302dl_interrupt_handle_click(struct lis3lv02d *lis3)
309 mutex_unlock(&lis3->mutex); 470 mutex_unlock(&lis3->mutex);
310} 471}
311 472
312static void lis302dl_interrupt_handle_ff_wu(struct lis3lv02d *lis3) 473static inline void lis302dl_data_ready(struct lis3lv02d *lis3, int index)
313{ 474{
314 u8 wu1_src; 475 int dummy;
315 u8 wu2_src;
316
317 lis3->read(lis3, FF_WU_SRC_1, &wu1_src);
318 lis3->read(lis3, FF_WU_SRC_2, &wu2_src);
319 476
320 wu1_src = wu1_src & FF_WU_SRC_IA ? wu1_src : 0; 477 /* Dummy read to ack interrupt */
321 wu2_src = wu2_src & FF_WU_SRC_IA ? wu2_src : 0; 478 lis3lv02d_get_xyz(lis3, &dummy, &dummy, &dummy);
322 479 lis3->data_ready_count[index]++;
323 /* joystick poll is internally protected by the lis3->mutex. */
324 if (wu1_src || wu2_src)
325 lis3lv02d_joystick_poll(lis3_dev.idev);
326} 480}
327 481
328static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data) 482static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
329{ 483{
330
331 struct lis3lv02d *lis3 = data; 484 struct lis3lv02d *lis3 = data;
485 u8 irq_cfg = lis3->irq_cfg & LIS3_IRQ1_MASK;
332 486
333 if ((lis3->pdata->irq_cfg & LIS3_IRQ1_MASK) == LIS3_IRQ1_CLICK) 487 if (irq_cfg == LIS3_IRQ1_CLICK)
334 lis302dl_interrupt_handle_click(lis3); 488 lis302dl_interrupt_handle_click(lis3);
489 else if (unlikely(irq_cfg == LIS3_IRQ1_DATA_READY))
490 lis302dl_data_ready(lis3, IRQ_LINE0);
335 else 491 else
336 lis302dl_interrupt_handle_ff_wu(lis3); 492 lis3lv02d_joystick_poll(lis3->idev);
337 493
338 return IRQ_HANDLED; 494 return IRQ_HANDLED;
339} 495}
340 496
341static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data) 497static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data)
342{ 498{
343
344 struct lis3lv02d *lis3 = data; 499 struct lis3lv02d *lis3 = data;
500 u8 irq_cfg = lis3->irq_cfg & LIS3_IRQ2_MASK;
345 501
346 if ((lis3->pdata->irq_cfg & LIS3_IRQ2_MASK) == LIS3_IRQ2_CLICK) 502 if (irq_cfg == LIS3_IRQ2_CLICK)
347 lis302dl_interrupt_handle_click(lis3); 503 lis302dl_interrupt_handle_click(lis3);
504 else if (unlikely(irq_cfg == LIS3_IRQ2_DATA_READY))
505 lis302dl_data_ready(lis3, IRQ_LINE1);
348 else 506 else
349 lis302dl_interrupt_handle_ff_wu(lis3); 507 lis3lv02d_joystick_poll(lis3->idev);
350 508
351 return IRQ_HANDLED; 509 return IRQ_HANDLED;
352} 510}
@@ -356,6 +514,9 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
356 if (test_and_set_bit(0, &lis3_dev.misc_opened)) 514 if (test_and_set_bit(0, &lis3_dev.misc_opened))
357 return -EBUSY; /* already open */ 515 return -EBUSY; /* already open */
358 516
517 if (lis3_dev.pm_dev)
518 pm_runtime_get_sync(lis3_dev.pm_dev);
519
359 atomic_set(&lis3_dev.count, 0); 520 atomic_set(&lis3_dev.count, 0);
360 return 0; 521 return 0;
361} 522}
@@ -364,6 +525,8 @@ static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
364{ 525{
365 fasync_helper(-1, file, 0, &lis3_dev.async_queue); 526 fasync_helper(-1, file, 0, &lis3_dev.async_queue);
366 clear_bit(0, &lis3_dev.misc_opened); /* release the device */ 527 clear_bit(0, &lis3_dev.misc_opened); /* release the device */
528 if (lis3_dev.pm_dev)
529 pm_runtime_put(lis3_dev.pm_dev);
367 return 0; 530 return 0;
368} 531}
369 532
@@ -460,6 +623,8 @@ int lis3lv02d_joystick_enable(void)
460 return -ENOMEM; 623 return -ENOMEM;
461 624
462 lis3_dev.idev->poll = lis3lv02d_joystick_poll; 625 lis3_dev.idev->poll = lis3lv02d_joystick_poll;
626 lis3_dev.idev->open = lis3lv02d_joystick_open;
627 lis3_dev.idev->close = lis3lv02d_joystick_close;
463 lis3_dev.idev->poll_interval = MDPS_POLL_INTERVAL; 628 lis3_dev.idev->poll_interval = MDPS_POLL_INTERVAL;
464 lis3_dev.idev->poll_interval_min = MDPS_POLL_MIN; 629 lis3_dev.idev->poll_interval_min = MDPS_POLL_MIN;
465 lis3_dev.idev->poll_interval_max = MDPS_POLL_MAX; 630 lis3_dev.idev->poll_interval_max = MDPS_POLL_MAX;
@@ -473,8 +638,16 @@ int lis3lv02d_joystick_enable(void)
473 638
474 set_bit(EV_ABS, input_dev->evbit); 639 set_bit(EV_ABS, input_dev->evbit);
475 max_val = (lis3_dev.mdps_max_val * lis3_dev.scale) / LIS3_ACCURACY; 640 max_val = (lis3_dev.mdps_max_val * lis3_dev.scale) / LIS3_ACCURACY;
476 fuzz = (LIS3_DEFAULT_FUZZ * lis3_dev.scale) / LIS3_ACCURACY; 641 if (lis3_dev.whoami == WAI_12B) {
477 flat = (LIS3_DEFAULT_FLAT * lis3_dev.scale) / LIS3_ACCURACY; 642 fuzz = LIS3_DEFAULT_FUZZ_12B;
643 flat = LIS3_DEFAULT_FLAT_12B;
644 } else {
645 fuzz = LIS3_DEFAULT_FUZZ_8B;
646 flat = LIS3_DEFAULT_FLAT_8B;
647 }
648 fuzz = (fuzz * lis3_dev.scale) / LIS3_ACCURACY;
649 flat = (flat * lis3_dev.scale) / LIS3_ACCURACY;
650
478 input_set_abs_params(input_dev, ABS_X, -max_val, max_val, fuzz, flat); 651 input_set_abs_params(input_dev, ABS_X, -max_val, max_val, fuzz, flat);
479 input_set_abs_params(input_dev, ABS_Y, -max_val, max_val, fuzz, flat); 652 input_set_abs_params(input_dev, ABS_Y, -max_val, max_val, fuzz, flat);
480 input_set_abs_params(input_dev, ABS_Z, -max_val, max_val, fuzz, flat); 653 input_set_abs_params(input_dev, ABS_Z, -max_val, max_val, fuzz, flat);
@@ -512,14 +685,47 @@ void lis3lv02d_joystick_disable(void)
512EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable); 685EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable);
513 686
514/* Sysfs stuff */ 687/* Sysfs stuff */
688static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3)
689{
690 /*
691 * SYSFS functions are fast visitors so put-call
692 * immediately after the get-call. However, keep
693 * chip running for a while and schedule delayed
694 * suspend. This way periodic sysfs calls doesn't
695 * suffer from relatively long power up time.
696 */
697
698 if (lis3->pm_dev) {
699 pm_runtime_get_sync(lis3->pm_dev);
700 pm_runtime_put_noidle(lis3->pm_dev);
701 pm_schedule_suspend(lis3->pm_dev, LIS3_SYSFS_POWERDOWN_DELAY);
702 }
703}
704
515static ssize_t lis3lv02d_selftest_show(struct device *dev, 705static ssize_t lis3lv02d_selftest_show(struct device *dev,
516 struct device_attribute *attr, char *buf) 706 struct device_attribute *attr, char *buf)
517{ 707{
518 int result;
519 s16 values[3]; 708 s16 values[3];
520 709
521 result = lis3lv02d_selftest(&lis3_dev, values); 710 static const char ok[] = "OK";
522 return sprintf(buf, "%s %d %d %d\n", result == 0 ? "OK" : "FAIL", 711 static const char fail[] = "FAIL";
712 static const char irq[] = "FAIL_IRQ";
713 const char *res;
714
715 lis3lv02d_sysfs_poweron(&lis3_dev);
716 switch (lis3lv02d_selftest(&lis3_dev, values)) {
717 case SELFTEST_FAIL:
718 res = fail;
719 break;
720 case SELFTEST_IRQ:
721 res = irq;
722 break;
723 case SELFTEST_OK:
724 default:
725 res = ok;
726 break;
727 }
728 return sprintf(buf, "%s %d %d %d\n", res,
523 values[0], values[1], values[2]); 729 values[0], values[1], values[2]);
524} 730}
525 731
@@ -528,6 +734,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
528{ 734{
529 int x, y, z; 735 int x, y, z;
530 736
737 lis3lv02d_sysfs_poweron(&lis3_dev);
531 mutex_lock(&lis3_dev.mutex); 738 mutex_lock(&lis3_dev.mutex);
532 lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); 739 lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
533 mutex_unlock(&lis3_dev.mutex); 740 mutex_unlock(&lis3_dev.mutex);
@@ -537,6 +744,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
537static ssize_t lis3lv02d_rate_show(struct device *dev, 744static ssize_t lis3lv02d_rate_show(struct device *dev,
538 struct device_attribute *attr, char *buf) 745 struct device_attribute *attr, char *buf)
539{ 746{
747 lis3lv02d_sysfs_poweron(&lis3_dev);
540 return sprintf(buf, "%d\n", lis3lv02d_get_odr()); 748 return sprintf(buf, "%d\n", lis3lv02d_get_odr());
541} 749}
542 750
@@ -549,6 +757,7 @@ static ssize_t lis3lv02d_rate_set(struct device *dev,
549 if (strict_strtoul(buf, 0, &rate)) 757 if (strict_strtoul(buf, 0, &rate))
550 return -EINVAL; 758 return -EINVAL;
551 759
760 lis3lv02d_sysfs_poweron(&lis3_dev);
552 if (lis3lv02d_set_odr(rate)) 761 if (lis3lv02d_set_odr(rate))
553 return -EINVAL; 762 return -EINVAL;
554 763
@@ -585,6 +794,18 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
585{ 794{
586 sysfs_remove_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group); 795 sysfs_remove_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group);
587 platform_device_unregister(lis3->pdev); 796 platform_device_unregister(lis3->pdev);
797 if (lis3->pm_dev) {
798 /* Barrier after the sysfs remove */
799 pm_runtime_barrier(lis3->pm_dev);
800
801 /* SYSFS may have left chip running. Turn off if necessary */
802 if (!pm_runtime_suspended(lis3->pm_dev))
803 lis3lv02d_poweroff(&lis3_dev);
804
805 pm_runtime_disable(lis3->pm_dev);
806 pm_runtime_set_suspended(lis3->pm_dev);
807 }
808 kfree(lis3->reg_cache);
588 return 0; 809 return 0;
589} 810}
590EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); 811EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
@@ -616,16 +837,16 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
616 if (p->wakeup_flags) { 837 if (p->wakeup_flags) {
617 dev->write(dev, FF_WU_CFG_1, p->wakeup_flags); 838 dev->write(dev, FF_WU_CFG_1, p->wakeup_flags);
618 dev->write(dev, FF_WU_THS_1, p->wakeup_thresh & 0x7f); 839 dev->write(dev, FF_WU_THS_1, p->wakeup_thresh & 0x7f);
619 /* default to 2.5ms for now */ 840 /* pdata value + 1 to keep this backward compatible*/
620 dev->write(dev, FF_WU_DURATION_1, 1); 841 dev->write(dev, FF_WU_DURATION_1, p->duration1 + 1);
621 ctrl2 ^= HP_FF_WU1; /* Xor to keep compatible with old pdata*/ 842 ctrl2 ^= HP_FF_WU1; /* Xor to keep compatible with old pdata*/
622 } 843 }
623 844
624 if (p->wakeup_flags2) { 845 if (p->wakeup_flags2) {
625 dev->write(dev, FF_WU_CFG_2, p->wakeup_flags2); 846 dev->write(dev, FF_WU_CFG_2, p->wakeup_flags2);
626 dev->write(dev, FF_WU_THS_2, p->wakeup_thresh2 & 0x7f); 847 dev->write(dev, FF_WU_THS_2, p->wakeup_thresh2 & 0x7f);
627 /* default to 2.5ms for now */ 848 /* pdata value + 1 to keep this backward compatible*/
628 dev->write(dev, FF_WU_DURATION_2, 1); 849 dev->write(dev, FF_WU_DURATION_2, p->duration2 + 1);
629 ctrl2 ^= HP_FF_WU2; /* Xor to keep compatible with old pdata*/ 850 ctrl2 ^= HP_FF_WU2; /* Xor to keep compatible with old pdata*/
630 } 851 }
631 /* Configure hipass filters */ 852 /* Configure hipass filters */
@@ -635,8 +856,8 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
635 err = request_threaded_irq(p->irq2, 856 err = request_threaded_irq(p->irq2,
636 NULL, 857 NULL,
637 lis302dl_interrupt_thread2_8b, 858 lis302dl_interrupt_thread2_8b,
638 IRQF_TRIGGER_RISING | 859 IRQF_TRIGGER_RISING | IRQF_ONESHOT |
639 IRQF_ONESHOT, 860 (p->irq_flags2 & IRQF_TRIGGER_MASK),
640 DRIVER_NAME, &lis3_dev); 861 DRIVER_NAME, &lis3_dev);
641 if (err < 0) 862 if (err < 0)
642 printk(KERN_ERR DRIVER_NAME 863 printk(KERN_ERR DRIVER_NAME
@@ -652,6 +873,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
652{ 873{
653 int err; 874 int err;
654 irq_handler_t thread_fn; 875 irq_handler_t thread_fn;
876 int irq_flags = 0;
655 877
656 dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I); 878 dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I);
657 879
@@ -664,6 +886,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
664 dev->odrs = lis3_12_rates; 886 dev->odrs = lis3_12_rates;
665 dev->odr_mask = CTRL1_DF0 | CTRL1_DF1; 887 dev->odr_mask = CTRL1_DF0 | CTRL1_DF1;
666 dev->scale = LIS3_SENSITIVITY_12B; 888 dev->scale = LIS3_SENSITIVITY_12B;
889 dev->regs = lis3_wai12_regs;
890 dev->regs_size = ARRAY_SIZE(lis3_wai12_regs);
667 break; 891 break;
668 case WAI_8B: 892 case WAI_8B:
669 printk(KERN_INFO DRIVER_NAME ": 8 bits sensor found\n"); 893 printk(KERN_INFO DRIVER_NAME ": 8 bits sensor found\n");
@@ -673,6 +897,17 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
673 dev->odrs = lis3_8_rates; 897 dev->odrs = lis3_8_rates;
674 dev->odr_mask = CTRL1_DR; 898 dev->odr_mask = CTRL1_DR;
675 dev->scale = LIS3_SENSITIVITY_8B; 899 dev->scale = LIS3_SENSITIVITY_8B;
900 dev->regs = lis3_wai8_regs;
901 dev->regs_size = ARRAY_SIZE(lis3_wai8_regs);
902 break;
903 case WAI_3DC:
904 printk(KERN_INFO DRIVER_NAME ": 8 bits 3DC sensor found\n");
905 dev->read_data = lis3lv02d_read_8;
906 dev->mdps_max_val = 128;
907 dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B;
908 dev->odrs = lis3_3dc_rates;
909 dev->odr_mask = CTRL1_ODR0|CTRL1_ODR1|CTRL1_ODR2|CTRL1_ODR3;
910 dev->scale = LIS3_SENSITIVITY_8B;
676 break; 911 break;
677 default: 912 default:
678 printk(KERN_ERR DRIVER_NAME 913 printk(KERN_ERR DRIVER_NAME
@@ -680,11 +915,25 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
680 return -EINVAL; 915 return -EINVAL;
681 } 916 }
682 917
918 dev->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs),
919 sizeof(lis3_wai12_regs)), GFP_KERNEL);
920
921 if (dev->reg_cache == NULL) {
922 printk(KERN_ERR DRIVER_NAME "out of memory\n");
923 return -ENOMEM;
924 }
925
683 mutex_init(&dev->mutex); 926 mutex_init(&dev->mutex);
927 atomic_set(&dev->wake_thread, 0);
684 928
685 lis3lv02d_add_fs(dev); 929 lis3lv02d_add_fs(dev);
686 lis3lv02d_poweron(dev); 930 lis3lv02d_poweron(dev);
687 931
932 if (dev->pm_dev) {
933 pm_runtime_set_active(dev->pm_dev);
934 pm_runtime_enable(dev->pm_dev);
935 }
936
688 if (lis3lv02d_joystick_enable()) 937 if (lis3lv02d_joystick_enable())
689 printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n"); 938 printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
690 939
@@ -696,8 +945,14 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
696 if (dev->whoami == WAI_8B) 945 if (dev->whoami == WAI_8B)
697 lis3lv02d_8b_configure(dev, p); 946 lis3lv02d_8b_configure(dev, p);
698 947
948 irq_flags = p->irq_flags1 & IRQF_TRIGGER_MASK;
949
950 dev->irq_cfg = p->irq_cfg;
699 if (p->irq_cfg) 951 if (p->irq_cfg)
700 dev->write(dev, CTRL_REG3, p->irq_cfg); 952 dev->write(dev, CTRL_REG3, p->irq_cfg);
953
954 if (p->default_rate)
955 lis3lv02d_set_odr(p->default_rate);
701 } 956 }
702 957
703 /* bail if we did not get an IRQ from the bus layer */ 958 /* bail if we did not get an IRQ from the bus layer */
@@ -725,7 +980,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
725 980
726 err = request_threaded_irq(dev->irq, lis302dl_interrupt, 981 err = request_threaded_irq(dev->irq, lis302dl_interrupt,
727 thread_fn, 982 thread_fn,
728 IRQF_TRIGGER_RISING | IRQF_ONESHOT, 983 IRQF_TRIGGER_RISING | IRQF_ONESHOT |
984 irq_flags,
729 DRIVER_NAME, &lis3_dev); 985 DRIVER_NAME, &lis3_dev);
730 986
731 if (err < 0) { 987 if (err < 0) {
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 854091380e33..a1939589eb2c 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -20,6 +20,7 @@
20 */ 20 */
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/input-polldev.h> 22#include <linux/input-polldev.h>
23#include <linux/regulator/consumer.h>
23 24
24/* 25/*
25 * This driver tries to support the "digital" accelerometer chips from 26 * This driver tries to support the "digital" accelerometer chips from
@@ -45,6 +46,7 @@ enum lis3_reg {
45 CTRL_REG1 = 0x20, 46 CTRL_REG1 = 0x20,
46 CTRL_REG2 = 0x21, 47 CTRL_REG2 = 0x21,
47 CTRL_REG3 = 0x22, 48 CTRL_REG3 = 0x22,
49 CTRL_REG4 = 0x23,
48 HP_FILTER_RESET = 0x23, 50 HP_FILTER_RESET = 0x23,
49 STATUS_REG = 0x27, 51 STATUS_REG = 0x27,
50 OUTX_L = 0x28, 52 OUTX_L = 0x28,
@@ -93,6 +95,7 @@ enum lis3lv02d_reg {
93}; 95};
94 96
95enum lis3_who_am_i { 97enum lis3_who_am_i {
98 WAI_3DC = 0x33, /* 8 bits: LIS3DC, HP3DC */
96 WAI_12B = 0x3A, /* 12 bits: LIS3LV02D[LQ]... */ 99 WAI_12B = 0x3A, /* 12 bits: LIS3LV02D[LQ]... */
97 WAI_8B = 0x3B, /* 8 bits: LIS[23]02D[LQ]... */ 100 WAI_8B = 0x3B, /* 8 bits: LIS[23]02D[LQ]... */
98 WAI_6B = 0x52, /* 6 bits: LIS331DLF - not supported */ 101 WAI_6B = 0x52, /* 6 bits: LIS331DLF - not supported */
@@ -118,6 +121,13 @@ enum lis3lv02d_ctrl1_8b {
118 CTRL1_DR = 0x80, 121 CTRL1_DR = 0x80,
119}; 122};
120 123
124enum lis3lv02d_ctrl1_3dc {
125 CTRL1_ODR0 = 0x10,
126 CTRL1_ODR1 = 0x20,
127 CTRL1_ODR2 = 0x40,
128 CTRL1_ODR3 = 0x80,
129};
130
121enum lis3lv02d_ctrl2 { 131enum lis3lv02d_ctrl2 {
122 CTRL2_DAS = 0x01, 132 CTRL2_DAS = 0x01,
123 CTRL2_SIM = 0x02, 133 CTRL2_SIM = 0x02,
@@ -129,9 +139,18 @@ enum lis3lv02d_ctrl2 {
129 CTRL2_FS = 0x80, /* Full Scale selection */ 139 CTRL2_FS = 0x80, /* Full Scale selection */
130}; 140};
131 141
142enum lis3lv02d_ctrl4_3dc {
143 CTRL4_SIM = 0x01,
144 CTRL4_ST0 = 0x02,
145 CTRL4_ST1 = 0x04,
146 CTRL4_FS0 = 0x10,
147 CTRL4_FS1 = 0x20,
148};
149
132enum lis302d_ctrl2 { 150enum lis302d_ctrl2 {
133 HP_FF_WU2 = 0x08, 151 HP_FF_WU2 = 0x08,
134 HP_FF_WU1 = 0x04, 152 HP_FF_WU1 = 0x04,
153 CTRL2_BOOT_8B = 0x40,
135}; 154};
136 155
137enum lis3lv02d_ctrl3 { 156enum lis3lv02d_ctrl3 {
@@ -206,19 +225,33 @@ enum lis3lv02d_click_src_8b {
206 CLICK_IA = 0x40, 225 CLICK_IA = 0x40,
207}; 226};
208 227
209struct axis_conversion { 228enum lis3lv02d_reg_state {
210 s8 x; 229 LIS3_REG_OFF = 0x00,
211 s8 y; 230 LIS3_REG_ON = 0x01,
212 s8 z; 231};
232
233union axis_conversion {
234 struct {
235 int x, y, z;
236 };
237 int as_array[3];
238
213}; 239};
214 240
215struct lis3lv02d { 241struct lis3lv02d {
216 void *bus_priv; /* used by the bus layer only */ 242 void *bus_priv; /* used by the bus layer only */
243 struct device *pm_dev; /* for pm_runtime purposes */
217 int (*init) (struct lis3lv02d *lis3); 244 int (*init) (struct lis3lv02d *lis3);
218 int (*write) (struct lis3lv02d *lis3, int reg, u8 val); 245 int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
219 int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret); 246 int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
247 int (*blkread) (struct lis3lv02d *lis3, int reg, int len, u8 *ret);
248 int (*reg_ctrl) (struct lis3lv02d *lis3, bool state);
220 249
221 int *odrs; /* Supported output data rates */ 250 int *odrs; /* Supported output data rates */
251 u8 *regs; /* Regs to store / restore */
252 int regs_size;
253 u8 *reg_cache;
254 bool regs_stored;
222 u8 odr_mask; /* ODR bit mask */ 255 u8 odr_mask; /* ODR bit mask */
223 u8 whoami; /* indicates measurement precision */ 256 u8 whoami; /* indicates measurement precision */
224 s16 (*read_data) (struct lis3lv02d *lis3, int reg); 257 s16 (*read_data) (struct lis3lv02d *lis3, int reg);
@@ -231,14 +264,18 @@ struct lis3lv02d {
231 264
232 struct input_polled_dev *idev; /* input device */ 265 struct input_polled_dev *idev; /* input device */
233 struct platform_device *pdev; /* platform device */ 266 struct platform_device *pdev; /* platform device */
267 struct regulator_bulk_data regulators[2];
234 atomic_t count; /* interrupt count after last read */ 268 atomic_t count; /* interrupt count after last read */
235 struct axis_conversion ac; /* hw -> logical axis */ 269 union axis_conversion ac; /* hw -> logical axis */
236 int mapped_btns[3]; 270 int mapped_btns[3];
237 271
238 u32 irq; /* IRQ number */ 272 u32 irq; /* IRQ number */
239 struct fasync_struct *async_queue; /* queue for the misc device */ 273 struct fasync_struct *async_queue; /* queue for the misc device */
240 wait_queue_head_t misc_wait; /* Wait queue for the misc device */ 274 wait_queue_head_t misc_wait; /* Wait queue for the misc device */
241 unsigned long misc_opened; /* bit0: whether the device is open */ 275 unsigned long misc_opened; /* bit0: whether the device is open */
276 int data_ready_count[2];
277 atomic_t wake_thread;
278 unsigned char irq_cfg;
242 279
243 struct lis3lv02d_platform_data *pdata; /* for passing board config */ 280 struct lis3lv02d_platform_data *pdata; /* for passing board config */
244 struct mutex mutex; /* Serialize poll and selftest */ 281 struct mutex mutex; /* Serialize poll and selftest */
diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index 8e5933b72d19..9f4bae07f719 100644
--- a/drivers/hwmon/lis3lv02d_i2c.c
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -29,10 +29,30 @@
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/err.h> 30#include <linux/err.h>
31#include <linux/i2c.h> 31#include <linux/i2c.h>
32#include <linux/pm_runtime.h>
33#include <linux/delay.h>
32#include "lis3lv02d.h" 34#include "lis3lv02d.h"
33 35
34#define DRV_NAME "lis3lv02d_i2c" 36#define DRV_NAME "lis3lv02d_i2c"
35 37
38static const char reg_vdd[] = "Vdd";
39static const char reg_vdd_io[] = "Vdd_IO";
40
41static int lis3_reg_ctrl(struct lis3lv02d *lis3, bool state)
42{
43 int ret;
44 if (state == LIS3_REG_OFF) {
45 ret = regulator_bulk_disable(ARRAY_SIZE(lis3->regulators),
46 lis3->regulators);
47 } else {
48 ret = regulator_bulk_enable(ARRAY_SIZE(lis3->regulators),
49 lis3->regulators);
50 /* Chip needs time to wakeup. Not mentioned in datasheet */
51 usleep_range(10000, 20000);
52 }
53 return ret;
54}
55
36static inline s32 lis3_i2c_write(struct lis3lv02d *lis3, int reg, u8 value) 56static inline s32 lis3_i2c_write(struct lis3lv02d *lis3, int reg, u8 value)
37{ 57{
38 struct i2c_client *c = lis3->bus_priv; 58 struct i2c_client *c = lis3->bus_priv;
@@ -46,24 +66,38 @@ static inline s32 lis3_i2c_read(struct lis3lv02d *lis3, int reg, u8 *v)
46 return 0; 66 return 0;
47} 67}
48 68
69static inline s32 lis3_i2c_blockread(struct lis3lv02d *lis3, int reg, int len,
70 u8 *v)
71{
72 struct i2c_client *c = lis3->bus_priv;
73 reg |= (1 << 7); /* 7th bit enables address auto incrementation */
74 return i2c_smbus_read_i2c_block_data(c, reg, len, v);
75}
76
49static int lis3_i2c_init(struct lis3lv02d *lis3) 77static int lis3_i2c_init(struct lis3lv02d *lis3)
50{ 78{
51 u8 reg; 79 u8 reg;
52 int ret; 80 int ret;
53 81
82 if (lis3->reg_ctrl)
83 lis3_reg_ctrl(lis3, LIS3_REG_ON);
84
85 lis3->read(lis3, WHO_AM_I, &reg);
86 if (reg != lis3->whoami)
87 printk(KERN_ERR "lis3: power on failure\n");
88
54 /* power up the device */ 89 /* power up the device */
55 ret = lis3->read(lis3, CTRL_REG1, &reg); 90 ret = lis3->read(lis3, CTRL_REG1, &reg);
56 if (ret < 0) 91 if (ret < 0)
57 return ret; 92 return ret;
58 93
59 reg |= CTRL1_PD0; 94 reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen;
60 return lis3->write(lis3, CTRL_REG1, reg); 95 return lis3->write(lis3, CTRL_REG1, reg);
61} 96}
62 97
63/* Default axis mapping but it can be overwritten by platform data */ 98/* Default axis mapping but it can be overwritten by platform data */
64static struct axis_conversion lis3lv02d_axis_map = { LIS3_DEV_X, 99static union axis_conversion lis3lv02d_axis_map =
65 LIS3_DEV_Y, 100 { .as_array = { LIS3_DEV_X, LIS3_DEV_Y, LIS3_DEV_Z } };
66 LIS3_DEV_Z };
67 101
68static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client, 102static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
69 const struct i2c_device_id *id) 103 const struct i2c_device_id *id)
@@ -72,6 +106,15 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
72 struct lis3lv02d_platform_data *pdata = client->dev.platform_data; 106 struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
73 107
74 if (pdata) { 108 if (pdata) {
109 /* Regulator control is optional */
110 if (pdata->driver_features & LIS3_USE_REGULATOR_CTRL)
111 lis3_dev.reg_ctrl = lis3_reg_ctrl;
112
113 if ((pdata->driver_features & LIS3_USE_BLOCK_READ) &&
114 (i2c_check_functionality(client->adapter,
115 I2C_FUNC_SMBUS_I2C_BLOCK)))
116 lis3_dev.blkread = lis3_i2c_blockread;
117
75 if (pdata->axis_x) 118 if (pdata->axis_x)
76 lis3lv02d_axis_map.x = pdata->axis_x; 119 lis3lv02d_axis_map.x = pdata->axis_x;
77 120
@@ -88,6 +131,16 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
88 goto fail; 131 goto fail;
89 } 132 }
90 133
134 if (lis3_dev.reg_ctrl) {
135 lis3_dev.regulators[0].supply = reg_vdd;
136 lis3_dev.regulators[1].supply = reg_vdd_io;
137 ret = regulator_bulk_get(&client->dev,
138 ARRAY_SIZE(lis3_dev.regulators),
139 lis3_dev.regulators);
140 if (ret < 0)
141 goto fail;
142 }
143
91 lis3_dev.pdata = pdata; 144 lis3_dev.pdata = pdata;
92 lis3_dev.bus_priv = client; 145 lis3_dev.bus_priv = client;
93 lis3_dev.init = lis3_i2c_init; 146 lis3_dev.init = lis3_i2c_init;
@@ -95,10 +148,24 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
95 lis3_dev.write = lis3_i2c_write; 148 lis3_dev.write = lis3_i2c_write;
96 lis3_dev.irq = client->irq; 149 lis3_dev.irq = client->irq;
97 lis3_dev.ac = lis3lv02d_axis_map; 150 lis3_dev.ac = lis3lv02d_axis_map;
151 lis3_dev.pm_dev = &client->dev;
98 152
99 i2c_set_clientdata(client, &lis3_dev); 153 i2c_set_clientdata(client, &lis3_dev);
154
155 /* Provide power over the init call */
156 if (lis3_dev.reg_ctrl)
157 lis3_reg_ctrl(&lis3_dev, LIS3_REG_ON);
158
100 ret = lis3lv02d_init_device(&lis3_dev); 159 ret = lis3lv02d_init_device(&lis3_dev);
160
161 if (lis3_dev.reg_ctrl)
162 lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF);
163
164 if (ret == 0)
165 return 0;
101fail: 166fail:
167 if (pdata && pdata->release_resources)
168 pdata->release_resources();
102 return ret; 169 return ret;
103} 170}
104 171
@@ -111,14 +178,18 @@ static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
111 pdata->release_resources(); 178 pdata->release_resources();
112 179
113 lis3lv02d_joystick_disable(); 180 lis3lv02d_joystick_disable();
114 lis3lv02d_poweroff(lis3); 181 lis3lv02d_remove_fs(&lis3_dev);
115 182
116 return lis3lv02d_remove_fs(&lis3_dev); 183 if (lis3_dev.reg_ctrl)
184 regulator_bulk_free(ARRAY_SIZE(lis3->regulators),
185 lis3_dev.regulators);
186 return 0;
117} 187}
118 188
119#ifdef CONFIG_PM 189#ifdef CONFIG_PM
120static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg) 190static int lis3lv02d_i2c_suspend(struct device *dev)
121{ 191{
192 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
122 struct lis3lv02d *lis3 = i2c_get_clientdata(client); 193 struct lis3lv02d *lis3 = i2c_get_clientdata(client);
123 194
124 if (!lis3->pdata || !lis3->pdata->wakeup_flags) 195 if (!lis3->pdata || !lis3->pdata->wakeup_flags)
@@ -126,18 +197,21 @@ static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
126 return 0; 197 return 0;
127} 198}
128 199
129static int lis3lv02d_i2c_resume(struct i2c_client *client) 200static int lis3lv02d_i2c_resume(struct device *dev)
130{ 201{
202 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
131 struct lis3lv02d *lis3 = i2c_get_clientdata(client); 203 struct lis3lv02d *lis3 = i2c_get_clientdata(client);
132 204
133 if (!lis3->pdata || !lis3->pdata->wakeup_flags) 205 /*
206 * pm_runtime documentation says that devices should always
207 * be powered on at resume. Pm_runtime turns them off after system
208 * wide resume is complete.
209 */
210 if (!lis3->pdata || !lis3->pdata->wakeup_flags ||
211 pm_runtime_suspended(dev))
134 lis3lv02d_poweron(lis3); 212 lis3lv02d_poweron(lis3);
135 return 0;
136}
137 213
138static void lis3lv02d_i2c_shutdown(struct i2c_client *client) 214 return 0;
139{
140 lis3lv02d_i2c_suspend(client, PMSG_SUSPEND);
141} 215}
142#else 216#else
143#define lis3lv02d_i2c_suspend NULL 217#define lis3lv02d_i2c_suspend NULL
@@ -145,6 +219,24 @@ static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
145#define lis3lv02d_i2c_shutdown NULL 219#define lis3lv02d_i2c_shutdown NULL
146#endif 220#endif
147 221
222static int lis3_i2c_runtime_suspend(struct device *dev)
223{
224 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
225 struct lis3lv02d *lis3 = i2c_get_clientdata(client);
226
227 lis3lv02d_poweroff(lis3);
228 return 0;
229}
230
231static int lis3_i2c_runtime_resume(struct device *dev)
232{
233 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
234 struct lis3lv02d *lis3 = i2c_get_clientdata(client);
235
236 lis3lv02d_poweron(lis3);
237 return 0;
238}
239
148static const struct i2c_device_id lis3lv02d_id[] = { 240static const struct i2c_device_id lis3lv02d_id[] = {
149 {"lis3lv02d", 0 }, 241 {"lis3lv02d", 0 },
150 {} 242 {}
@@ -152,14 +244,20 @@ static const struct i2c_device_id lis3lv02d_id[] = {
152 244
153MODULE_DEVICE_TABLE(i2c, lis3lv02d_id); 245MODULE_DEVICE_TABLE(i2c, lis3lv02d_id);
154 246
247static const struct dev_pm_ops lis3_pm_ops = {
248 SET_SYSTEM_SLEEP_PM_OPS(lis3lv02d_i2c_suspend,
249 lis3lv02d_i2c_resume)
250 SET_RUNTIME_PM_OPS(lis3_i2c_runtime_suspend,
251 lis3_i2c_runtime_resume,
252 NULL)
253};
254
155static struct i2c_driver lis3lv02d_i2c_driver = { 255static struct i2c_driver lis3lv02d_i2c_driver = {
156 .driver = { 256 .driver = {
157 .name = DRV_NAME, 257 .name = DRV_NAME,
158 .owner = THIS_MODULE, 258 .owner = THIS_MODULE,
259 .pm = &lis3_pm_ops,
159 }, 260 },
160 .suspend = lis3lv02d_i2c_suspend,
161 .shutdown = lis3lv02d_i2c_shutdown,
162 .resume = lis3lv02d_i2c_resume,
163 .probe = lis3lv02d_i2c_probe, 261 .probe = lis3lv02d_i2c_probe,
164 .remove = __devexit_p(lis3lv02d_i2c_remove), 262 .remove = __devexit_p(lis3lv02d_i2c_remove),
165 .id_table = lis3lv02d_id, 263 .id_table = lis3lv02d_id,
diff --git a/drivers/hwmon/lis3lv02d_spi.c b/drivers/hwmon/lis3lv02d_spi.c
index b9be5e3a22b3..2549de1de4e2 100644
--- a/drivers/hwmon/lis3lv02d_spi.c
+++ b/drivers/hwmon/lis3lv02d_spi.c
@@ -50,11 +50,12 @@ static int lis3_spi_init(struct lis3lv02d *lis3)
50 if (ret < 0) 50 if (ret < 0)
51 return ret; 51 return ret;
52 52
53 reg |= CTRL1_PD0; 53 reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen;
54 return lis3->write(lis3, CTRL_REG1, reg); 54 return lis3->write(lis3, CTRL_REG1, reg);
55} 55}
56 56
57static struct axis_conversion lis3lv02d_axis_normal = { 1, 2, 3 }; 57static union axis_conversion lis3lv02d_axis_normal =
58 { .as_array = { 1, 2, 3 } };
58 59
59static int __devinit lis302dl_spi_probe(struct spi_device *spi) 60static int __devinit lis302dl_spi_probe(struct spi_device *spi)
60{ 61{
diff --git a/drivers/hwmon/ltc4261.c b/drivers/hwmon/ltc4261.c
new file mode 100644
index 000000000000..267626178678
--- /dev/null
+++ b/drivers/hwmon/ltc4261.c
@@ -0,0 +1,315 @@
1/*
2 * Driver for Linear Technology LTC4261 I2C Negative Voltage Hot Swap Controller
3 *
4 * Copyright (C) 2010 Ericsson AB.
5 *
6 * Derived from:
7 *
8 * Driver for Linear Technology LTC4245 I2C Multiple Supply Hot Swap Controller
9 * Copyright (C) 2008 Ira W. Snyder <iws@ovro.caltech.edu>
10 *
11 * Datasheet: http://cds.linear.com/docs/Datasheet/42612fb.pdf
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/err.h>
32#include <linux/slab.h>
33#include <linux/i2c.h>
34#include <linux/hwmon.h>
35#include <linux/hwmon-sysfs.h>
36
37/* chip registers */
38#define LTC4261_STATUS 0x00 /* readonly */
39#define LTC4261_FAULT 0x01
40#define LTC4261_ALERT 0x02
41#define LTC4261_CONTROL 0x03
42#define LTC4261_SENSE_H 0x04
43#define LTC4261_SENSE_L 0x05
44#define LTC4261_ADIN2_H 0x06
45#define LTC4261_ADIN2_L 0x07
46#define LTC4261_ADIN_H 0x08
47#define LTC4261_ADIN_L 0x09
48
49/*
50 * Fault register bits
51 */
52#define FAULT_OV (1<<0)
53#define FAULT_UV (1<<1)
54#define FAULT_OC (1<<2)
55
56struct ltc4261_data {
57 struct device *hwmon_dev;
58
59 struct mutex update_lock;
60 bool valid;
61 unsigned long last_updated; /* in jiffies */
62
63 /* Registers */
64 u8 regs[10];
65};
66
67static struct ltc4261_data *ltc4261_update_device(struct device *dev)
68{
69 struct i2c_client *client = to_i2c_client(dev);
70 struct ltc4261_data *data = i2c_get_clientdata(client);
71 struct ltc4261_data *ret = data;
72
73 mutex_lock(&data->update_lock);
74
75 if (time_after(jiffies, data->last_updated + HZ / 4) || !data->valid) {
76 int i;
77
78 /* Read registers -- 0x00 to 0x09 */
79 for (i = 0; i < ARRAY_SIZE(data->regs); i++) {
80 int val;
81
82 val = i2c_smbus_read_byte_data(client, i);
83 if (unlikely(val < 0)) {
84 dev_dbg(dev,
85 "Failed to read ADC value: error %d",
86 val);
87 ret = ERR_PTR(val);
88 goto abort;
89 }
90 data->regs[i] = val;
91 }
92 data->last_updated = jiffies;
93 data->valid = 1;
94 }
95abort:
96 mutex_unlock(&data->update_lock);
97 return ret;
98}
99
100/* Return the voltage from the given register in mV or mA */
101static int ltc4261_get_value(struct ltc4261_data *data, u8 reg)
102{
103 u32 val;
104
105 val = (data->regs[reg] << 2) + (data->regs[reg + 1] >> 6);
106
107 switch (reg) {
108 case LTC4261_ADIN_H:
109 case LTC4261_ADIN2_H:
110 /* 2.5mV resolution. Convert to mV. */
111 val = val * 25 / 10;
112 break;
113 case LTC4261_SENSE_H:
114 /*
115 * 62.5uV resolution. Convert to current as measured with
116 * an 1 mOhm sense resistor, in mA. If a different sense
117 * resistor is installed, calculate the actual current by
118 * dividing the reported current by the sense resistor value
119 * in mOhm.
120 */
121 val = val * 625 / 10;
122 break;
123 default:
124 /* If we get here, the developer messed up */
125 WARN_ON_ONCE(1);
126 val = 0;
127 break;
128 }
129
130 return val;
131}
132
133static ssize_t ltc4261_show_value(struct device *dev,
134 struct device_attribute *da, char *buf)
135{
136 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
137 struct ltc4261_data *data = ltc4261_update_device(dev);
138 int value;
139
140 if (IS_ERR(data))
141 return PTR_ERR(data);
142
143 value = ltc4261_get_value(data, attr->index);
144 return snprintf(buf, PAGE_SIZE, "%d\n", value);
145}
146
147static ssize_t ltc4261_show_bool(struct device *dev,
148 struct device_attribute *da, char *buf)
149{
150 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
151 struct i2c_client *client = to_i2c_client(dev);
152 struct ltc4261_data *data = ltc4261_update_device(dev);
153 u8 fault;
154
155 if (IS_ERR(data))
156 return PTR_ERR(data);
157
158 fault = data->regs[LTC4261_FAULT] & attr->index;
159 if (fault) /* Clear reported faults in chip register */
160 i2c_smbus_write_byte_data(client, LTC4261_FAULT, ~fault);
161
162 return snprintf(buf, PAGE_SIZE, "%d\n", fault ? 1 : 0);
163}
164
165/*
166 * These macros are used below in constructing device attribute objects
167 * for use with sysfs_create_group() to make a sysfs device file
168 * for each register.
169 */
170
171#define LTC4261_VALUE(name, ltc4261_cmd_idx) \
172 static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
173 ltc4261_show_value, NULL, ltc4261_cmd_idx)
174
175#define LTC4261_BOOL(name, mask) \
176 static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
177 ltc4261_show_bool, NULL, (mask))
178
179/*
180 * Input voltages.
181 */
182LTC4261_VALUE(in1_input, LTC4261_ADIN_H);
183LTC4261_VALUE(in2_input, LTC4261_ADIN2_H);
184
185/*
186 * Voltage alarms. The chip has only one set of voltage alarm status bits,
187 * triggered by input voltage alarms. In many designs, those alarms are
188 * associated with the ADIN2 sensor, due to the proximity of the ADIN2 pin
189 * to the OV pin. ADIN2 is, however, not available on all chip variants.
190 * To ensure that the alarm condition is reported to the user, report it
191 * with both voltage sensors.
192 */
193LTC4261_BOOL(in1_min_alarm, FAULT_UV);
194LTC4261_BOOL(in1_max_alarm, FAULT_OV);
195LTC4261_BOOL(in2_min_alarm, FAULT_UV);
196LTC4261_BOOL(in2_max_alarm, FAULT_OV);
197
198/* Currents (via sense resistor) */
199LTC4261_VALUE(curr1_input, LTC4261_SENSE_H);
200
201/* Overcurrent alarm */
202LTC4261_BOOL(curr1_max_alarm, FAULT_OC);
203
204static struct attribute *ltc4261_attributes[] = {
205 &sensor_dev_attr_in1_input.dev_attr.attr,
206 &sensor_dev_attr_in1_min_alarm.dev_attr.attr,
207 &sensor_dev_attr_in1_max_alarm.dev_attr.attr,
208 &sensor_dev_attr_in2_input.dev_attr.attr,
209 &sensor_dev_attr_in2_min_alarm.dev_attr.attr,
210 &sensor_dev_attr_in2_max_alarm.dev_attr.attr,
211
212 &sensor_dev_attr_curr1_input.dev_attr.attr,
213 &sensor_dev_attr_curr1_max_alarm.dev_attr.attr,
214
215 NULL,
216};
217
218static const struct attribute_group ltc4261_group = {
219 .attrs = ltc4261_attributes,
220};
221
222static int ltc4261_probe(struct i2c_client *client,
223 const struct i2c_device_id *id)
224{
225 struct i2c_adapter *adapter = client->adapter;
226 struct ltc4261_data *data;
227 int ret;
228
229 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
230 return -ENODEV;
231
232 if (i2c_smbus_read_byte_data(client, LTC4261_STATUS) < 0) {
233 dev_err(&client->dev, "Failed to read register %d:%02x:%02x\n",
234 adapter->id, client->addr, LTC4261_STATUS);
235 return -ENODEV;
236 }
237
238 data = kzalloc(sizeof(*data), GFP_KERNEL);
239 if (!data) {
240 ret = -ENOMEM;
241 goto out_kzalloc;
242 }
243
244 i2c_set_clientdata(client, data);
245 mutex_init(&data->update_lock);
246
247 /* Clear faults */
248 i2c_smbus_write_byte_data(client, LTC4261_FAULT, 0x00);
249
250 /* Register sysfs hooks */
251 ret = sysfs_create_group(&client->dev.kobj, &ltc4261_group);
252 if (ret)
253 goto out_sysfs_create_group;
254
255 data->hwmon_dev = hwmon_device_register(&client->dev);
256 if (IS_ERR(data->hwmon_dev)) {
257 ret = PTR_ERR(data->hwmon_dev);
258 goto out_hwmon_device_register;
259 }
260
261 return 0;
262
263out_hwmon_device_register:
264 sysfs_remove_group(&client->dev.kobj, &ltc4261_group);
265out_sysfs_create_group:
266 kfree(data);
267out_kzalloc:
268 return ret;
269}
270
271static int ltc4261_remove(struct i2c_client *client)
272{
273 struct ltc4261_data *data = i2c_get_clientdata(client);
274
275 hwmon_device_unregister(data->hwmon_dev);
276 sysfs_remove_group(&client->dev.kobj, &ltc4261_group);
277
278 kfree(data);
279
280 return 0;
281}
282
283static const struct i2c_device_id ltc4261_id[] = {
284 {"ltc4261", 0},
285 {}
286};
287
288MODULE_DEVICE_TABLE(i2c, ltc4261_id);
289
290/* This is the driver that will be inserted */
291static struct i2c_driver ltc4261_driver = {
292 .driver = {
293 .name = "ltc4261",
294 },
295 .probe = ltc4261_probe,
296 .remove = ltc4261_remove,
297 .id_table = ltc4261_id,
298};
299
300static int __init ltc4261_init(void)
301{
302 return i2c_add_driver(&ltc4261_driver);
303}
304
305static void __exit ltc4261_exit(void)
306{
307 i2c_del_driver(&ltc4261_driver);
308}
309
310MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>");
311MODULE_DESCRIPTION("LTC4261 driver");
312MODULE_LICENSE("GPL");
313
314module_init(ltc4261_init);
315module_exit(ltc4261_exit);
diff --git a/drivers/hwmon/pkgtemp.c b/drivers/hwmon/pkgtemp.c
index f11903936c8b..0798210590bc 100644
--- a/drivers/hwmon/pkgtemp.c
+++ b/drivers/hwmon/pkgtemp.c
@@ -21,7 +21,6 @@
21 */ 21 */
22 22
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/delay.h>
25#include <linux/init.h> 24#include <linux/init.h>
26#include <linux/slab.h> 25#include <linux/slab.h>
27#include <linux/jiffies.h> 26#include <linux/jiffies.h>
@@ -35,6 +34,7 @@
35#include <linux/cpu.h> 34#include <linux/cpu.h>
36#include <asm/msr.h> 35#include <asm/msr.h>
37#include <asm/processor.h> 36#include <asm/processor.h>
37#include <asm/smp.h>
38 38
39#define DRVNAME "pkgtemp" 39#define DRVNAME "pkgtemp"
40 40
@@ -339,8 +339,7 @@ exit:
339 return err; 339 return err;
340} 340}
341 341
342#ifdef CONFIG_HOTPLUG_CPU 342static void __cpuinit pkgtemp_device_remove(unsigned int cpu)
343static void pkgtemp_device_remove(unsigned int cpu)
344{ 343{
345 struct pdev_entry *p; 344 struct pdev_entry *p;
346 unsigned int i; 345 unsigned int i;
@@ -387,12 +386,10 @@ static int __cpuinit pkgtemp_cpu_callback(struct notifier_block *nfb,
387static struct notifier_block pkgtemp_cpu_notifier __refdata = { 386static struct notifier_block pkgtemp_cpu_notifier __refdata = {
388 .notifier_call = pkgtemp_cpu_callback, 387 .notifier_call = pkgtemp_cpu_callback,
389}; 388};
390#endif /* !CONFIG_HOTPLUG_CPU */
391 389
392static int __init pkgtemp_init(void) 390static int __init pkgtemp_init(void)
393{ 391{
394 int i, err = -ENODEV; 392 int i, err = -ENODEV;
395 struct pdev_entry *p, *n;
396 393
397 /* quick check if we run Intel */ 394 /* quick check if we run Intel */
398 if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL) 395 if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL)
@@ -402,31 +399,23 @@ static int __init pkgtemp_init(void)
402 if (err) 399 if (err)
403 goto exit; 400 goto exit;
404 401
405 for_each_online_cpu(i) { 402 for_each_online_cpu(i)
406 err = pkgtemp_device_add(i); 403 pkgtemp_device_add(i);
407 if (err) 404
408 goto exit_devices_unreg; 405#ifndef CONFIG_HOTPLUG_CPU
409 }
410 if (list_empty(&pdev_list)) { 406 if (list_empty(&pdev_list)) {
411 err = -ENODEV; 407 err = -ENODEV;
412 goto exit_driver_unreg; 408 goto exit_driver_unreg;
413 } 409 }
410#endif
414 411
415#ifdef CONFIG_HOTPLUG_CPU
416 register_hotcpu_notifier(&pkgtemp_cpu_notifier); 412 register_hotcpu_notifier(&pkgtemp_cpu_notifier);
417#endif
418 return 0; 413 return 0;
419 414
420exit_devices_unreg: 415#ifndef CONFIG_HOTPLUG_CPU
421 mutex_lock(&pdev_list_mutex);
422 list_for_each_entry_safe(p, n, &pdev_list, list) {
423 platform_device_unregister(p->pdev);
424 list_del(&p->list);
425 kfree(p);
426 }
427 mutex_unlock(&pdev_list_mutex);
428exit_driver_unreg: 416exit_driver_unreg:
429 platform_driver_unregister(&pkgtemp_driver); 417 platform_driver_unregister(&pkgtemp_driver);
418#endif
430exit: 419exit:
431 return err; 420 return err;
432} 421}
@@ -434,9 +423,8 @@ exit:
434static void __exit pkgtemp_exit(void) 423static void __exit pkgtemp_exit(void)
435{ 424{
436 struct pdev_entry *p, *n; 425 struct pdev_entry *p, *n;
437#ifdef CONFIG_HOTPLUG_CPU 426
438 unregister_hotcpu_notifier(&pkgtemp_cpu_notifier); 427 unregister_hotcpu_notifier(&pkgtemp_cpu_notifier);
439#endif
440 mutex_lock(&pdev_list_mutex); 428 mutex_lock(&pdev_list_mutex);
441 list_for_each_entry_safe(p, n, &pdev_list, list) { 429 list_for_each_entry_safe(p, n, &pdev_list, list) {
442 platform_device_unregister(p->pdev); 430 platform_device_unregister(p->pdev);
diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c
index ffb793af680b..ec7fad747adc 100644
--- a/drivers/hwmon/via-cputemp.c
+++ b/drivers/hwmon/via-cputemp.c
@@ -22,10 +22,8 @@
22 */ 22 */
23 23
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/delay.h>
26#include <linux/init.h> 25#include <linux/init.h>
27#include <linux/slab.h> 26#include <linux/slab.h>
28#include <linux/jiffies.h>
29#include <linux/hwmon.h> 27#include <linux/hwmon.h>
30#include <linux/sysfs.h> 28#include <linux/sysfs.h>
31#include <linux/hwmon-sysfs.h> 29#include <linux/hwmon-sysfs.h>
@@ -237,8 +235,7 @@ exit:
237 return err; 235 return err;
238} 236}
239 237
240#ifdef CONFIG_HOTPLUG_CPU 238static void __cpuinit via_cputemp_device_remove(unsigned int cpu)
241static void via_cputemp_device_remove(unsigned int cpu)
242{ 239{
243 struct pdev_entry *p, *n; 240 struct pdev_entry *p, *n;
244 mutex_lock(&pdev_list_mutex); 241 mutex_lock(&pdev_list_mutex);
@@ -272,7 +269,6 @@ static int __cpuinit via_cputemp_cpu_callback(struct notifier_block *nfb,
272static struct notifier_block via_cputemp_cpu_notifier __refdata = { 269static struct notifier_block via_cputemp_cpu_notifier __refdata = {
273 .notifier_call = via_cputemp_cpu_callback, 270 .notifier_call = via_cputemp_cpu_callback,
274}; 271};
275#endif /* !CONFIG_HOTPLUG_CPU */
276 272
277static int __init via_cputemp_init(void) 273static int __init via_cputemp_init(void)
278{ 274{
@@ -313,9 +309,7 @@ static int __init via_cputemp_init(void)
313 goto exit_driver_unreg; 309 goto exit_driver_unreg;
314 } 310 }
315 311
316#ifdef CONFIG_HOTPLUG_CPU
317 register_hotcpu_notifier(&via_cputemp_cpu_notifier); 312 register_hotcpu_notifier(&via_cputemp_cpu_notifier);
318#endif
319 return 0; 313 return 0;
320 314
321exit_devices_unreg: 315exit_devices_unreg:
@@ -335,9 +329,8 @@ exit:
335static void __exit via_cputemp_exit(void) 329static void __exit via_cputemp_exit(void)
336{ 330{
337 struct pdev_entry *p, *n; 331 struct pdev_entry *p, *n;
338#ifdef CONFIG_HOTPLUG_CPU 332
339 unregister_hotcpu_notifier(&via_cputemp_cpu_notifier); 333 unregister_hotcpu_notifier(&via_cputemp_cpu_notifier);
340#endif
341 mutex_lock(&pdev_list_mutex); 334 mutex_lock(&pdev_list_mutex);
342 list_for_each_entry_safe(p, n, &pdev_list, list) { 335 list_for_each_entry_safe(p, n, &pdev_list, list) {
343 platform_device_unregister(p->pdev); 336 platform_device_unregister(p->pdev);
diff --git a/include/linux/gpio-fan.h b/include/linux/gpio-fan.h
new file mode 100644
index 000000000000..096659169215
--- /dev/null
+++ b/include/linux/gpio-fan.h
@@ -0,0 +1,36 @@
1/*
2 * include/linux/gpio-fan.h
3 *
4 * Platform data structure for GPIO fan driver
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11#ifndef __LINUX_GPIO_FAN_H
12#define __LINUX_GPIO_FAN_H
13
14struct gpio_fan_alarm {
15 unsigned gpio;
16 unsigned active_low;
17};
18
19struct gpio_fan_speed {
20 int rpm;
21 int ctrl_val;
22};
23
24struct gpio_fan_platform_data {
25 int num_ctrl;
26 unsigned *ctrl; /* fan control GPIOs. */
27 struct gpio_fan_alarm *alarm; /* fan alarm GPIO. */
28 /*
29 * Speed conversion array: rpm from/to GPIO bit field.
30 * This array _must_ be sorted in ascending rpm order.
31 */
32 int num_speed;
33 struct gpio_fan_speed *speed;
34};
35
36#endif /* __LINUX_GPIO_FAN_H */
diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
index 0e8a346424bb..d4292c8431e0 100644
--- a/include/linux/lis3lv02d.h
+++ b/include/linux/lis3lv02d.h
@@ -1,6 +1,52 @@
1#ifndef __LIS3LV02D_H_ 1#ifndef __LIS3LV02D_H_
2#define __LIS3LV02D_H_ 2#define __LIS3LV02D_H_
3 3
4/**
5 * struct lis3lv02d_platform_data - lis3 chip family platform data
6 * @click_flags: Click detection unit configuration
7 * @click_thresh_x: Click detection unit x axis threshold
8 * @click_thresh_y: Click detection unit y axis threshold
9 * @click_thresh_z: Click detection unit z axis threshold
10 * @click_time_limit: Click detection unit time parameter
11 * @click_latency: Click detection unit latency parameter
12 * @click_window: Click detection unit window parameter
13 * @irq_cfg: On chip irq source and type configuration (click /
14 * data available / wake up, open drain, polarity)
15 * @irq_flags1: Additional irq triggering flags for irq channel 0
16 * @irq_flags2: Additional irq triggering flags for irq channel 1
17 * @duration1: Wake up unit 1 duration parameter
18 * @duration2: Wake up unit 2 duration parameter
19 * @wakeup_flags: Wake up unit 1 flags
20 * @wakeup_thresh: Wake up unit 1 threshold value
21 * @wakeup_flags2: Wake up unit 2 flags
22 * @wakeup_thresh2: Wake up unit 2 threshold value
23 * @hipass_ctrl: High pass filter control (enable / disable, cut off
24 * frequency)
25 * @axis_x: Sensor orientation remapping for x-axis
26 * @axis_y: Sensor orientation remapping for y-axis
27 * @axis_z: Sensor orientation remapping for z-axis
28 * @driver_features: Enable bits for different features. Disabled by default
29 * @default_rate: Default sampling rate. 0 means reset default
30 * @setup_resources: Interrupt line setup call back function
31 * @release_resources: Interrupt line release call back function
32 * @st_min_limits[3]: Selftest acceptance minimum values
33 * @st_max_limits[3]: Selftest acceptance maximum values
34 * @irq2: Irq line 2 number
35 *
36 * Platform data is used to setup the sensor chip. Meaning of the different
37 * chip features can be found from the data sheet. It is publicly available
38 * at www.st.com web pages. Currently the platform data is used
39 * only for the 8 bit device. The 8 bit device has two wake up / free fall
40 * detection units and click detection unit. There are plenty of ways to
41 * configure the chip which makes is quite hard to explain deeper meaning of
42 * the fields here. Behaviour of the detection blocks varies heavily depending
43 * on the configuration. For example, interrupt detection block can use high
44 * pass filtered data which makes it react to the changes in the acceleration.
45 * Irq_flags can be used to enable interrupt detection on the both edges.
46 * With proper chip configuration this produces interrupt when some trigger
47 * starts and when it goes away.
48 */
49
4struct lis3lv02d_platform_data { 50struct lis3lv02d_platform_data {
5 /* please note: the 'click' feature is only supported for 51 /* please note: the 'click' feature is only supported for
6 * LIS[32]02DL variants of the chip and will be ignored for 52 * LIS[32]02DL variants of the chip and will be ignored for
@@ -36,7 +82,10 @@ struct lis3lv02d_platform_data {
36#define LIS3_IRQ_OPEN_DRAIN (1 << 6) 82#define LIS3_IRQ_OPEN_DRAIN (1 << 6)
37#define LIS3_IRQ_ACTIVE_LOW (1 << 7) 83#define LIS3_IRQ_ACTIVE_LOW (1 << 7)
38 unsigned char irq_cfg; 84 unsigned char irq_cfg;
39 85 unsigned char irq_flags1; /* Additional irq edge / level flags */
86 unsigned char irq_flags2; /* Additional irq edge / level flags */
87 unsigned char duration1;
88 unsigned char duration2;
40#define LIS3_WAKEUP_X_LO (1 << 0) 89#define LIS3_WAKEUP_X_LO (1 << 0)
41#define LIS3_WAKEUP_X_HI (1 << 1) 90#define LIS3_WAKEUP_X_HI (1 << 1)
42#define LIS3_WAKEUP_Y_LO (1 << 2) 91#define LIS3_WAKEUP_Y_LO (1 << 2)
@@ -64,6 +113,10 @@ struct lis3lv02d_platform_data {
64 s8 axis_x; 113 s8 axis_x;
65 s8 axis_y; 114 s8 axis_y;
66 s8 axis_z; 115 s8 axis_z;
116#define LIS3_USE_REGULATOR_CTRL 0x01
117#define LIS3_USE_BLOCK_READ 0x02
118 u16 driver_features;
119 int default_rate;
67 int (*setup_resources)(void); 120 int (*setup_resources)(void);
68 int (*release_resources)(void); 121 int (*release_resources)(void);
69 /* Limits for selftest are specified in chip data sheet */ 122 /* Limits for selftest are specified in chip data sheet */