All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-22 11:57 ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Changes are tested only with I2C interface using 8bit sensor since I don't
have other possibilities. Some features are not enabled
by default since I can't test them with all possible configurations.
Platform data contains field which controls new features.

Description about the changes:

0001: pm_runtime support
Add support for pm_runtime framework for lis3 core driver and lis3-i2c
interface code. hp_accel and spi should not be affected by the changes.
When either input device or freefall device is opened, chip is powered up.
When a sysfs entry is accessed, chip is powered up and scheduled power down
is requested to happen within 5 seconds.

0002: regulator control
Regulator frame work support added. Regulators are controlled based on
pm_runtime state transitions. Chip register context is stored at power down
and restored at power up. Regulators are controlled only when I2C interface is
used since the implementation requires pm_runtime support.
Regulator control is disabled by default. It can be enabled via platform data.

0003: Cleanup interrupt handling
Interrupt control is cleaned up little bit. The need for threaded interrupt
is controlled by the input layer open / close function. In the interrupt,
only one check is needed instead of several one.
Platform information is copied to lis3_dev structure to shorten access
in interrupt code.
Interrupt handling for the WU blocks doesn't check interrupt source anymore.
It is not necessary since interrupt handler is called only when WU unit causes
an interrupt.

0004: Update coordinates at polled device open
It is possible to use input interface purely under threshold interrupt control
by setting polling interval to 0. In that case, it may take a long time
when coordinates are updated after the input device open. Applications can see
totally outdated information. Coordinates are now refreshed at the device open.

0005: Power on corrections
We have faced sometimes situation where lis3 powerup fails somehow. BOOT
bit is set at device init to force boot sequence. This way lis3 recovers
from the failed boot.

0006: restore axis enabled bits
Data ready interrupts are enabled at init (reset default value). They
have been removed if the module is unloaded and loaded back.

0007: New parameters to platform data
Add some missing parameters to 8bit chip platform data.
Chip interrupt generation features can now be controlled better.
Chip default sampling rate can be controlled via platform data.
It is also possible to configure interrupts at both rising and falling edges.
With some fancy interrupt configuration, this gives fresh coordinates
at the beginning and end of the acceleration event.

0008: Adjust fuzziness for 8 bit device
Set lower default fuzziness for 8bit device. Original value was from 12bit
device which is much more sensitive than the 8 bit device.

0009: use block read to access data registers
If enabled in platform data and supported by the I2C controller block
read is used for accessing the coordinate data.

0010: Enhance lis3 selftest with IRQ line test
Selftest is enhanced to test also IRQ lines in 8bit device.
This is done by enabling data_ready interrupt during selftest and
calculating number of received interrupts during the test.

0011: Short explanations of platform data fields 
Short explanations in kernel doc format

0012: Release resources is case of failure
I2C interface driver was not releasing HW resources if the probe failed.
That made re-attempt to always fail.

Samu Onkalo (12):
  hwmon: lis3: pm_runtime support
  hwmon: lis3: regulator control
  hwmon: lis3: Cleanup interrupt handling
  hwmon: lis3: Update coordinates at polled device open
  hwmon: lis3: Power on corrections
  hwmon: lis3: restore axis enabled bits
  hwmon: lis3: New parameters to platform data
  hwmon: lis3: Adjust fuzziness for 8 bit device
  hwmon: lis3: use block read to access data registers
  hwmon: lis3: Enhance lis3 selftest with IRQ line test
  hwmon: lis3: Short explanations of platform data fields
  hwmon: lis3: Release resources is case of failure

 drivers/hwmon/lis3lv02d.c     |  304 ++++++++++++++++++++++++++++++++++------
 drivers/hwmon/lis3lv02d.h     |   18 +++
 drivers/hwmon/lis3lv02d_i2c.c |  127 +++++++++++++++--
 drivers/hwmon/lis3lv02d_spi.c |    2 +-
 include/linux/lis3lv02d.h     |   50 +++++++-
 5 files changed, 439 insertions(+), 62 deletions(-)


^ permalink raw reply	[flat|nested] 101+ messages in thread

* [lm-sensors] [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-22 11:57 ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Changes are tested only with I2C interface using 8bit sensor since I don't
have other possibilities. Some features are not enabled
by default since I can't test them with all possible configurations.
Platform data contains field which controls new features.

Description about the changes:

0001: pm_runtime support
Add support for pm_runtime framework for lis3 core driver and lis3-i2c
interface code. hp_accel and spi should not be affected by the changes.
When either input device or freefall device is opened, chip is powered up.
When a sysfs entry is accessed, chip is powered up and scheduled power down
is requested to happen within 5 seconds.

0002: regulator control
Regulator frame work support added. Regulators are controlled based on
pm_runtime state transitions. Chip register context is stored at power down
and restored at power up. Regulators are controlled only when I2C interface is
used since the implementation requires pm_runtime support.
Regulator control is disabled by default. It can be enabled via platform data.

0003: Cleanup interrupt handling
Interrupt control is cleaned up little bit. The need for threaded interrupt
is controlled by the input layer open / close function. In the interrupt,
only one check is needed instead of several one.
Platform information is copied to lis3_dev structure to shorten access
in interrupt code.
Interrupt handling for the WU blocks doesn't check interrupt source anymore.
It is not necessary since interrupt handler is called only when WU unit causes
an interrupt.

0004: Update coordinates at polled device open
It is possible to use input interface purely under threshold interrupt control
by setting polling interval to 0. In that case, it may take a long time
when coordinates are updated after the input device open. Applications can see
totally outdated information. Coordinates are now refreshed at the device open.

0005: Power on corrections
We have faced sometimes situation where lis3 powerup fails somehow. BOOT
bit is set at device init to force boot sequence. This way lis3 recovers
from the failed boot.

0006: restore axis enabled bits
Data ready interrupts are enabled at init (reset default value). They
have been removed if the module is unloaded and loaded back.

0007: New parameters to platform data
Add some missing parameters to 8bit chip platform data.
Chip interrupt generation features can now be controlled better.
Chip default sampling rate can be controlled via platform data.
It is also possible to configure interrupts at both rising and falling edges.
With some fancy interrupt configuration, this gives fresh coordinates
at the beginning and end of the acceleration event.

0008: Adjust fuzziness for 8 bit device
Set lower default fuzziness for 8bit device. Original value was from 12bit
device which is much more sensitive than the 8 bit device.

0009: use block read to access data registers
If enabled in platform data and supported by the I2C controller block
read is used for accessing the coordinate data.

0010: Enhance lis3 selftest with IRQ line test
Selftest is enhanced to test also IRQ lines in 8bit device.
This is done by enabling data_ready interrupt during selftest and
calculating number of received interrupts during the test.

0011: Short explanations of platform data fields 
Short explanations in kernel doc format

0012: Release resources is case of failure
I2C interface driver was not releasing HW resources if the probe failed.
That made re-attempt to always fail.

Samu Onkalo (12):
  hwmon: lis3: pm_runtime support
  hwmon: lis3: regulator control
  hwmon: lis3: Cleanup interrupt handling
  hwmon: lis3: Update coordinates at polled device open
  hwmon: lis3: Power on corrections
  hwmon: lis3: restore axis enabled bits
  hwmon: lis3: New parameters to platform data
  hwmon: lis3: Adjust fuzziness for 8 bit device
  hwmon: lis3: use block read to access data registers
  hwmon: lis3: Enhance lis3 selftest with IRQ line test
  hwmon: lis3: Short explanations of platform data fields
  hwmon: lis3: Release resources is case of failure

 drivers/hwmon/lis3lv02d.c     |  304 ++++++++++++++++++++++++++++++++++------
 drivers/hwmon/lis3lv02d.h     |   18 +++
 drivers/hwmon/lis3lv02d_i2c.c |  127 +++++++++++++++--
 drivers/hwmon/lis3lv02d_spi.c |    2 +-
 include/linux/lis3lv02d.h     |   50 +++++++-
 5 files changed, 439 insertions(+), 62 deletions(-)


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCH 01/12] hwmon: lis3: pm_runtime support
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Add pm_runtime support to lis3 core driver.
Add pm_runtime support to lis3 i2c driver.

spi and hp_accel drivers are not yet supported. Old always
on functionality remains for those.

For sysfs there is 5 second delay before turning off the
chip to avoid long ramp up delay.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d.c     |   60 +++++++++++++++++++++++++++++++++++++++++
 drivers/hwmon/lis3lv02d.h     |    1 +
 drivers/hwmon/lis3lv02d_i2c.c |   54 ++++++++++++++++++++++++++++---------
 3 files changed, 102 insertions(+), 13 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index fc591ae..412ddc3 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -34,6 +34,7 @@
 #include <linux/freezer.h>
 #include <linux/uaccess.h>
 #include <linux/miscdevice.h>
+#include <linux/pm_runtime.h>
 #include <asm/atomic.h>
 #include "lis3lv02d.h"
 
@@ -43,6 +44,9 @@
 #define MDPS_POLL_INTERVAL 50
 #define MDPS_POLL_MIN	   0
 #define MDPS_POLL_MAX	   2000
+
+#define LIS3_SYSFS_POWERDOWN_DELAY 5000 /* In milliseconds */
+
 /*
  * The sensor can also generate interrupts (DRDY) but it's pretty pointless
  * because they are generated even if the data do not change. So it's better
@@ -262,6 +266,18 @@ static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev)
 	mutex_unlock(&lis3_dev.mutex);
 }
 
+static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
+{
+	if (lis3_dev.pm_dev)
+		pm_runtime_get_sync(lis3_dev.pm_dev);
+}
+
+static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
+{
+	if (lis3_dev.pm_dev)
+		pm_runtime_put(lis3_dev.pm_dev);
+}
+
 static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
 {
 	if (!test_bit(0, &lis3_dev.misc_opened))
@@ -356,6 +372,9 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
 	if (test_and_set_bit(0, &lis3_dev.misc_opened))
 		return -EBUSY; /* already open */
 
+	if (lis3_dev.pm_dev)
+		pm_runtime_get_sync(lis3_dev.pm_dev);
+
 	atomic_set(&lis3_dev.count, 0);
 	return 0;
 }
@@ -364,6 +383,8 @@ static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
 {
 	fasync_helper(-1, file, 0, &lis3_dev.async_queue);
 	clear_bit(0, &lis3_dev.misc_opened); /* release the device */
+	if (lis3_dev.pm_dev)
+		pm_runtime_put(lis3_dev.pm_dev);
 	return 0;
 }
 
@@ -460,6 +481,8 @@ int lis3lv02d_joystick_enable(void)
 		return -ENOMEM;
 
 	lis3_dev.idev->poll = lis3lv02d_joystick_poll;
+	lis3_dev.idev->open = lis3lv02d_joystick_open;
+	lis3_dev.idev->close = lis3lv02d_joystick_close;
 	lis3_dev.idev->poll_interval = MDPS_POLL_INTERVAL;
 	lis3_dev.idev->poll_interval_min = MDPS_POLL_MIN;
 	lis3_dev.idev->poll_interval_max = MDPS_POLL_MAX;
@@ -512,12 +535,30 @@ void lis3lv02d_joystick_disable(void)
 EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable);
 
 /* Sysfs stuff */
+static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3)
+{
+	/*
+	 * SYSFS functions are fast visitors so put-call
+	 * immediately after the get-call. However, keep
+	 * chip running for a while and schedule delayed
+	 * suspend. This way periodic sysfs calls doesn't
+	 * suffer from relatively long power up time.
+	 */
+
+	if (lis3->pm_dev) {
+		pm_runtime_get_sync(lis3->pm_dev);
+		pm_runtime_put_noidle(lis3->pm_dev);
+		pm_schedule_suspend(lis3->pm_dev, LIS3_SYSFS_POWERDOWN_DELAY);
+	}
+}
+
 static ssize_t lis3lv02d_selftest_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
 	int result;
 	s16 values[3];
 
+	lis3lv02d_sysfs_poweron(&lis3_dev);
 	result = lis3lv02d_selftest(&lis3_dev, values);
 	return sprintf(buf, "%s %d %d %d\n", result == 0 ? "OK" : "FAIL",
 		values[0], values[1], values[2]);
@@ -528,6 +569,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
 {
 	int x, y, z;
 
+	lis3lv02d_sysfs_poweron(&lis3_dev);
 	mutex_lock(&lis3_dev.mutex);
 	lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
 	mutex_unlock(&lis3_dev.mutex);
@@ -537,6 +579,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
 static ssize_t lis3lv02d_rate_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
+	lis3lv02d_sysfs_poweron(&lis3_dev);
 	return sprintf(buf, "%d\n", lis3lv02d_get_odr());
 }
 
@@ -549,6 +592,7 @@ static ssize_t lis3lv02d_rate_set(struct device *dev,
 	if (strict_strtoul(buf, 0, &rate))
 		return -EINVAL;
 
+	lis3lv02d_sysfs_poweron(&lis3_dev);
 	if (lis3lv02d_set_odr(rate))
 		return -EINVAL;
 
@@ -585,6 +629,17 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
 {
 	sysfs_remove_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group);
 	platform_device_unregister(lis3->pdev);
+	if (lis3->pm_dev) {
+		/* Barrier after the sysfs remove */
+		pm_runtime_barrier(lis3->pm_dev);
+
+		/* SYSFS may have left chip running. Turn off if necessary */
+		if (!pm_runtime_suspended(lis3->pm_dev))
+			lis3lv02d_poweroff(&lis3_dev);
+
+		pm_runtime_disable(lis3->pm_dev);
+		pm_runtime_set_suspended(lis3->pm_dev);
+	}
 	return 0;
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
@@ -685,6 +740,11 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 	lis3lv02d_add_fs(dev);
 	lis3lv02d_poweron(dev);
 
+	if (dev->pm_dev) {
+		pm_runtime_set_active(dev->pm_dev);
+		pm_runtime_enable(dev->pm_dev);
+	}
+
 	if (lis3lv02d_joystick_enable())
 		printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
 
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 8540913..3e8a208 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -214,6 +214,7 @@ struct axis_conversion {
 
 struct lis3lv02d {
 	void			*bus_priv; /* used by the bus layer only */
+	struct device		*pm_dev; /* for pm_runtime purposes */
 	int (*init) (struct lis3lv02d *lis3);
 	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
 	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index 8e5933b..6e965d7 100644
--- a/drivers/hwmon/lis3lv02d_i2c.c
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -29,6 +29,7 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/i2c.h>
+#include <linux/pm_runtime.h>
 #include "lis3lv02d.h"
 
 #define DRV_NAME 	"lis3lv02d_i2c"
@@ -95,6 +96,7 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
 	lis3_dev.write	  = lis3_i2c_write;
 	lis3_dev.irq	  = client->irq;
 	lis3_dev.ac	  = lis3lv02d_axis_map;
+	lis3_dev.pm_dev	  = &client->dev;
 
 	i2c_set_clientdata(client, &lis3_dev);
 	ret = lis3lv02d_init_device(&lis3_dev);
@@ -104,21 +106,20 @@ fail:
 
 static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
 {
-	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
 	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
 
 	if (pdata && pdata->release_resources)
 		pdata->release_resources();
 
 	lis3lv02d_joystick_disable();
-	lis3lv02d_poweroff(lis3);
 
 	return lis3lv02d_remove_fs(&lis3_dev);
 }
 
 #ifdef CONFIG_PM
-static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
+static int lis3lv02d_i2c_suspend(struct device *dev)
 {
+	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
 	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
 
 	if (!lis3->pdata || !lis3->pdata->wakeup_flags)
@@ -126,18 +127,21 @@ static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
 	return 0;
 }
 
-static int lis3lv02d_i2c_resume(struct i2c_client *client)
+static int lis3lv02d_i2c_resume(struct device *dev)
 {
+	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
 	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
 
-	if (!lis3->pdata || !lis3->pdata->wakeup_flags)
+	/*
+	 * pm_runtime documentation says that devices should always
+	 * be powered on at resume. Pm_runtime turns them off after system
+	 * wide resume is complete.
+	 */
+	if (!lis3->pdata || !lis3->pdata->wakeup_flags ||
+		pm_runtime_suspended(dev))
 		lis3lv02d_poweron(lis3);
-	return 0;
-}
 
-static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
-{
-	lis3lv02d_i2c_suspend(client, PMSG_SUSPEND);
+	return 0;
 }
 #else
 #define lis3lv02d_i2c_suspend	NULL
@@ -145,6 +149,24 @@ static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
 #define lis3lv02d_i2c_shutdown	NULL
 #endif
 
+static int lis3_i2c_runtime_suspend(struct device *dev)
+{
+	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
+
+	lis3lv02d_poweroff(lis3);
+	return 0;
+}
+
+static int lis3_i2c_runtime_resume(struct device *dev)
+{
+	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
+
+	lis3lv02d_poweron(lis3);
+	return 0;
+}
+
 static const struct i2c_device_id lis3lv02d_id[] = {
 	{"lis3lv02d", 0 },
 	{}
@@ -152,14 +174,20 @@ static const struct i2c_device_id lis3lv02d_id[] = {
 
 MODULE_DEVICE_TABLE(i2c, lis3lv02d_id);
 
+static const struct dev_pm_ops lis3_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(lis3lv02d_i2c_suspend,
+				lis3lv02d_i2c_resume)
+	SET_RUNTIME_PM_OPS(lis3_i2c_runtime_suspend,
+			   lis3_i2c_runtime_resume,
+			   NULL)
+};
+
 static struct i2c_driver lis3lv02d_i2c_driver = {
 	.driver	 = {
 		.name   = DRV_NAME,
 		.owner  = THIS_MODULE,
+		.pm     = &lis3_pm_ops,
 	},
-	.suspend = lis3lv02d_i2c_suspend,
-	.shutdown = lis3lv02d_i2c_shutdown,
-	.resume = lis3lv02d_i2c_resume,
 	.probe	= lis3lv02d_i2c_probe,
 	.remove	= __devexit_p(lis3lv02d_i2c_remove),
 	.id_table = lis3lv02d_id,
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH 01/12] hwmon: lis3: pm_runtime support
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel-VkQ1JFuSMpfAbQlEx87xDw, khali-PUYAD+kWke1g9hUCZPvPmw,
	guenter.roeck-IzeFyvvaP7pWk0Htik3J/w,
	jic23-KWPb1pKIrIJaa/9Udqfwiw
  Cc: lm-sensors-GZX6beZjE8VD60Wz+7aTrA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Add pm_runtime support to lis3 core driver.
Add pm_runtime support to lis3 i2c driver.

spi and hp_accel drivers are not yet supported. Old always
on functionality remains for those.

For sysfs there is 5 second delay before turning off the
chip to avoid long ramp up delay.

Signed-off-by: Samu Onkalo <samu.p.onkalo-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
---
 drivers/hwmon/lis3lv02d.c     |   60 +++++++++++++++++++++++++++++++++++++++++
 drivers/hwmon/lis3lv02d.h     |    1 +
 drivers/hwmon/lis3lv02d_i2c.c |   54 ++++++++++++++++++++++++++++---------
 3 files changed, 102 insertions(+), 13 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index fc591ae..412ddc3 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -34,6 +34,7 @@
 #include <linux/freezer.h>
 #include <linux/uaccess.h>
 #include <linux/miscdevice.h>
+#include <linux/pm_runtime.h>
 #include <asm/atomic.h>
 #include "lis3lv02d.h"
 
@@ -43,6 +44,9 @@
 #define MDPS_POLL_INTERVAL 50
 #define MDPS_POLL_MIN	   0
 #define MDPS_POLL_MAX	   2000
+
+#define LIS3_SYSFS_POWERDOWN_DELAY 5000 /* In milliseconds */
+
 /*
  * The sensor can also generate interrupts (DRDY) but it's pretty pointless
  * because they are generated even if the data do not change. So it's better
@@ -262,6 +266,18 @@ static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev)
 	mutex_unlock(&lis3_dev.mutex);
 }
 
+static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
+{
+	if (lis3_dev.pm_dev)
+		pm_runtime_get_sync(lis3_dev.pm_dev);
+}
+
+static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
+{
+	if (lis3_dev.pm_dev)
+		pm_runtime_put(lis3_dev.pm_dev);
+}
+
 static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
 {
 	if (!test_bit(0, &lis3_dev.misc_opened))
@@ -356,6 +372,9 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
 	if (test_and_set_bit(0, &lis3_dev.misc_opened))
 		return -EBUSY; /* already open */
 
+	if (lis3_dev.pm_dev)
+		pm_runtime_get_sync(lis3_dev.pm_dev);
+
 	atomic_set(&lis3_dev.count, 0);
 	return 0;
 }
@@ -364,6 +383,8 @@ static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
 {
 	fasync_helper(-1, file, 0, &lis3_dev.async_queue);
 	clear_bit(0, &lis3_dev.misc_opened); /* release the device */
+	if (lis3_dev.pm_dev)
+		pm_runtime_put(lis3_dev.pm_dev);
 	return 0;
 }
 
@@ -460,6 +481,8 @@ int lis3lv02d_joystick_enable(void)
 		return -ENOMEM;
 
 	lis3_dev.idev->poll = lis3lv02d_joystick_poll;
+	lis3_dev.idev->open = lis3lv02d_joystick_open;
+	lis3_dev.idev->close = lis3lv02d_joystick_close;
 	lis3_dev.idev->poll_interval = MDPS_POLL_INTERVAL;
 	lis3_dev.idev->poll_interval_min = MDPS_POLL_MIN;
 	lis3_dev.idev->poll_interval_max = MDPS_POLL_MAX;
@@ -512,12 +535,30 @@ void lis3lv02d_joystick_disable(void)
 EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable);
 
 /* Sysfs stuff */
+static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3)
+{
+	/*
+	 * SYSFS functions are fast visitors so put-call
+	 * immediately after the get-call. However, keep
+	 * chip running for a while and schedule delayed
+	 * suspend. This way periodic sysfs calls doesn't
+	 * suffer from relatively long power up time.
+	 */
+
+	if (lis3->pm_dev) {
+		pm_runtime_get_sync(lis3->pm_dev);
+		pm_runtime_put_noidle(lis3->pm_dev);
+		pm_schedule_suspend(lis3->pm_dev, LIS3_SYSFS_POWERDOWN_DELAY);
+	}
+}
+
 static ssize_t lis3lv02d_selftest_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
 	int result;
 	s16 values[3];
 
+	lis3lv02d_sysfs_poweron(&lis3_dev);
 	result = lis3lv02d_selftest(&lis3_dev, values);
 	return sprintf(buf, "%s %d %d %d\n", result == 0 ? "OK" : "FAIL",
 		values[0], values[1], values[2]);
@@ -528,6 +569,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
 {
 	int x, y, z;
 
+	lis3lv02d_sysfs_poweron(&lis3_dev);
 	mutex_lock(&lis3_dev.mutex);
 	lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
 	mutex_unlock(&lis3_dev.mutex);
@@ -537,6 +579,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
 static ssize_t lis3lv02d_rate_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
+	lis3lv02d_sysfs_poweron(&lis3_dev);
 	return sprintf(buf, "%d\n", lis3lv02d_get_odr());
 }
 
@@ -549,6 +592,7 @@ static ssize_t lis3lv02d_rate_set(struct device *dev,
 	if (strict_strtoul(buf, 0, &rate))
 		return -EINVAL;
 
+	lis3lv02d_sysfs_poweron(&lis3_dev);
 	if (lis3lv02d_set_odr(rate))
 		return -EINVAL;
 
@@ -585,6 +629,17 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
 {
 	sysfs_remove_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group);
 	platform_device_unregister(lis3->pdev);
+	if (lis3->pm_dev) {
+		/* Barrier after the sysfs remove */
+		pm_runtime_barrier(lis3->pm_dev);
+
+		/* SYSFS may have left chip running. Turn off if necessary */
+		if (!pm_runtime_suspended(lis3->pm_dev))
+			lis3lv02d_poweroff(&lis3_dev);
+
+		pm_runtime_disable(lis3->pm_dev);
+		pm_runtime_set_suspended(lis3->pm_dev);
+	}
 	return 0;
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
@@ -685,6 +740,11 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 	lis3lv02d_add_fs(dev);
 	lis3lv02d_poweron(dev);
 
+	if (dev->pm_dev) {
+		pm_runtime_set_active(dev->pm_dev);
+		pm_runtime_enable(dev->pm_dev);
+	}
+
 	if (lis3lv02d_joystick_enable())
 		printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
 
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 8540913..3e8a208 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -214,6 +214,7 @@ struct axis_conversion {
 
 struct lis3lv02d {
 	void			*bus_priv; /* used by the bus layer only */
+	struct device		*pm_dev; /* for pm_runtime purposes */
 	int (*init) (struct lis3lv02d *lis3);
 	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
 	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index 8e5933b..6e965d7 100644
--- a/drivers/hwmon/lis3lv02d_i2c.c
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -29,6 +29,7 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/i2c.h>
+#include <linux/pm_runtime.h>
 #include "lis3lv02d.h"
 
 #define DRV_NAME 	"lis3lv02d_i2c"
@@ -95,6 +96,7 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
 	lis3_dev.write	  = lis3_i2c_write;
 	lis3_dev.irq	  = client->irq;
 	lis3_dev.ac	  = lis3lv02d_axis_map;
+	lis3_dev.pm_dev	  = &client->dev;
 
 	i2c_set_clientdata(client, &lis3_dev);
 	ret = lis3lv02d_init_device(&lis3_dev);
@@ -104,21 +106,20 @@ fail:
 
 static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
 {
-	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
 	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
 
 	if (pdata && pdata->release_resources)
 		pdata->release_resources();
 
 	lis3lv02d_joystick_disable();
-	lis3lv02d_poweroff(lis3);
 
 	return lis3lv02d_remove_fs(&lis3_dev);
 }
 
 #ifdef CONFIG_PM
-static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
+static int lis3lv02d_i2c_suspend(struct device *dev)
 {
+	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
 	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
 
 	if (!lis3->pdata || !lis3->pdata->wakeup_flags)
@@ -126,18 +127,21 @@ static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
 	return 0;
 }
 
-static int lis3lv02d_i2c_resume(struct i2c_client *client)
+static int lis3lv02d_i2c_resume(struct device *dev)
 {
+	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
 	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
 
-	if (!lis3->pdata || !lis3->pdata->wakeup_flags)
+	/*
+	 * pm_runtime documentation says that devices should always
+	 * be powered on at resume. Pm_runtime turns them off after system
+	 * wide resume is complete.
+	 */
+	if (!lis3->pdata || !lis3->pdata->wakeup_flags ||
+		pm_runtime_suspended(dev))
 		lis3lv02d_poweron(lis3);
-	return 0;
-}
 
-static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
-{
-	lis3lv02d_i2c_suspend(client, PMSG_SUSPEND);
+	return 0;
 }
 #else
 #define lis3lv02d_i2c_suspend	NULL
@@ -145,6 +149,24 @@ static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
 #define lis3lv02d_i2c_shutdown	NULL
 #endif
 
+static int lis3_i2c_runtime_suspend(struct device *dev)
+{
+	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
+
+	lis3lv02d_poweroff(lis3);
+	return 0;
+}
+
+static int lis3_i2c_runtime_resume(struct device *dev)
+{
+	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
+
+	lis3lv02d_poweron(lis3);
+	return 0;
+}
+
 static const struct i2c_device_id lis3lv02d_id[] = {
 	{"lis3lv02d", 0 },
 	{}
@@ -152,14 +174,20 @@ static const struct i2c_device_id lis3lv02d_id[] = {
 
 MODULE_DEVICE_TABLE(i2c, lis3lv02d_id);
 
+static const struct dev_pm_ops lis3_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(lis3lv02d_i2c_suspend,
+				lis3lv02d_i2c_resume)
+	SET_RUNTIME_PM_OPS(lis3_i2c_runtime_suspend,
+			   lis3_i2c_runtime_resume,
+			   NULL)
+};
+
 static struct i2c_driver lis3lv02d_i2c_driver = {
 	.driver	 = {
 		.name   = DRV_NAME,
 		.owner  = THIS_MODULE,
+		.pm     = &lis3_pm_ops,
 	},
-	.suspend = lis3lv02d_i2c_suspend,
-	.shutdown = lis3lv02d_i2c_shutdown,
-	.resume = lis3lv02d_i2c_resume,
 	.probe	= lis3lv02d_i2c_probe,
 	.remove	= __devexit_p(lis3lv02d_i2c_remove),
 	.id_table = lis3lv02d_id,
-- 
1.6.0.4

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [lm-sensors] [PATCH 01/12] hwmon: lis3: pm_runtime support
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Add pm_runtime support to lis3 core driver.
Add pm_runtime support to lis3 i2c driver.

spi and hp_accel drivers are not yet supported. Old always
on functionality remains for those.

For sysfs there is 5 second delay before turning off the
chip to avoid long ramp up delay.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d.c     |   60 +++++++++++++++++++++++++++++++++++++++++
 drivers/hwmon/lis3lv02d.h     |    1 +
 drivers/hwmon/lis3lv02d_i2c.c |   54 ++++++++++++++++++++++++++++---------
 3 files changed, 102 insertions(+), 13 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index fc591ae..412ddc3 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -34,6 +34,7 @@
 #include <linux/freezer.h>
 #include <linux/uaccess.h>
 #include <linux/miscdevice.h>
+#include <linux/pm_runtime.h>
 #include <asm/atomic.h>
 #include "lis3lv02d.h"
 
@@ -43,6 +44,9 @@
 #define MDPS_POLL_INTERVAL 50
 #define MDPS_POLL_MIN	   0
 #define MDPS_POLL_MAX	   2000
+
+#define LIS3_SYSFS_POWERDOWN_DELAY 5000 /* In milliseconds */
+
 /*
  * The sensor can also generate interrupts (DRDY) but it's pretty pointless
  * because they are generated even if the data do not change. So it's better
@@ -262,6 +266,18 @@ static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev)
 	mutex_unlock(&lis3_dev.mutex);
 }
 
+static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
+{
+	if (lis3_dev.pm_dev)
+		pm_runtime_get_sync(lis3_dev.pm_dev);
+}
+
+static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
+{
+	if (lis3_dev.pm_dev)
+		pm_runtime_put(lis3_dev.pm_dev);
+}
+
 static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
 {
 	if (!test_bit(0, &lis3_dev.misc_opened))
@@ -356,6 +372,9 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
 	if (test_and_set_bit(0, &lis3_dev.misc_opened))
 		return -EBUSY; /* already open */
 
+	if (lis3_dev.pm_dev)
+		pm_runtime_get_sync(lis3_dev.pm_dev);
+
 	atomic_set(&lis3_dev.count, 0);
 	return 0;
 }
@@ -364,6 +383,8 @@ static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
 {
 	fasync_helper(-1, file, 0, &lis3_dev.async_queue);
 	clear_bit(0, &lis3_dev.misc_opened); /* release the device */
+	if (lis3_dev.pm_dev)
+		pm_runtime_put(lis3_dev.pm_dev);
 	return 0;
 }
 
@@ -460,6 +481,8 @@ int lis3lv02d_joystick_enable(void)
 		return -ENOMEM;
 
 	lis3_dev.idev->poll = lis3lv02d_joystick_poll;
+	lis3_dev.idev->open = lis3lv02d_joystick_open;
+	lis3_dev.idev->close = lis3lv02d_joystick_close;
 	lis3_dev.idev->poll_interval = MDPS_POLL_INTERVAL;
 	lis3_dev.idev->poll_interval_min = MDPS_POLL_MIN;
 	lis3_dev.idev->poll_interval_max = MDPS_POLL_MAX;
@@ -512,12 +535,30 @@ void lis3lv02d_joystick_disable(void)
 EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable);
 
 /* Sysfs stuff */
+static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3)
+{
+	/*
+	 * SYSFS functions are fast visitors so put-call
+	 * immediately after the get-call. However, keep
+	 * chip running for a while and schedule delayed
+	 * suspend. This way periodic sysfs calls doesn't
+	 * suffer from relatively long power up time.
+	 */
+
+	if (lis3->pm_dev) {
+		pm_runtime_get_sync(lis3->pm_dev);
+		pm_runtime_put_noidle(lis3->pm_dev);
+		pm_schedule_suspend(lis3->pm_dev, LIS3_SYSFS_POWERDOWN_DELAY);
+	}
+}
+
 static ssize_t lis3lv02d_selftest_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
 	int result;
 	s16 values[3];
 
+	lis3lv02d_sysfs_poweron(&lis3_dev);
 	result = lis3lv02d_selftest(&lis3_dev, values);
 	return sprintf(buf, "%s %d %d %d\n", result = 0 ? "OK" : "FAIL",
 		values[0], values[1], values[2]);
@@ -528,6 +569,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
 {
 	int x, y, z;
 
+	lis3lv02d_sysfs_poweron(&lis3_dev);
 	mutex_lock(&lis3_dev.mutex);
 	lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
 	mutex_unlock(&lis3_dev.mutex);
@@ -537,6 +579,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
 static ssize_t lis3lv02d_rate_show(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
+	lis3lv02d_sysfs_poweron(&lis3_dev);
 	return sprintf(buf, "%d\n", lis3lv02d_get_odr());
 }
 
@@ -549,6 +592,7 @@ static ssize_t lis3lv02d_rate_set(struct device *dev,
 	if (strict_strtoul(buf, 0, &rate))
 		return -EINVAL;
 
+	lis3lv02d_sysfs_poweron(&lis3_dev);
 	if (lis3lv02d_set_odr(rate))
 		return -EINVAL;
 
@@ -585,6 +629,17 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
 {
 	sysfs_remove_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group);
 	platform_device_unregister(lis3->pdev);
+	if (lis3->pm_dev) {
+		/* Barrier after the sysfs remove */
+		pm_runtime_barrier(lis3->pm_dev);
+
+		/* SYSFS may have left chip running. Turn off if necessary */
+		if (!pm_runtime_suspended(lis3->pm_dev))
+			lis3lv02d_poweroff(&lis3_dev);
+
+		pm_runtime_disable(lis3->pm_dev);
+		pm_runtime_set_suspended(lis3->pm_dev);
+	}
 	return 0;
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
@@ -685,6 +740,11 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 	lis3lv02d_add_fs(dev);
 	lis3lv02d_poweron(dev);
 
+	if (dev->pm_dev) {
+		pm_runtime_set_active(dev->pm_dev);
+		pm_runtime_enable(dev->pm_dev);
+	}
+
 	if (lis3lv02d_joystick_enable())
 		printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
 
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 8540913..3e8a208 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -214,6 +214,7 @@ struct axis_conversion {
 
 struct lis3lv02d {
 	void			*bus_priv; /* used by the bus layer only */
+	struct device		*pm_dev; /* for pm_runtime purposes */
 	int (*init) (struct lis3lv02d *lis3);
 	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
 	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index 8e5933b..6e965d7 100644
--- a/drivers/hwmon/lis3lv02d_i2c.c
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -29,6 +29,7 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/i2c.h>
+#include <linux/pm_runtime.h>
 #include "lis3lv02d.h"
 
 #define DRV_NAME 	"lis3lv02d_i2c"
@@ -95,6 +96,7 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
 	lis3_dev.write	  = lis3_i2c_write;
 	lis3_dev.irq	  = client->irq;
 	lis3_dev.ac	  = lis3lv02d_axis_map;
+	lis3_dev.pm_dev	  = &client->dev;
 
 	i2c_set_clientdata(client, &lis3_dev);
 	ret = lis3lv02d_init_device(&lis3_dev);
@@ -104,21 +106,20 @@ fail:
 
 static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
 {
-	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
 	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
 
 	if (pdata && pdata->release_resources)
 		pdata->release_resources();
 
 	lis3lv02d_joystick_disable();
-	lis3lv02d_poweroff(lis3);
 
 	return lis3lv02d_remove_fs(&lis3_dev);
 }
 
 #ifdef CONFIG_PM
-static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
+static int lis3lv02d_i2c_suspend(struct device *dev)
 {
+	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
 	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
 
 	if (!lis3->pdata || !lis3->pdata->wakeup_flags)
@@ -126,18 +127,21 @@ static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
 	return 0;
 }
 
-static int lis3lv02d_i2c_resume(struct i2c_client *client)
+static int lis3lv02d_i2c_resume(struct device *dev)
 {
+	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
 	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
 
-	if (!lis3->pdata || !lis3->pdata->wakeup_flags)
+	/*
+	 * pm_runtime documentation says that devices should always
+	 * be powered on at resume. Pm_runtime turns them off after system
+	 * wide resume is complete.
+	 */
+	if (!lis3->pdata || !lis3->pdata->wakeup_flags ||
+		pm_runtime_suspended(dev))
 		lis3lv02d_poweron(lis3);
-	return 0;
-}
 
-static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
-{
-	lis3lv02d_i2c_suspend(client, PMSG_SUSPEND);
+	return 0;
 }
 #else
 #define lis3lv02d_i2c_suspend	NULL
@@ -145,6 +149,24 @@ static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
 #define lis3lv02d_i2c_shutdown	NULL
 #endif
 
+static int lis3_i2c_runtime_suspend(struct device *dev)
+{
+	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
+
+	lis3lv02d_poweroff(lis3);
+	return 0;
+}
+
+static int lis3_i2c_runtime_resume(struct device *dev)
+{
+	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
+
+	lis3lv02d_poweron(lis3);
+	return 0;
+}
+
 static const struct i2c_device_id lis3lv02d_id[] = {
 	{"lis3lv02d", 0 },
 	{}
@@ -152,14 +174,20 @@ static const struct i2c_device_id lis3lv02d_id[] = {
 
 MODULE_DEVICE_TABLE(i2c, lis3lv02d_id);
 
+static const struct dev_pm_ops lis3_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(lis3lv02d_i2c_suspend,
+				lis3lv02d_i2c_resume)
+	SET_RUNTIME_PM_OPS(lis3_i2c_runtime_suspend,
+			   lis3_i2c_runtime_resume,
+			   NULL)
+};
+
 static struct i2c_driver lis3lv02d_i2c_driver = {
 	.driver	 = {
 		.name   = DRV_NAME,
 		.owner  = THIS_MODULE,
+		.pm     = &lis3_pm_ops,
 	},
-	.suspend = lis3lv02d_i2c_suspend,
-	.shutdown = lis3lv02d_i2c_shutdown,
-	.resume = lis3lv02d_i2c_resume,
 	.probe	= lis3lv02d_i2c_probe,
 	.remove	= __devexit_p(lis3lv02d_i2c_remove),
 	.id_table = lis3lv02d_id,
-- 
1.6.0.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH 02/12] hwmon: lis3: regulator control
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Based on pm_runtime control, turn lis3 regulators on and off.
Perform context save and restore on transitions.

Feature is optional and must be enabled in platform data.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d.c     |   52 ++++++++++++++++++++++++++++++++++++++
 drivers/hwmon/lis3lv02d.h     |   12 +++++++++
 drivers/hwmon/lis3lv02d_i2c.c |   55 ++++++++++++++++++++++++++++++++++++++++-
 include/linux/lis3lv02d.h     |    2 +
 4 files changed, 120 insertions(+), 1 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index 412ddc3..ade6f3a 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -31,6 +31,7 @@
 #include <linux/delay.h>
 #include <linux/wait.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <linux/freezer.h>
 #include <linux/uaccess.h>
 #include <linux/miscdevice.h>
@@ -223,10 +224,46 @@ fail:
 	return ret;
 }
 
+/*
+ * Order of registers in the list affects to order of the restore process.
+ * Perhaps it is a good idea to set interrupt enable register as a last one
+ * after all other configurations
+ */
+static u8 lis3_wai8_regs[] = { FF_WU_CFG_1, FF_WU_THS_1, FF_WU_DURATION_1,
+			       FF_WU_CFG_2, FF_WU_THS_2, FF_WU_DURATION_2,
+			       CLICK_CFG, CLICK_SRC, CLICK_THSY_X, CLICK_THSZ,
+			       CLICK_TIMELIMIT, CLICK_LATENCY, CLICK_WINDOW,
+			       CTRL_REG1, CTRL_REG2, CTRL_REG3};
+
+static u8 lis3_wai12_regs[] = {FF_WU_CFG, FF_WU_THS_L, FF_WU_THS_H,
+			       FF_WU_DURATION, DD_CFG, DD_THSI_L, DD_THSI_H,
+			       DD_THSE_L, DD_THSE_H,
+			       CTRL_REG1, CTRL_REG3, CTRL_REG2};
+
+static inline void lis3_context_save(struct lis3lv02d *lis3)
+{
+	int i;
+	for (i = 0; i < lis3->regs_size; i++)
+		lis3->read(lis3, lis3->regs[i], &lis3->reg_cache[i]);
+	lis3->regs_stored = true;
+}
+
+static inline void lis3_context_restore(struct lis3lv02d *lis3)
+{
+	int i;
+	if (lis3->regs_stored)
+		for (i = 0; i < lis3->regs_size; i++)
+			lis3->write(lis3, lis3->regs[i], lis3->reg_cache[i]);
+}
+
 void lis3lv02d_poweroff(struct lis3lv02d *lis3)
 {
+	if (lis3->reg_ctrl)
+		lis3_context_save(lis3);
 	/* disable X,Y,Z axis and power down */
 	lis3->write(lis3, CTRL_REG1, 0x00);
+	if (lis3->reg_ctrl)
+		lis3->reg_ctrl(lis3, LIS3_REG_OFF);
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_poweroff);
 
@@ -249,6 +286,8 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3)
 		reg |= CTRL2_BDU;
 		lis3->write(lis3, CTRL_REG2, reg);
 	}
+	if (lis3->reg_ctrl)
+		lis3_context_restore(lis3);
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
 
@@ -640,6 +679,7 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
 		pm_runtime_disable(lis3->pm_dev);
 		pm_runtime_set_suspended(lis3->pm_dev);
 	}
+	kfree(lis3->reg_cache);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
@@ -719,6 +759,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 		dev->odrs = lis3_12_rates;
 		dev->odr_mask = CTRL1_DF0 | CTRL1_DF1;
 		dev->scale = LIS3_SENSITIVITY_12B;
+		dev->regs = lis3_wai12_regs;
+		dev->regs_size = ARRAY_SIZE(lis3_wai12_regs);
 		break;
 	case WAI_8B:
 		printk(KERN_INFO DRIVER_NAME ": 8 bits sensor found\n");
@@ -728,6 +770,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 		dev->odrs = lis3_8_rates;
 		dev->odr_mask = CTRL1_DR;
 		dev->scale = LIS3_SENSITIVITY_8B;
+		dev->regs = lis3_wai8_regs;
+		dev->regs_size = ARRAY_SIZE(lis3_wai8_regs);
 		break;
 	default:
 		printk(KERN_ERR DRIVER_NAME
@@ -735,6 +779,14 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 		return -EINVAL;
 	}
 
+	dev->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs),
+				     sizeof(lis3_wai12_regs)), GFP_KERNEL);
+
+	if (dev->reg_cache == NULL) {
+		printk(KERN_ERR DRIVER_NAME "out of memory\n");
+		return -ENOMEM;
+	}
+
 	mutex_init(&dev->mutex);
 
 	lis3lv02d_add_fs(dev);
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 3e8a208..7661e59 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -20,6 +20,7 @@
  */
 #include <linux/platform_device.h>
 #include <linux/input-polldev.h>
+#include <linux/regulator/consumer.h>
 
 /*
  * This driver tries to support the "digital" accelerometer chips from
@@ -206,6 +207,11 @@ enum lis3lv02d_click_src_8b {
 	CLICK_IA	= 0x40,
 };
 
+enum lis3lv02d_reg_state {
+	LIS3_REG_OFF	= 0x00,
+	LIS3_REG_ON	= 0x01,
+};
+
 struct axis_conversion {
 	s8	x;
 	s8	y;
@@ -218,8 +224,13 @@ struct lis3lv02d {
 	int (*init) (struct lis3lv02d *lis3);
 	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
 	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
+	int (*reg_ctrl) (struct lis3lv02d *lis3, bool state);
 
 	int                     *odrs;     /* Supported output data rates */
+	u8			*regs;	   /* Regs to store / restore */
+	int			regs_size;
+	u8                      *reg_cache;
+	bool			regs_stored;
 	u8                      odr_mask;  /* ODR bit mask */
 	u8			whoami;    /* indicates measurement precision */
 	s16 (*read_data) (struct lis3lv02d *lis3, int reg);
@@ -232,6 +243,7 @@ struct lis3lv02d {
 
 	struct input_polled_dev	*idev;     /* input device */
 	struct platform_device	*pdev;     /* platform device */
+	struct regulator_bulk_data regulators[2];
 	atomic_t		count;     /* interrupt count after last read */
 	struct axis_conversion	ac;        /* hw -> logical axis */
 	int			mapped_btns[3];
diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index 6e965d7..98983cc 100644
--- a/drivers/hwmon/lis3lv02d_i2c.c
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -30,10 +30,29 @@
 #include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/pm_runtime.h>
+#include <linux/delay.h>
 #include "lis3lv02d.h"
 
 #define DRV_NAME 	"lis3lv02d_i2c"
 
+static const char reg_vdd[]    = "Vdd";
+static const char reg_vdd_io[] = "Vdd_IO";
+
+static int lis3_reg_ctrl(struct lis3lv02d *lis3, bool state)
+{
+	int ret;
+	if (state == LIS3_REG_OFF) {
+		ret = regulator_bulk_disable(ARRAY_SIZE(lis3->regulators),
+					lis3->regulators);
+	} else {
+		ret = regulator_bulk_enable(ARRAY_SIZE(lis3->regulators),
+					lis3->regulators);
+		/* Chip needs time to wakeup. Not mentioned in datasheet */
+		usleep_range(10000, 20000);
+	}
+	return ret;
+}
+
 static inline s32 lis3_i2c_write(struct lis3lv02d *lis3, int reg, u8 value)
 {
 	struct i2c_client *c = lis3->bus_priv;
@@ -52,6 +71,13 @@ static int lis3_i2c_init(struct lis3lv02d *lis3)
 	u8 reg;
 	int ret;
 
+	if (lis3->reg_ctrl)
+		lis3_reg_ctrl(lis3, LIS3_REG_ON);
+
+	lis3->read(lis3, WHO_AM_I, &reg);
+	if (reg != lis3->whoami)
+		printk(KERN_ERR "lis3: power on failure\n");
+
 	/* power up the device */
 	ret = lis3->read(lis3, CTRL_REG1, &reg);
 	if (ret < 0)
@@ -73,6 +99,10 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
 	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
 
 	if (pdata) {
+		/* Regulator control is optional */
+		if (pdata->driver_features & LIS3_USE_REGULATOR_CTRL)
+			lis3_dev.reg_ctrl = lis3_reg_ctrl;
+
 		if (pdata->axis_x)
 			lis3lv02d_axis_map.x = pdata->axis_x;
 
@@ -89,6 +119,16 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
 			goto fail;
 	}
 
+	if (lis3_dev.reg_ctrl) {
+		lis3_dev.regulators[0].supply = reg_vdd;
+		lis3_dev.regulators[1].supply = reg_vdd_io;
+		ret = regulator_bulk_get(&client->dev,
+					ARRAY_SIZE(lis3_dev.regulators),
+					lis3_dev.regulators);
+		if (ret < 0)
+			goto fail;
+	}
+
 	lis3_dev.pdata	  = pdata;
 	lis3_dev.bus_priv = client;
 	lis3_dev.init	  = lis3_i2c_init;
@@ -99,21 +139,34 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
 	lis3_dev.pm_dev	  = &client->dev;
 
 	i2c_set_clientdata(client, &lis3_dev);
+
+	/* Provide power over the init call */
+	if (lis3_dev.reg_ctrl)
+		lis3_reg_ctrl(&lis3_dev, LIS3_REG_ON);
+
 	ret = lis3lv02d_init_device(&lis3_dev);
+
+	if (lis3_dev.reg_ctrl)
+		lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF);
 fail:
 	return ret;
 }
 
 static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
 {
+	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
 	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
 
 	if (pdata && pdata->release_resources)
 		pdata->release_resources();
 
 	lis3lv02d_joystick_disable();
+	lis3lv02d_remove_fs(&lis3_dev);
 
-	return lis3lv02d_remove_fs(&lis3_dev);
+	if (lis3_dev.reg_ctrl)
+		regulator_bulk_free(ARRAY_SIZE(lis3->regulators),
+				lis3_dev.regulators);
+	return 0;
 }
 
 #ifdef CONFIG_PM
diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
index 0e8a346..c4a4a52 100644
--- a/include/linux/lis3lv02d.h
+++ b/include/linux/lis3lv02d.h
@@ -64,6 +64,8 @@ struct lis3lv02d_platform_data {
 	s8 axis_x;
 	s8 axis_y;
 	s8 axis_z;
+#define LIS3_USE_REGULATOR_CTRL 0x01
+	u16 driver_features;
 	int (*setup_resources)(void);
 	int (*release_resources)(void);
 	/* Limits for selftest are specified in chip data sheet */
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH 02/12] hwmon: lis3: regulator control
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel-VkQ1JFuSMpfAbQlEx87xDw, khali-PUYAD+kWke1g9hUCZPvPmw,
	guenter.roeck-IzeFyvvaP7pWk0Htik3J/w,
	jic23-KWPb1pKIrIJaa/9Udqfwiw
  Cc: lm-sensors-GZX6beZjE8VD60Wz+7aTrA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Based on pm_runtime control, turn lis3 regulators on and off.
Perform context save and restore on transitions.

Feature is optional and must be enabled in platform data.

Signed-off-by: Samu Onkalo <samu.p.onkalo-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
---
 drivers/hwmon/lis3lv02d.c     |   52 ++++++++++++++++++++++++++++++++++++++
 drivers/hwmon/lis3lv02d.h     |   12 +++++++++
 drivers/hwmon/lis3lv02d_i2c.c |   55 ++++++++++++++++++++++++++++++++++++++++-
 include/linux/lis3lv02d.h     |    2 +
 4 files changed, 120 insertions(+), 1 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index 412ddc3..ade6f3a 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -31,6 +31,7 @@
 #include <linux/delay.h>
 #include <linux/wait.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <linux/freezer.h>
 #include <linux/uaccess.h>
 #include <linux/miscdevice.h>
@@ -223,10 +224,46 @@ fail:
 	return ret;
 }
 
+/*
+ * Order of registers in the list affects to order of the restore process.
+ * Perhaps it is a good idea to set interrupt enable register as a last one
+ * after all other configurations
+ */
+static u8 lis3_wai8_regs[] = { FF_WU_CFG_1, FF_WU_THS_1, FF_WU_DURATION_1,
+			       FF_WU_CFG_2, FF_WU_THS_2, FF_WU_DURATION_2,
+			       CLICK_CFG, CLICK_SRC, CLICK_THSY_X, CLICK_THSZ,
+			       CLICK_TIMELIMIT, CLICK_LATENCY, CLICK_WINDOW,
+			       CTRL_REG1, CTRL_REG2, CTRL_REG3};
+
+static u8 lis3_wai12_regs[] = {FF_WU_CFG, FF_WU_THS_L, FF_WU_THS_H,
+			       FF_WU_DURATION, DD_CFG, DD_THSI_L, DD_THSI_H,
+			       DD_THSE_L, DD_THSE_H,
+			       CTRL_REG1, CTRL_REG3, CTRL_REG2};
+
+static inline void lis3_context_save(struct lis3lv02d *lis3)
+{
+	int i;
+	for (i = 0; i < lis3->regs_size; i++)
+		lis3->read(lis3, lis3->regs[i], &lis3->reg_cache[i]);
+	lis3->regs_stored = true;
+}
+
+static inline void lis3_context_restore(struct lis3lv02d *lis3)
+{
+	int i;
+	if (lis3->regs_stored)
+		for (i = 0; i < lis3->regs_size; i++)
+			lis3->write(lis3, lis3->regs[i], lis3->reg_cache[i]);
+}
+
 void lis3lv02d_poweroff(struct lis3lv02d *lis3)
 {
+	if (lis3->reg_ctrl)
+		lis3_context_save(lis3);
 	/* disable X,Y,Z axis and power down */
 	lis3->write(lis3, CTRL_REG1, 0x00);
+	if (lis3->reg_ctrl)
+		lis3->reg_ctrl(lis3, LIS3_REG_OFF);
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_poweroff);
 
@@ -249,6 +286,8 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3)
 		reg |= CTRL2_BDU;
 		lis3->write(lis3, CTRL_REG2, reg);
 	}
+	if (lis3->reg_ctrl)
+		lis3_context_restore(lis3);
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
 
@@ -640,6 +679,7 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
 		pm_runtime_disable(lis3->pm_dev);
 		pm_runtime_set_suspended(lis3->pm_dev);
 	}
+	kfree(lis3->reg_cache);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
@@ -719,6 +759,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 		dev->odrs = lis3_12_rates;
 		dev->odr_mask = CTRL1_DF0 | CTRL1_DF1;
 		dev->scale = LIS3_SENSITIVITY_12B;
+		dev->regs = lis3_wai12_regs;
+		dev->regs_size = ARRAY_SIZE(lis3_wai12_regs);
 		break;
 	case WAI_8B:
 		printk(KERN_INFO DRIVER_NAME ": 8 bits sensor found\n");
@@ -728,6 +770,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 		dev->odrs = lis3_8_rates;
 		dev->odr_mask = CTRL1_DR;
 		dev->scale = LIS3_SENSITIVITY_8B;
+		dev->regs = lis3_wai8_regs;
+		dev->regs_size = ARRAY_SIZE(lis3_wai8_regs);
 		break;
 	default:
 		printk(KERN_ERR DRIVER_NAME
@@ -735,6 +779,14 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 		return -EINVAL;
 	}
 
+	dev->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs),
+				     sizeof(lis3_wai12_regs)), GFP_KERNEL);
+
+	if (dev->reg_cache == NULL) {
+		printk(KERN_ERR DRIVER_NAME "out of memory\n");
+		return -ENOMEM;
+	}
+
 	mutex_init(&dev->mutex);
 
 	lis3lv02d_add_fs(dev);
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 3e8a208..7661e59 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -20,6 +20,7 @@
  */
 #include <linux/platform_device.h>
 #include <linux/input-polldev.h>
+#include <linux/regulator/consumer.h>
 
 /*
  * This driver tries to support the "digital" accelerometer chips from
@@ -206,6 +207,11 @@ enum lis3lv02d_click_src_8b {
 	CLICK_IA	= 0x40,
 };
 
+enum lis3lv02d_reg_state {
+	LIS3_REG_OFF	= 0x00,
+	LIS3_REG_ON	= 0x01,
+};
+
 struct axis_conversion {
 	s8	x;
 	s8	y;
@@ -218,8 +224,13 @@ struct lis3lv02d {
 	int (*init) (struct lis3lv02d *lis3);
 	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
 	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
+	int (*reg_ctrl) (struct lis3lv02d *lis3, bool state);
 
 	int                     *odrs;     /* Supported output data rates */
+	u8			*regs;	   /* Regs to store / restore */
+	int			regs_size;
+	u8                      *reg_cache;
+	bool			regs_stored;
 	u8                      odr_mask;  /* ODR bit mask */
 	u8			whoami;    /* indicates measurement precision */
 	s16 (*read_data) (struct lis3lv02d *lis3, int reg);
@@ -232,6 +243,7 @@ struct lis3lv02d {
 
 	struct input_polled_dev	*idev;     /* input device */
 	struct platform_device	*pdev;     /* platform device */
+	struct regulator_bulk_data regulators[2];
 	atomic_t		count;     /* interrupt count after last read */
 	struct axis_conversion	ac;        /* hw -> logical axis */
 	int			mapped_btns[3];
diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index 6e965d7..98983cc 100644
--- a/drivers/hwmon/lis3lv02d_i2c.c
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -30,10 +30,29 @@
 #include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/pm_runtime.h>
+#include <linux/delay.h>
 #include "lis3lv02d.h"
 
 #define DRV_NAME 	"lis3lv02d_i2c"
 
+static const char reg_vdd[]    = "Vdd";
+static const char reg_vdd_io[] = "Vdd_IO";
+
+static int lis3_reg_ctrl(struct lis3lv02d *lis3, bool state)
+{
+	int ret;
+	if (state == LIS3_REG_OFF) {
+		ret = regulator_bulk_disable(ARRAY_SIZE(lis3->regulators),
+					lis3->regulators);
+	} else {
+		ret = regulator_bulk_enable(ARRAY_SIZE(lis3->regulators),
+					lis3->regulators);
+		/* Chip needs time to wakeup. Not mentioned in datasheet */
+		usleep_range(10000, 20000);
+	}
+	return ret;
+}
+
 static inline s32 lis3_i2c_write(struct lis3lv02d *lis3, int reg, u8 value)
 {
 	struct i2c_client *c = lis3->bus_priv;
@@ -52,6 +71,13 @@ static int lis3_i2c_init(struct lis3lv02d *lis3)
 	u8 reg;
 	int ret;
 
+	if (lis3->reg_ctrl)
+		lis3_reg_ctrl(lis3, LIS3_REG_ON);
+
+	lis3->read(lis3, WHO_AM_I, &reg);
+	if (reg != lis3->whoami)
+		printk(KERN_ERR "lis3: power on failure\n");
+
 	/* power up the device */
 	ret = lis3->read(lis3, CTRL_REG1, &reg);
 	if (ret < 0)
@@ -73,6 +99,10 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
 	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
 
 	if (pdata) {
+		/* Regulator control is optional */
+		if (pdata->driver_features & LIS3_USE_REGULATOR_CTRL)
+			lis3_dev.reg_ctrl = lis3_reg_ctrl;
+
 		if (pdata->axis_x)
 			lis3lv02d_axis_map.x = pdata->axis_x;
 
@@ -89,6 +119,16 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
 			goto fail;
 	}
 
+	if (lis3_dev.reg_ctrl) {
+		lis3_dev.regulators[0].supply = reg_vdd;
+		lis3_dev.regulators[1].supply = reg_vdd_io;
+		ret = regulator_bulk_get(&client->dev,
+					ARRAY_SIZE(lis3_dev.regulators),
+					lis3_dev.regulators);
+		if (ret < 0)
+			goto fail;
+	}
+
 	lis3_dev.pdata	  = pdata;
 	lis3_dev.bus_priv = client;
 	lis3_dev.init	  = lis3_i2c_init;
@@ -99,21 +139,34 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
 	lis3_dev.pm_dev	  = &client->dev;
 
 	i2c_set_clientdata(client, &lis3_dev);
+
+	/* Provide power over the init call */
+	if (lis3_dev.reg_ctrl)
+		lis3_reg_ctrl(&lis3_dev, LIS3_REG_ON);
+
 	ret = lis3lv02d_init_device(&lis3_dev);
+
+	if (lis3_dev.reg_ctrl)
+		lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF);
 fail:
 	return ret;
 }
 
 static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
 {
+	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
 	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
 
 	if (pdata && pdata->release_resources)
 		pdata->release_resources();
 
 	lis3lv02d_joystick_disable();
+	lis3lv02d_remove_fs(&lis3_dev);
 
-	return lis3lv02d_remove_fs(&lis3_dev);
+	if (lis3_dev.reg_ctrl)
+		regulator_bulk_free(ARRAY_SIZE(lis3->regulators),
+				lis3_dev.regulators);
+	return 0;
 }
 
 #ifdef CONFIG_PM
diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
index 0e8a346..c4a4a52 100644
--- a/include/linux/lis3lv02d.h
+++ b/include/linux/lis3lv02d.h
@@ -64,6 +64,8 @@ struct lis3lv02d_platform_data {
 	s8 axis_x;
 	s8 axis_y;
 	s8 axis_z;
+#define LIS3_USE_REGULATOR_CTRL 0x01
+	u16 driver_features;
 	int (*setup_resources)(void);
 	int (*release_resources)(void);
 	/* Limits for selftest are specified in chip data sheet */
-- 
1.6.0.4

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [lm-sensors] [PATCH 02/12] hwmon: lis3: regulator control
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Based on pm_runtime control, turn lis3 regulators on and off.
Perform context save and restore on transitions.

Feature is optional and must be enabled in platform data.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d.c     |   52 ++++++++++++++++++++++++++++++++++++++
 drivers/hwmon/lis3lv02d.h     |   12 +++++++++
 drivers/hwmon/lis3lv02d_i2c.c |   55 ++++++++++++++++++++++++++++++++++++++++-
 include/linux/lis3lv02d.h     |    2 +
 4 files changed, 120 insertions(+), 1 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index 412ddc3..ade6f3a 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -31,6 +31,7 @@
 #include <linux/delay.h>
 #include <linux/wait.h>
 #include <linux/poll.h>
+#include <linux/slab.h>
 #include <linux/freezer.h>
 #include <linux/uaccess.h>
 #include <linux/miscdevice.h>
@@ -223,10 +224,46 @@ fail:
 	return ret;
 }
 
+/*
+ * Order of registers in the list affects to order of the restore process.
+ * Perhaps it is a good idea to set interrupt enable register as a last one
+ * after all other configurations
+ */
+static u8 lis3_wai8_regs[] = { FF_WU_CFG_1, FF_WU_THS_1, FF_WU_DURATION_1,
+			       FF_WU_CFG_2, FF_WU_THS_2, FF_WU_DURATION_2,
+			       CLICK_CFG, CLICK_SRC, CLICK_THSY_X, CLICK_THSZ,
+			       CLICK_TIMELIMIT, CLICK_LATENCY, CLICK_WINDOW,
+			       CTRL_REG1, CTRL_REG2, CTRL_REG3};
+
+static u8 lis3_wai12_regs[] = {FF_WU_CFG, FF_WU_THS_L, FF_WU_THS_H,
+			       FF_WU_DURATION, DD_CFG, DD_THSI_L, DD_THSI_H,
+			       DD_THSE_L, DD_THSE_H,
+			       CTRL_REG1, CTRL_REG3, CTRL_REG2};
+
+static inline void lis3_context_save(struct lis3lv02d *lis3)
+{
+	int i;
+	for (i = 0; i < lis3->regs_size; i++)
+		lis3->read(lis3, lis3->regs[i], &lis3->reg_cache[i]);
+	lis3->regs_stored = true;
+}
+
+static inline void lis3_context_restore(struct lis3lv02d *lis3)
+{
+	int i;
+	if (lis3->regs_stored)
+		for (i = 0; i < lis3->regs_size; i++)
+			lis3->write(lis3, lis3->regs[i], lis3->reg_cache[i]);
+}
+
 void lis3lv02d_poweroff(struct lis3lv02d *lis3)
 {
+	if (lis3->reg_ctrl)
+		lis3_context_save(lis3);
 	/* disable X,Y,Z axis and power down */
 	lis3->write(lis3, CTRL_REG1, 0x00);
+	if (lis3->reg_ctrl)
+		lis3->reg_ctrl(lis3, LIS3_REG_OFF);
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_poweroff);
 
@@ -249,6 +286,8 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3)
 		reg |= CTRL2_BDU;
 		lis3->write(lis3, CTRL_REG2, reg);
 	}
+	if (lis3->reg_ctrl)
+		lis3_context_restore(lis3);
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
 
@@ -640,6 +679,7 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
 		pm_runtime_disable(lis3->pm_dev);
 		pm_runtime_set_suspended(lis3->pm_dev);
 	}
+	kfree(lis3->reg_cache);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
@@ -719,6 +759,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 		dev->odrs = lis3_12_rates;
 		dev->odr_mask = CTRL1_DF0 | CTRL1_DF1;
 		dev->scale = LIS3_SENSITIVITY_12B;
+		dev->regs = lis3_wai12_regs;
+		dev->regs_size = ARRAY_SIZE(lis3_wai12_regs);
 		break;
 	case WAI_8B:
 		printk(KERN_INFO DRIVER_NAME ": 8 bits sensor found\n");
@@ -728,6 +770,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 		dev->odrs = lis3_8_rates;
 		dev->odr_mask = CTRL1_DR;
 		dev->scale = LIS3_SENSITIVITY_8B;
+		dev->regs = lis3_wai8_regs;
+		dev->regs_size = ARRAY_SIZE(lis3_wai8_regs);
 		break;
 	default:
 		printk(KERN_ERR DRIVER_NAME
@@ -735,6 +779,14 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 		return -EINVAL;
 	}
 
+	dev->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs),
+				     sizeof(lis3_wai12_regs)), GFP_KERNEL);
+
+	if (dev->reg_cache = NULL) {
+		printk(KERN_ERR DRIVER_NAME "out of memory\n");
+		return -ENOMEM;
+	}
+
 	mutex_init(&dev->mutex);
 
 	lis3lv02d_add_fs(dev);
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 3e8a208..7661e59 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -20,6 +20,7 @@
  */
 #include <linux/platform_device.h>
 #include <linux/input-polldev.h>
+#include <linux/regulator/consumer.h>
 
 /*
  * This driver tries to support the "digital" accelerometer chips from
@@ -206,6 +207,11 @@ enum lis3lv02d_click_src_8b {
 	CLICK_IA	= 0x40,
 };
 
+enum lis3lv02d_reg_state {
+	LIS3_REG_OFF	= 0x00,
+	LIS3_REG_ON	= 0x01,
+};
+
 struct axis_conversion {
 	s8	x;
 	s8	y;
@@ -218,8 +224,13 @@ struct lis3lv02d {
 	int (*init) (struct lis3lv02d *lis3);
 	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
 	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
+	int (*reg_ctrl) (struct lis3lv02d *lis3, bool state);
 
 	int                     *odrs;     /* Supported output data rates */
+	u8			*regs;	   /* Regs to store / restore */
+	int			regs_size;
+	u8                      *reg_cache;
+	bool			regs_stored;
 	u8                      odr_mask;  /* ODR bit mask */
 	u8			whoami;    /* indicates measurement precision */
 	s16 (*read_data) (struct lis3lv02d *lis3, int reg);
@@ -232,6 +243,7 @@ struct lis3lv02d {
 
 	struct input_polled_dev	*idev;     /* input device */
 	struct platform_device	*pdev;     /* platform device */
+	struct regulator_bulk_data regulators[2];
 	atomic_t		count;     /* interrupt count after last read */
 	struct axis_conversion	ac;        /* hw -> logical axis */
 	int			mapped_btns[3];
diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index 6e965d7..98983cc 100644
--- a/drivers/hwmon/lis3lv02d_i2c.c
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -30,10 +30,29 @@
 #include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/pm_runtime.h>
+#include <linux/delay.h>
 #include "lis3lv02d.h"
 
 #define DRV_NAME 	"lis3lv02d_i2c"
 
+static const char reg_vdd[]    = "Vdd";
+static const char reg_vdd_io[] = "Vdd_IO";
+
+static int lis3_reg_ctrl(struct lis3lv02d *lis3, bool state)
+{
+	int ret;
+	if (state = LIS3_REG_OFF) {
+		ret = regulator_bulk_disable(ARRAY_SIZE(lis3->regulators),
+					lis3->regulators);
+	} else {
+		ret = regulator_bulk_enable(ARRAY_SIZE(lis3->regulators),
+					lis3->regulators);
+		/* Chip needs time to wakeup. Not mentioned in datasheet */
+		usleep_range(10000, 20000);
+	}
+	return ret;
+}
+
 static inline s32 lis3_i2c_write(struct lis3lv02d *lis3, int reg, u8 value)
 {
 	struct i2c_client *c = lis3->bus_priv;
@@ -52,6 +71,13 @@ static int lis3_i2c_init(struct lis3lv02d *lis3)
 	u8 reg;
 	int ret;
 
+	if (lis3->reg_ctrl)
+		lis3_reg_ctrl(lis3, LIS3_REG_ON);
+
+	lis3->read(lis3, WHO_AM_I, &reg);
+	if (reg != lis3->whoami)
+		printk(KERN_ERR "lis3: power on failure\n");
+
 	/* power up the device */
 	ret = lis3->read(lis3, CTRL_REG1, &reg);
 	if (ret < 0)
@@ -73,6 +99,10 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
 	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
 
 	if (pdata) {
+		/* Regulator control is optional */
+		if (pdata->driver_features & LIS3_USE_REGULATOR_CTRL)
+			lis3_dev.reg_ctrl = lis3_reg_ctrl;
+
 		if (pdata->axis_x)
 			lis3lv02d_axis_map.x = pdata->axis_x;
 
@@ -89,6 +119,16 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
 			goto fail;
 	}
 
+	if (lis3_dev.reg_ctrl) {
+		lis3_dev.regulators[0].supply = reg_vdd;
+		lis3_dev.regulators[1].supply = reg_vdd_io;
+		ret = regulator_bulk_get(&client->dev,
+					ARRAY_SIZE(lis3_dev.regulators),
+					lis3_dev.regulators);
+		if (ret < 0)
+			goto fail;
+	}
+
 	lis3_dev.pdata	  = pdata;
 	lis3_dev.bus_priv = client;
 	lis3_dev.init	  = lis3_i2c_init;
@@ -99,21 +139,34 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
 	lis3_dev.pm_dev	  = &client->dev;
 
 	i2c_set_clientdata(client, &lis3_dev);
+
+	/* Provide power over the init call */
+	if (lis3_dev.reg_ctrl)
+		lis3_reg_ctrl(&lis3_dev, LIS3_REG_ON);
+
 	ret = lis3lv02d_init_device(&lis3_dev);
+
+	if (lis3_dev.reg_ctrl)
+		lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF);
 fail:
 	return ret;
 }
 
 static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
 {
+	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
 	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
 
 	if (pdata && pdata->release_resources)
 		pdata->release_resources();
 
 	lis3lv02d_joystick_disable();
+	lis3lv02d_remove_fs(&lis3_dev);
 
-	return lis3lv02d_remove_fs(&lis3_dev);
+	if (lis3_dev.reg_ctrl)
+		regulator_bulk_free(ARRAY_SIZE(lis3->regulators),
+				lis3_dev.regulators);
+	return 0;
 }
 
 #ifdef CONFIG_PM
diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
index 0e8a346..c4a4a52 100644
--- a/include/linux/lis3lv02d.h
+++ b/include/linux/lis3lv02d.h
@@ -64,6 +64,8 @@ struct lis3lv02d_platform_data {
 	s8 axis_x;
 	s8 axis_y;
 	s8 axis_z;
+#define LIS3_USE_REGULATOR_CTRL 0x01
+	u16 driver_features;
 	int (*setup_resources)(void);
 	int (*release_resources)(void);
 	/* Limits for selftest are specified in chip data sheet */
-- 
1.6.0.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH 03/12] hwmon: lis3: Cleanup interrupt handling
  2010-10-22 11:57 ` [lm-sensors] " Samu Onkalo
@ 2010-10-22 11:57   ` Samu Onkalo
  -1 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Irqcfg moved to chip data instead of platform data.
This simplifies access in interrupt handler little bit.

Input device open and close functions set status for
interrupt threaded handler once.

Unnecessary check for interrupt source removed since
it is enough that active interrupt line indicates that
there was an interrupt.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d.c |   33 +++++++++++----------------------
 drivers/hwmon/lis3lv02d.h |    2 ++
 2 files changed, 13 insertions(+), 22 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index ade6f3a..fe97390 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -309,10 +309,14 @@ static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
 {
 	if (lis3_dev.pm_dev)
 		pm_runtime_get_sync(lis3_dev.pm_dev);
+
+	if (lis3_dev.pdata && lis3_dev.whoami == WAI_8B && lis3_dev.idev)
+		atomic_set(&lis3_dev.wake_thread, 1);
 }
 
 static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
 {
+	atomic_set(&lis3_dev.wake_thread, 0);
 	if (lis3_dev.pm_dev)
 		pm_runtime_put(lis3_dev.pm_dev);
 }
@@ -332,8 +336,7 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
 	wake_up_interruptible(&lis3_dev.misc_wait);
 	kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN);
 out:
-	if (lis3_dev.pdata && lis3_dev.whoami == WAI_8B && lis3_dev.idev &&
-	    lis3_dev.idev->input->users)
+	if (atomic_read(&lis3_dev.wake_thread))
 		return IRQ_WAKE_THREAD;
 	return IRQ_HANDLED;
 }
@@ -364,31 +367,15 @@ static void lis302dl_interrupt_handle_click(struct lis3lv02d *lis3)
 	mutex_unlock(&lis3->mutex);
 }
 
-static void lis302dl_interrupt_handle_ff_wu(struct lis3lv02d *lis3)
-{
-	u8 wu1_src;
-	u8 wu2_src;
-
-	lis3->read(lis3, FF_WU_SRC_1, &wu1_src);
-	lis3->read(lis3, FF_WU_SRC_2, &wu2_src);
-
-	wu1_src = wu1_src & FF_WU_SRC_IA ? wu1_src : 0;
-	wu2_src = wu2_src & FF_WU_SRC_IA ? wu2_src : 0;
-
-	/* joystick poll is internally protected by the lis3->mutex. */
-	if (wu1_src || wu2_src)
-		lis3lv02d_joystick_poll(lis3_dev.idev);
-}
-
 static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
 {
 
 	struct lis3lv02d *lis3 = data;
 
-	if ((lis3->pdata->irq_cfg & LIS3_IRQ1_MASK) == LIS3_IRQ1_CLICK)
+	if ((lis3->irq_cfg & LIS3_IRQ1_MASK) == LIS3_IRQ1_CLICK)
 		lis302dl_interrupt_handle_click(lis3);
 	else
-		lis302dl_interrupt_handle_ff_wu(lis3);
+		lis3lv02d_joystick_poll(lis3->idev);
 
 	return IRQ_HANDLED;
 }
@@ -398,10 +385,10 @@ static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data)
 
 	struct lis3lv02d *lis3 = data;
 
-	if ((lis3->pdata->irq_cfg & LIS3_IRQ2_MASK) == LIS3_IRQ2_CLICK)
+	if ((lis3->irq_cfg & LIS3_IRQ2_MASK) == LIS3_IRQ2_CLICK)
 		lis302dl_interrupt_handle_click(lis3);
 	else
-		lis302dl_interrupt_handle_ff_wu(lis3);
+		lis3lv02d_joystick_poll(lis3->idev);
 
 	return IRQ_HANDLED;
 }
@@ -788,6 +775,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 	}
 
 	mutex_init(&dev->mutex);
+	atomic_set(&dev->wake_thread, 0);
 
 	lis3lv02d_add_fs(dev);
 	lis3lv02d_poweron(dev);
@@ -808,6 +796,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 		if (dev->whoami == WAI_8B)
 			lis3lv02d_8b_configure(dev, p);
 
+		dev->irq_cfg = p->irq_cfg;
 		if (p->irq_cfg)
 			dev->write(dev, CTRL_REG3, p->irq_cfg);
 	}
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 7661e59..66e37b1 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -252,6 +252,8 @@ struct lis3lv02d {
 	struct fasync_struct	*async_queue; /* queue for the misc device */
 	wait_queue_head_t	misc_wait; /* Wait queue for the misc device */
 	unsigned long		misc_opened; /* bit0: whether the device is open */
+	atomic_t                wake_thread;
+	unsigned char           irq_cfg;
 
 	struct lis3lv02d_platform_data *pdata;	/* for passing board config */
 	struct mutex		mutex;     /* Serialize poll and selftest */
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [lm-sensors] [PATCH 03/12] hwmon: lis3: Cleanup interrupt handling
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Irqcfg moved to chip data instead of platform data.
This simplifies access in interrupt handler little bit.

Input device open and close functions set status for
interrupt threaded handler once.

Unnecessary check for interrupt source removed since
it is enough that active interrupt line indicates that
there was an interrupt.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d.c |   33 +++++++++++----------------------
 drivers/hwmon/lis3lv02d.h |    2 ++
 2 files changed, 13 insertions(+), 22 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index ade6f3a..fe97390 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -309,10 +309,14 @@ static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
 {
 	if (lis3_dev.pm_dev)
 		pm_runtime_get_sync(lis3_dev.pm_dev);
+
+	if (lis3_dev.pdata && lis3_dev.whoami = WAI_8B && lis3_dev.idev)
+		atomic_set(&lis3_dev.wake_thread, 1);
 }
 
 static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
 {
+	atomic_set(&lis3_dev.wake_thread, 0);
 	if (lis3_dev.pm_dev)
 		pm_runtime_put(lis3_dev.pm_dev);
 }
@@ -332,8 +336,7 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
 	wake_up_interruptible(&lis3_dev.misc_wait);
 	kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN);
 out:
-	if (lis3_dev.pdata && lis3_dev.whoami = WAI_8B && lis3_dev.idev &&
-	    lis3_dev.idev->input->users)
+	if (atomic_read(&lis3_dev.wake_thread))
 		return IRQ_WAKE_THREAD;
 	return IRQ_HANDLED;
 }
@@ -364,31 +367,15 @@ static void lis302dl_interrupt_handle_click(struct lis3lv02d *lis3)
 	mutex_unlock(&lis3->mutex);
 }
 
-static void lis302dl_interrupt_handle_ff_wu(struct lis3lv02d *lis3)
-{
-	u8 wu1_src;
-	u8 wu2_src;
-
-	lis3->read(lis3, FF_WU_SRC_1, &wu1_src);
-	lis3->read(lis3, FF_WU_SRC_2, &wu2_src);
-
-	wu1_src = wu1_src & FF_WU_SRC_IA ? wu1_src : 0;
-	wu2_src = wu2_src & FF_WU_SRC_IA ? wu2_src : 0;
-
-	/* joystick poll is internally protected by the lis3->mutex. */
-	if (wu1_src || wu2_src)
-		lis3lv02d_joystick_poll(lis3_dev.idev);
-}
-
 static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
 {
 
 	struct lis3lv02d *lis3 = data;
 
-	if ((lis3->pdata->irq_cfg & LIS3_IRQ1_MASK) = LIS3_IRQ1_CLICK)
+	if ((lis3->irq_cfg & LIS3_IRQ1_MASK) = LIS3_IRQ1_CLICK)
 		lis302dl_interrupt_handle_click(lis3);
 	else
-		lis302dl_interrupt_handle_ff_wu(lis3);
+		lis3lv02d_joystick_poll(lis3->idev);
 
 	return IRQ_HANDLED;
 }
@@ -398,10 +385,10 @@ static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data)
 
 	struct lis3lv02d *lis3 = data;
 
-	if ((lis3->pdata->irq_cfg & LIS3_IRQ2_MASK) = LIS3_IRQ2_CLICK)
+	if ((lis3->irq_cfg & LIS3_IRQ2_MASK) = LIS3_IRQ2_CLICK)
 		lis302dl_interrupt_handle_click(lis3);
 	else
-		lis302dl_interrupt_handle_ff_wu(lis3);
+		lis3lv02d_joystick_poll(lis3->idev);
 
 	return IRQ_HANDLED;
 }
@@ -788,6 +775,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 	}
 
 	mutex_init(&dev->mutex);
+	atomic_set(&dev->wake_thread, 0);
 
 	lis3lv02d_add_fs(dev);
 	lis3lv02d_poweron(dev);
@@ -808,6 +796,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 		if (dev->whoami = WAI_8B)
 			lis3lv02d_8b_configure(dev, p);
 
+		dev->irq_cfg = p->irq_cfg;
 		if (p->irq_cfg)
 			dev->write(dev, CTRL_REG3, p->irq_cfg);
 	}
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 7661e59..66e37b1 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -252,6 +252,8 @@ struct lis3lv02d {
 	struct fasync_struct	*async_queue; /* queue for the misc device */
 	wait_queue_head_t	misc_wait; /* Wait queue for the misc device */
 	unsigned long		misc_opened; /* bit0: whether the device is open */
+	atomic_t                wake_thread;
+	unsigned char           irq_cfg;
 
 	struct lis3lv02d_platform_data *pdata;	/* for passing board config */
 	struct mutex		mutex;     /* Serialize poll and selftest */
-- 
1.6.0.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH 04/12] hwmon: lis3: Update coordinates at polled device open
  2010-10-22 11:57 ` [lm-sensors] " Samu Onkalo
@ 2010-10-22 11:57   ` Samu Onkalo
  -1 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Call input device poll function at device open to refresh coordinates
immediately. This is needed for the case where poll interval is set to
zero and coordinate updates happens purely under interrupt control.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index fe97390..e2e0bb4 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -312,6 +312,11 @@ static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
 
 	if (lis3_dev.pdata && lis3_dev.whoami == WAI_8B && lis3_dev.idev)
 		atomic_set(&lis3_dev.wake_thread, 1);
+	/*
+	 * Update coordinates for the case where poll interval is 0 and
+	 * the chip in running purely under interrupt control
+	 */
+	lis3lv02d_joystick_poll(pidev);
 }
 
 static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [lm-sensors] [PATCH 04/12] hwmon: lis3: Update coordinates at
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Call input device poll function at device open to refresh coordinates
immediately. This is needed for the case where poll interval is set to
zero and coordinate updates happens purely under interrupt control.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index fe97390..e2e0bb4 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -312,6 +312,11 @@ static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
 
 	if (lis3_dev.pdata && lis3_dev.whoami = WAI_8B && lis3_dev.idev)
 		atomic_set(&lis3_dev.wake_thread, 1);
+	/*
+	 * Update coordinates for the case where poll interval is 0 and
+	 * the chip in running purely under interrupt control
+	 */
+	lis3lv02d_joystick_poll(pidev);
 }
 
 static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
-- 
1.6.0.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH 05/12] hwmon: lis3: Power on corrections
  2010-10-22 11:57 ` [lm-sensors] " Samu Onkalo
  (?)
@ 2010-10-22 11:57   ` Samu Onkalo
  -1 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Sometimes lis3 chip seems to fail to setup factory tuning at boot up.
This probably happens if there is some odd power ramp down ramp up sequence
for example in device restart. Set boot bit in control2 register to
trig boot sequence manually and wait until it is finished.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/hwmon/lis3lv02d.c |   19 +++++++++++--------
 drivers/hwmon/lis3lv02d.h |    1 +
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index e2e0bb4..b44d4c5 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -273,19 +273,22 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3)
 
 	lis3->init(lis3);
 
-	/* LIS3 power on delay is quite long */
-	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
-
 	/*
 	 * Common configuration
 	 * BDU: (12 bits sensors only) LSB and MSB values are not updated until
 	 *      both have been read. So the value read will always be correct.
+	 * Set BOOT bit to refresh factory tuning values.
 	 */
-	if (lis3->whoami ==  WAI_12B) {
-		lis3->read(lis3, CTRL_REG2, &reg);
-		reg |= CTRL2_BDU;
-		lis3->write(lis3, CTRL_REG2, reg);
-	}
+	lis3->read(lis3, CTRL_REG2, &reg);
+	if (lis3->whoami ==  WAI_12B)
+		reg |= CTRL2_BDU | CTRL2_BOOT;
+	else
+		reg |= CTRL2_BOOT_8B;
+	lis3->write(lis3, CTRL_REG2, reg);
+
+	/* LIS3 power on delay is quite long */
+	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
+
 	if (lis3->reg_ctrl)
 		lis3_context_restore(lis3);
 }
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 66e37b1..2ac27b9 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -133,6 +133,7 @@ enum lis3lv02d_ctrl2 {
 enum lis302d_ctrl2 {
 	HP_FF_WU2	= 0x08,
 	HP_FF_WU1	= 0x04,
+	CTRL2_BOOT_8B   = 0x40,
 };
 
 enum lis3lv02d_ctrl3 {
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH 05/12] hwmon: lis3: Power on corrections
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: linux-kernel, linux-i2c, lm-sensors

Sometimes lis3 chip seems to fail to setup factory tuning at boot up.
This probably happens if there is some odd power ramp down ramp up sequence
for example in device restart. Set boot bit in control2 register to
trig boot sequence manually and wait until it is finished.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/hwmon/lis3lv02d.c |   19 +++++++++++--------
 drivers/hwmon/lis3lv02d.h |    1 +
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index e2e0bb4..b44d4c5 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -273,19 +273,22 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3)
 
 	lis3->init(lis3);
 
-	/* LIS3 power on delay is quite long */
-	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
-
 	/*
 	 * Common configuration
 	 * BDU: (12 bits sensors only) LSB and MSB values are not updated until
 	 *      both have been read. So the value read will always be correct.
+	 * Set BOOT bit to refresh factory tuning values.
 	 */
-	if (lis3->whoami ==  WAI_12B) {
-		lis3->read(lis3, CTRL_REG2, &reg);
-		reg |= CTRL2_BDU;
-		lis3->write(lis3, CTRL_REG2, reg);
-	}
+	lis3->read(lis3, CTRL_REG2, &reg);
+	if (lis3->whoami ==  WAI_12B)
+		reg |= CTRL2_BDU | CTRL2_BOOT;
+	else
+		reg |= CTRL2_BOOT_8B;
+	lis3->write(lis3, CTRL_REG2, reg);
+
+	/* LIS3 power on delay is quite long */
+	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
+
 	if (lis3->reg_ctrl)
 		lis3_context_restore(lis3);
 }
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 66e37b1..2ac27b9 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -133,6 +133,7 @@ enum lis3lv02d_ctrl2 {
 enum lis302d_ctrl2 {
 	HP_FF_WU2	= 0x08,
 	HP_FF_WU1	= 0x04,
+	CTRL2_BOOT_8B   = 0x40,
 };
 
 enum lis3lv02d_ctrl3 {
-- 
1.6.0.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [lm-sensors] [PATCH 05/12] hwmon: lis3: Power on corrections
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Sometimes lis3 chip seems to fail to setup factory tuning at boot up.
This probably happens if there is some odd power ramp down ramp up sequence
for example in device restart. Set boot bit in control2 register to
trig boot sequence manually and wait until it is finished.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
---
 drivers/hwmon/lis3lv02d.c |   19 +++++++++++--------
 drivers/hwmon/lis3lv02d.h |    1 +
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index e2e0bb4..b44d4c5 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -273,19 +273,22 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3)
 
 	lis3->init(lis3);
 
-	/* LIS3 power on delay is quite long */
-	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
-
 	/*
 	 * Common configuration
 	 * BDU: (12 bits sensors only) LSB and MSB values are not updated until
 	 *      both have been read. So the value read will always be correct.
+	 * Set BOOT bit to refresh factory tuning values.
 	 */
-	if (lis3->whoami =  WAI_12B) {
-		lis3->read(lis3, CTRL_REG2, &reg);
-		reg |= CTRL2_BDU;
-		lis3->write(lis3, CTRL_REG2, reg);
-	}
+	lis3->read(lis3, CTRL_REG2, &reg);
+	if (lis3->whoami =  WAI_12B)
+		reg |= CTRL2_BDU | CTRL2_BOOT;
+	else
+		reg |= CTRL2_BOOT_8B;
+	lis3->write(lis3, CTRL_REG2, reg);
+
+	/* LIS3 power on delay is quite long */
+	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
+
 	if (lis3->reg_ctrl)
 		lis3_context_restore(lis3);
 }
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 66e37b1..2ac27b9 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -133,6 +133,7 @@ enum lis3lv02d_ctrl2 {
 enum lis302d_ctrl2 {
 	HP_FF_WU2	= 0x08,
 	HP_FF_WU1	= 0x04,
+	CTRL2_BOOT_8B   = 0x40,
 };
 
 enum lis3lv02d_ctrl3 {
-- 
1.6.0.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH 06/12] hwmon: lis3: restore axis enabled bits
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

All axis enable bits are set to 0 at module remove.
Restore reset default value at init.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d_i2c.c |    2 +-
 drivers/hwmon/lis3lv02d_spi.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index 98983cc..36171bf 100644
--- a/drivers/hwmon/lis3lv02d_i2c.c
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -83,7 +83,7 @@ static int lis3_i2c_init(struct lis3lv02d *lis3)
 	if (ret < 0)
 		return ret;
 
-	reg |= CTRL1_PD0;
+	reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen;
 	return lis3->write(lis3, CTRL_REG1, reg);
 }
 
diff --git a/drivers/hwmon/lis3lv02d_spi.c b/drivers/hwmon/lis3lv02d_spi.c
index b9be5e3..778885d 100644
--- a/drivers/hwmon/lis3lv02d_spi.c
+++ b/drivers/hwmon/lis3lv02d_spi.c
@@ -50,7 +50,7 @@ static int lis3_spi_init(struct lis3lv02d *lis3)
 	if (ret < 0)
 		return ret;
 
-	reg |= CTRL1_PD0;
+	reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen;
 	return lis3->write(lis3, CTRL_REG1, reg);
 }
 
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH 06/12] hwmon: lis3: restore axis enabled bits
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel-VkQ1JFuSMpfAbQlEx87xDw, khali-PUYAD+kWke1g9hUCZPvPmw,
	guenter.roeck-IzeFyvvaP7pWk0Htik3J/w,
	jic23-KWPb1pKIrIJaa/9Udqfwiw
  Cc: lm-sensors-GZX6beZjE8VD60Wz+7aTrA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

All axis enable bits are set to 0 at module remove.
Restore reset default value at init.

Signed-off-by: Samu Onkalo <samu.p.onkalo-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
---
 drivers/hwmon/lis3lv02d_i2c.c |    2 +-
 drivers/hwmon/lis3lv02d_spi.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index 98983cc..36171bf 100644
--- a/drivers/hwmon/lis3lv02d_i2c.c
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -83,7 +83,7 @@ static int lis3_i2c_init(struct lis3lv02d *lis3)
 	if (ret < 0)
 		return ret;
 
-	reg |= CTRL1_PD0;
+	reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen;
 	return lis3->write(lis3, CTRL_REG1, reg);
 }
 
diff --git a/drivers/hwmon/lis3lv02d_spi.c b/drivers/hwmon/lis3lv02d_spi.c
index b9be5e3..778885d 100644
--- a/drivers/hwmon/lis3lv02d_spi.c
+++ b/drivers/hwmon/lis3lv02d_spi.c
@@ -50,7 +50,7 @@ static int lis3_spi_init(struct lis3lv02d *lis3)
 	if (ret < 0)
 		return ret;
 
-	reg |= CTRL1_PD0;
+	reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen;
 	return lis3->write(lis3, CTRL_REG1, reg);
 }
 
-- 
1.6.0.4

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [lm-sensors] [PATCH 06/12] hwmon: lis3: restore axis enabled bits
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

All axis enable bits are set to 0 at module remove.
Restore reset default value at init.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d_i2c.c |    2 +-
 drivers/hwmon/lis3lv02d_spi.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index 98983cc..36171bf 100644
--- a/drivers/hwmon/lis3lv02d_i2c.c
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -83,7 +83,7 @@ static int lis3_i2c_init(struct lis3lv02d *lis3)
 	if (ret < 0)
 		return ret;
 
-	reg |= CTRL1_PD0;
+	reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen;
 	return lis3->write(lis3, CTRL_REG1, reg);
 }
 
diff --git a/drivers/hwmon/lis3lv02d_spi.c b/drivers/hwmon/lis3lv02d_spi.c
index b9be5e3..778885d 100644
--- a/drivers/hwmon/lis3lv02d_spi.c
+++ b/drivers/hwmon/lis3lv02d_spi.c
@@ -50,7 +50,7 @@ static int lis3_spi_init(struct lis3lv02d *lis3)
 	if (ret < 0)
 		return ret;
 
-	reg |= CTRL1_PD0;
+	reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen;
 	return lis3->write(lis3, CTRL_REG1, reg);
 }
 
-- 
1.6.0.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH 07/12] hwmon: lis3: New parameters to platform data
  2010-10-22 11:57 ` [lm-sensors] " Samu Onkalo
@ 2010-10-22 11:57   ` Samu Onkalo
  -1 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Added default output data rate setting to platform data.
If default rate is 0, reset default value is used.
Added control for duration via platform data.
Added possibility to configure interrupts to trig on
both rising and falling edge. The lis3 WU unit can be
configured quite many ways and with some configurations it
is quite handy to get coordinate refresh when some
event trigs and when it reason goes away.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d.c |   21 ++++++++++++++-------
 include/linux/lis3lv02d.h |    6 +++++-
 2 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index b44d4c5..d66cbe1 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -706,16 +706,16 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
 	if (p->wakeup_flags) {
 		dev->write(dev, FF_WU_CFG_1, p->wakeup_flags);
 		dev->write(dev, FF_WU_THS_1, p->wakeup_thresh & 0x7f);
-		/* default to 2.5ms for now */
-		dev->write(dev, FF_WU_DURATION_1, 1);
+		/* pdata value + 1 to keep this backward compatible*/
+		dev->write(dev, FF_WU_DURATION_1, p->duration1 + 1);
 		ctrl2 ^= HP_FF_WU1; /* Xor to keep compatible with old pdata*/
 	}
 
 	if (p->wakeup_flags2) {
 		dev->write(dev, FF_WU_CFG_2, p->wakeup_flags2);
 		dev->write(dev, FF_WU_THS_2, p->wakeup_thresh2 & 0x7f);
-		/* default to 2.5ms for now */
-		dev->write(dev, FF_WU_DURATION_2, 1);
+		/* pdata value + 1 to keep this backward compatible*/
+		dev->write(dev, FF_WU_DURATION_2, p->duration2 + 1);
 		ctrl2 ^= HP_FF_WU2; /* Xor to keep compatible with old pdata*/
 	}
 	/* Configure hipass filters */
@@ -725,8 +725,8 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
 		err = request_threaded_irq(p->irq2,
 					NULL,
 					lis302dl_interrupt_thread2_8b,
-					IRQF_TRIGGER_RISING |
-					IRQF_ONESHOT,
+					IRQF_TRIGGER_RISING | IRQF_ONESHOT |
+					(p->irq_flags2 & IRQF_TRIGGER_MASK),
 					DRIVER_NAME, &lis3_dev);
 		if (err < 0)
 			printk(KERN_ERR DRIVER_NAME
@@ -742,6 +742,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 {
 	int err;
 	irq_handler_t thread_fn;
+	int irq_flags = 0;
 
 	dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I);
 
@@ -804,9 +805,14 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 		if (dev->whoami == WAI_8B)
 			lis3lv02d_8b_configure(dev, p);
 
+		irq_flags = p->irq_flags1 & IRQF_TRIGGER_MASK;
+
 		dev->irq_cfg = p->irq_cfg;
 		if (p->irq_cfg)
 			dev->write(dev, CTRL_REG3, p->irq_cfg);
+
+		if (p->default_rate)
+			lis3lv02d_set_odr(p->default_rate);
 	}
 
 	/* bail if we did not get an IRQ from the bus layer */
@@ -834,7 +840,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 
 	err = request_threaded_irq(dev->irq, lis302dl_interrupt,
 				thread_fn,
-				IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+				IRQF_TRIGGER_RISING | IRQF_ONESHOT |
+				irq_flags,
 				DRIVER_NAME, &lis3_dev);
 
 	if (err < 0) {
diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
index c4a4a52..18d578f 100644
--- a/include/linux/lis3lv02d.h
+++ b/include/linux/lis3lv02d.h
@@ -36,7 +36,10 @@ struct lis3lv02d_platform_data {
 #define LIS3_IRQ_OPEN_DRAIN	(1 << 6)
 #define LIS3_IRQ_ACTIVE_LOW	(1 << 7)
 	unsigned char irq_cfg;
-
+	unsigned char irq_flags1; /* Additional irq edge / level flags */
+	unsigned char irq_flags2; /* Additional irq edge / level flags */
+	unsigned char duration1;
+	unsigned char duration2;
 #define LIS3_WAKEUP_X_LO	(1 << 0)
 #define LIS3_WAKEUP_X_HI	(1 << 1)
 #define LIS3_WAKEUP_Y_LO	(1 << 2)
@@ -66,6 +69,7 @@ struct lis3lv02d_platform_data {
 	s8 axis_z;
 #define LIS3_USE_REGULATOR_CTRL 0x01
 	u16 driver_features;
+	int default_rate;
 	int (*setup_resources)(void);
 	int (*release_resources)(void);
 	/* Limits for selftest are specified in chip data sheet */
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [lm-sensors] [PATCH 07/12] hwmon: lis3: New parameters to platform
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Added default output data rate setting to platform data.
If default rate is 0, reset default value is used.
Added control for duration via platform data.
Added possibility to configure interrupts to trig on
both rising and falling edge. The lis3 WU unit can be
configured quite many ways and with some configurations it
is quite handy to get coordinate refresh when some
event trigs and when it reason goes away.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d.c |   21 ++++++++++++++-------
 include/linux/lis3lv02d.h |    6 +++++-
 2 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index b44d4c5..d66cbe1 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -706,16 +706,16 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
 	if (p->wakeup_flags) {
 		dev->write(dev, FF_WU_CFG_1, p->wakeup_flags);
 		dev->write(dev, FF_WU_THS_1, p->wakeup_thresh & 0x7f);
-		/* default to 2.5ms for now */
-		dev->write(dev, FF_WU_DURATION_1, 1);
+		/* pdata value + 1 to keep this backward compatible*/
+		dev->write(dev, FF_WU_DURATION_1, p->duration1 + 1);
 		ctrl2 ^= HP_FF_WU1; /* Xor to keep compatible with old pdata*/
 	}
 
 	if (p->wakeup_flags2) {
 		dev->write(dev, FF_WU_CFG_2, p->wakeup_flags2);
 		dev->write(dev, FF_WU_THS_2, p->wakeup_thresh2 & 0x7f);
-		/* default to 2.5ms for now */
-		dev->write(dev, FF_WU_DURATION_2, 1);
+		/* pdata value + 1 to keep this backward compatible*/
+		dev->write(dev, FF_WU_DURATION_2, p->duration2 + 1);
 		ctrl2 ^= HP_FF_WU2; /* Xor to keep compatible with old pdata*/
 	}
 	/* Configure hipass filters */
@@ -725,8 +725,8 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
 		err = request_threaded_irq(p->irq2,
 					NULL,
 					lis302dl_interrupt_thread2_8b,
-					IRQF_TRIGGER_RISING |
-					IRQF_ONESHOT,
+					IRQF_TRIGGER_RISING | IRQF_ONESHOT |
+					(p->irq_flags2 & IRQF_TRIGGER_MASK),
 					DRIVER_NAME, &lis3_dev);
 		if (err < 0)
 			printk(KERN_ERR DRIVER_NAME
@@ -742,6 +742,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 {
 	int err;
 	irq_handler_t thread_fn;
+	int irq_flags = 0;
 
 	dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I);
 
@@ -804,9 +805,14 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 		if (dev->whoami = WAI_8B)
 			lis3lv02d_8b_configure(dev, p);
 
+		irq_flags = p->irq_flags1 & IRQF_TRIGGER_MASK;
+
 		dev->irq_cfg = p->irq_cfg;
 		if (p->irq_cfg)
 			dev->write(dev, CTRL_REG3, p->irq_cfg);
+
+		if (p->default_rate)
+			lis3lv02d_set_odr(p->default_rate);
 	}
 
 	/* bail if we did not get an IRQ from the bus layer */
@@ -834,7 +840,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 
 	err = request_threaded_irq(dev->irq, lis302dl_interrupt,
 				thread_fn,
-				IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+				IRQF_TRIGGER_RISING | IRQF_ONESHOT |
+				irq_flags,
 				DRIVER_NAME, &lis3_dev);
 
 	if (err < 0) {
diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
index c4a4a52..18d578f 100644
--- a/include/linux/lis3lv02d.h
+++ b/include/linux/lis3lv02d.h
@@ -36,7 +36,10 @@ struct lis3lv02d_platform_data {
 #define LIS3_IRQ_OPEN_DRAIN	(1 << 6)
 #define LIS3_IRQ_ACTIVE_LOW	(1 << 7)
 	unsigned char irq_cfg;
-
+	unsigned char irq_flags1; /* Additional irq edge / level flags */
+	unsigned char irq_flags2; /* Additional irq edge / level flags */
+	unsigned char duration1;
+	unsigned char duration2;
 #define LIS3_WAKEUP_X_LO	(1 << 0)
 #define LIS3_WAKEUP_X_HI	(1 << 1)
 #define LIS3_WAKEUP_Y_LO	(1 << 2)
@@ -66,6 +69,7 @@ struct lis3lv02d_platform_data {
 	s8 axis_z;
 #define LIS3_USE_REGULATOR_CTRL 0x01
 	u16 driver_features;
+	int default_rate;
 	int (*setup_resources)(void);
 	int (*release_resources)(void);
 	/* Limits for selftest are specified in chip data sheet */
-- 
1.6.0.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH 08/12] hwmon: lis3: Adjust fuzziness for 8 bit device
  2010-10-22 11:57 ` [lm-sensors] " Samu Onkalo
@ 2010-10-22 11:57   ` Samu Onkalo
  -1 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Default fuziness is set smaller for 8 device.
In 12 bit device LSB is quite close to 1 mg
(mg = 1 / 1000 of earth gravity).
In 8bit device LSB is about 18 mg.
Set fuziness to 1 for 8 bit device.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d.c |   18 ++++++++++++++----
 1 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index d66cbe1..7555091 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -71,8 +71,10 @@
 #define LIS3_SENSITIVITY_12B		((LIS3_ACCURACY * 1000) / 1024)
 #define LIS3_SENSITIVITY_8B		(18 * LIS3_ACCURACY)
 
-#define LIS3_DEFAULT_FUZZ		3
-#define LIS3_DEFAULT_FLAT		3
+#define LIS3_DEFAULT_FUZZ_12B		3
+#define LIS3_DEFAULT_FLAT_12B		3
+#define LIS3_DEFAULT_FUZZ_8B		1
+#define LIS3_DEFAULT_FLAT_8B		1
 
 struct lis3lv02d lis3_dev = {
 	.misc_wait   = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait),
@@ -530,8 +532,16 @@ int lis3lv02d_joystick_enable(void)
 
 	set_bit(EV_ABS, input_dev->evbit);
 	max_val = (lis3_dev.mdps_max_val * lis3_dev.scale) / LIS3_ACCURACY;
-	fuzz = (LIS3_DEFAULT_FUZZ * lis3_dev.scale) / LIS3_ACCURACY;
-	flat = (LIS3_DEFAULT_FLAT * lis3_dev.scale) / LIS3_ACCURACY;
+	if (lis3_dev.whoami == WAI_12B) {
+		fuzz = LIS3_DEFAULT_FUZZ_12B;
+		flat = LIS3_DEFAULT_FLAT_12B;
+	} else {
+		fuzz = LIS3_DEFAULT_FUZZ_8B;
+		flat = LIS3_DEFAULT_FLAT_8B;
+	}
+	fuzz = (fuzz * lis3_dev.scale) / LIS3_ACCURACY;
+	flat = (flat * lis3_dev.scale) / LIS3_ACCURACY;
+
 	input_set_abs_params(input_dev, ABS_X, -max_val, max_val, fuzz, flat);
 	input_set_abs_params(input_dev, ABS_Y, -max_val, max_val, fuzz, flat);
 	input_set_abs_params(input_dev, ABS_Z, -max_val, max_val, fuzz, flat);
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [lm-sensors] [PATCH 08/12] hwmon: lis3: Adjust fuzziness for 8 bit
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Default fuziness is set smaller for 8 device.
In 12 bit device LSB is quite close to 1 mg
(mg = 1 / 1000 of earth gravity).
In 8bit device LSB is about 18 mg.
Set fuziness to 1 for 8 bit device.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d.c |   18 ++++++++++++++----
 1 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index d66cbe1..7555091 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -71,8 +71,10 @@
 #define LIS3_SENSITIVITY_12B		((LIS3_ACCURACY * 1000) / 1024)
 #define LIS3_SENSITIVITY_8B		(18 * LIS3_ACCURACY)
 
-#define LIS3_DEFAULT_FUZZ		3
-#define LIS3_DEFAULT_FLAT		3
+#define LIS3_DEFAULT_FUZZ_12B		3
+#define LIS3_DEFAULT_FLAT_12B		3
+#define LIS3_DEFAULT_FUZZ_8B		1
+#define LIS3_DEFAULT_FLAT_8B		1
 
 struct lis3lv02d lis3_dev = {
 	.misc_wait   = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait),
@@ -530,8 +532,16 @@ int lis3lv02d_joystick_enable(void)
 
 	set_bit(EV_ABS, input_dev->evbit);
 	max_val = (lis3_dev.mdps_max_val * lis3_dev.scale) / LIS3_ACCURACY;
-	fuzz = (LIS3_DEFAULT_FUZZ * lis3_dev.scale) / LIS3_ACCURACY;
-	flat = (LIS3_DEFAULT_FLAT * lis3_dev.scale) / LIS3_ACCURACY;
+	if (lis3_dev.whoami = WAI_12B) {
+		fuzz = LIS3_DEFAULT_FUZZ_12B;
+		flat = LIS3_DEFAULT_FLAT_12B;
+	} else {
+		fuzz = LIS3_DEFAULT_FUZZ_8B;
+		flat = LIS3_DEFAULT_FLAT_8B;
+	}
+	fuzz = (fuzz * lis3_dev.scale) / LIS3_ACCURACY;
+	flat = (flat * lis3_dev.scale) / LIS3_ACCURACY;
+
 	input_set_abs_params(input_dev, ABS_X, -max_val, max_val, fuzz, flat);
 	input_set_abs_params(input_dev, ABS_Y, -max_val, max_val, fuzz, flat);
 	input_set_abs_params(input_dev, ABS_Z, -max_val, max_val, fuzz, flat);
-- 
1.6.0.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH 09/12] hwmon: lis3: use block read to access data registers
  2010-10-22 11:57 ` [lm-sensors] " Samu Onkalo
@ 2010-10-22 11:57   ` Samu Onkalo
  -1 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Add optional blockread function to interface driver. If available
the chip driver uses it for data register access. For 12 bit device
it reads 6 bytes to get 3*16bit data. For 8 bit device it reads out
5 bytes since every second byte is dummy.
This optimizes bus usage and reduces number of operations and
interrupts needed for one data update.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d.c     |   21 ++++++++++++++++++---
 drivers/hwmon/lis3lv02d.h     |    1 +
 drivers/hwmon/lis3lv02d_i2c.c |   13 +++++++++++++
 include/linux/lis3lv02d.h     |    1 +
 4 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index 7555091..9fd946c 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -130,9 +130,24 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
 	int position[3];
 	int i;
 
-	position[0] = lis3->read_data(lis3, OUTX);
-	position[1] = lis3->read_data(lis3, OUTY);
-	position[2] = lis3->read_data(lis3, OUTZ);
+	if (lis3->blkread) {
+		if (lis3_dev.whoami == WAI_12B) {
+			u16 data[3];
+			lis3->blkread(lis3, OUTX_L, 6, (u8 *)data);
+			for (i = 0; i < 3; i++)
+				position[i] = (s16)le16_to_cpu(data[i]);
+		} else {
+			u8 data[5];
+			/* Data: x, dummy, y, dummy, z */
+			lis3->blkread(lis3, OUTX, 5, data);
+			for (i = 0; i < 3; i++)
+				position[i] = (s8)data[i * 2];
+		}
+	} else {
+		position[0] = lis3->read_data(lis3, OUTX);
+		position[1] = lis3->read_data(lis3, OUTY);
+		position[2] = lis3->read_data(lis3, OUTZ);
+	}
 
 	for (i = 0; i < 3; i++)
 		position[i] = (position[i] * lis3->scale) / LIS3_ACCURACY;
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 2ac27b9..d3cb662 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -225,6 +225,7 @@ struct lis3lv02d {
 	int (*init) (struct lis3lv02d *lis3);
 	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
 	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
+	int (*blkread) (struct lis3lv02d *lis3, int reg, int len, u8 *ret);
 	int (*reg_ctrl) (struct lis3lv02d *lis3, bool state);
 
 	int                     *odrs;     /* Supported output data rates */
diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index 36171bf..61c109b 100644
--- a/drivers/hwmon/lis3lv02d_i2c.c
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -66,6 +66,14 @@ static inline s32 lis3_i2c_read(struct lis3lv02d *lis3, int reg, u8 *v)
 	return 0;
 }
 
+static inline s32 lis3_i2c_blockread(struct lis3lv02d *lis3, int reg, int len,
+				u8 *v)
+{
+	struct i2c_client *c = lis3->bus_priv;
+	reg |= (1 << 7); /* 7th bit enables address auto incrementation */
+	return i2c_smbus_read_i2c_block_data(c, reg, len, v);
+}
+
 static int lis3_i2c_init(struct lis3lv02d *lis3)
 {
 	u8 reg;
@@ -103,6 +111,11 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
 		if (pdata->driver_features & LIS3_USE_REGULATOR_CTRL)
 			lis3_dev.reg_ctrl = lis3_reg_ctrl;
 
+		if ((pdata->driver_features & LIS3_USE_BLOCK_READ) &&
+			(i2c_check_functionality(client->adapter,
+						I2C_FUNC_SMBUS_I2C_BLOCK)))
+			lis3_dev.blkread  = lis3_i2c_blockread;
+
 		if (pdata->axis_x)
 			lis3lv02d_axis_map.x = pdata->axis_x;
 
diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
index 18d578f..c949612 100644
--- a/include/linux/lis3lv02d.h
+++ b/include/linux/lis3lv02d.h
@@ -68,6 +68,7 @@ struct lis3lv02d_platform_data {
 	s8 axis_y;
 	s8 axis_z;
 #define LIS3_USE_REGULATOR_CTRL 0x01
+#define LIS3_USE_BLOCK_READ	0x02
 	u16 driver_features;
 	int default_rate;
 	int (*setup_resources)(void);
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [lm-sensors] [PATCH 09/12] hwmon: lis3: use block read to access
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Add optional blockread function to interface driver. If available
the chip driver uses it for data register access. For 12 bit device
it reads 6 bytes to get 3*16bit data. For 8 bit device it reads out
5 bytes since every second byte is dummy.
This optimizes bus usage and reduces number of operations and
interrupts needed for one data update.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d.c     |   21 ++++++++++++++++++---
 drivers/hwmon/lis3lv02d.h     |    1 +
 drivers/hwmon/lis3lv02d_i2c.c |   13 +++++++++++++
 include/linux/lis3lv02d.h     |    1 +
 4 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index 7555091..9fd946c 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -130,9 +130,24 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
 	int position[3];
 	int i;
 
-	position[0] = lis3->read_data(lis3, OUTX);
-	position[1] = lis3->read_data(lis3, OUTY);
-	position[2] = lis3->read_data(lis3, OUTZ);
+	if (lis3->blkread) {
+		if (lis3_dev.whoami = WAI_12B) {
+			u16 data[3];
+			lis3->blkread(lis3, OUTX_L, 6, (u8 *)data);
+			for (i = 0; i < 3; i++)
+				position[i] = (s16)le16_to_cpu(data[i]);
+		} else {
+			u8 data[5];
+			/* Data: x, dummy, y, dummy, z */
+			lis3->blkread(lis3, OUTX, 5, data);
+			for (i = 0; i < 3; i++)
+				position[i] = (s8)data[i * 2];
+		}
+	} else {
+		position[0] = lis3->read_data(lis3, OUTX);
+		position[1] = lis3->read_data(lis3, OUTY);
+		position[2] = lis3->read_data(lis3, OUTZ);
+	}
 
 	for (i = 0; i < 3; i++)
 		position[i] = (position[i] * lis3->scale) / LIS3_ACCURACY;
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 2ac27b9..d3cb662 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -225,6 +225,7 @@ struct lis3lv02d {
 	int (*init) (struct lis3lv02d *lis3);
 	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
 	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
+	int (*blkread) (struct lis3lv02d *lis3, int reg, int len, u8 *ret);
 	int (*reg_ctrl) (struct lis3lv02d *lis3, bool state);
 
 	int                     *odrs;     /* Supported output data rates */
diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index 36171bf..61c109b 100644
--- a/drivers/hwmon/lis3lv02d_i2c.c
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -66,6 +66,14 @@ static inline s32 lis3_i2c_read(struct lis3lv02d *lis3, int reg, u8 *v)
 	return 0;
 }
 
+static inline s32 lis3_i2c_blockread(struct lis3lv02d *lis3, int reg, int len,
+				u8 *v)
+{
+	struct i2c_client *c = lis3->bus_priv;
+	reg |= (1 << 7); /* 7th bit enables address auto incrementation */
+	return i2c_smbus_read_i2c_block_data(c, reg, len, v);
+}
+
 static int lis3_i2c_init(struct lis3lv02d *lis3)
 {
 	u8 reg;
@@ -103,6 +111,11 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
 		if (pdata->driver_features & LIS3_USE_REGULATOR_CTRL)
 			lis3_dev.reg_ctrl = lis3_reg_ctrl;
 
+		if ((pdata->driver_features & LIS3_USE_BLOCK_READ) &&
+			(i2c_check_functionality(client->adapter,
+						I2C_FUNC_SMBUS_I2C_BLOCK)))
+			lis3_dev.blkread  = lis3_i2c_blockread;
+
 		if (pdata->axis_x)
 			lis3lv02d_axis_map.x = pdata->axis_x;
 
diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
index 18d578f..c949612 100644
--- a/include/linux/lis3lv02d.h
+++ b/include/linux/lis3lv02d.h
@@ -68,6 +68,7 @@ struct lis3lv02d_platform_data {
 	s8 axis_y;
 	s8 axis_z;
 #define LIS3_USE_REGULATOR_CTRL 0x01
+#define LIS3_USE_BLOCK_READ	0x02
 	u16 driver_features;
 	int default_rate;
 	int (*setup_resources)(void);
-- 
1.6.0.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH 10/12] hwmon: lis3: Enhance lis3 selftest with IRQ line test
  2010-10-22 11:57 ` [lm-sensors] " Samu Onkalo
@ 2010-10-22 11:57   ` Samu Onkalo
  -1 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Configure chip to data ready mode in selftest and count received
interrupts to see that interrupt line(s) are working.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d.c |   87 ++++++++++++++++++++++++++++++++++++++++----
 drivers/hwmon/lis3lv02d.h |    3 +-
 2 files changed, 81 insertions(+), 9 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index 9fd946c..f0343f3 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -48,6 +48,13 @@
 
 #define LIS3_SYSFS_POWERDOWN_DELAY 5000 /* In milliseconds */
 
+#define SELFTEST_OK	       0
+#define SELFTEST_FAIL	       -1
+#define SELFTEST_IRQ	       -2
+
+#define IRQ_LINE0	       0
+#define IRQ_LINE1	       1
+
 /*
  * The sensor can also generate interrupts (DRDY) but it's pretty pointless
  * because they are generated even if the data do not change. So it's better
@@ -198,6 +205,8 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
 	s16 x, y, z;
 	u8 selftest;
 	int ret;
+	u8 ctrl_reg_data;
+	unsigned char irq_cfg;
 
 	mutex_lock(&lis3->mutex);
 	if (lis3_dev.whoami == WAI_12B)
@@ -205,6 +214,20 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
 	else
 		selftest = CTRL1_STP;
 
+	irq_cfg = lis3->irq_cfg;
+	if (lis3_dev.whoami == WAI_8B) {
+		lis3->data_ready_count[IRQ_LINE0] = 0;
+		lis3->data_ready_count[IRQ_LINE1] = 0;
+
+		/* Change interrupt cfg to data ready for selftest */
+		atomic_inc(&lis3_dev.wake_thread);
+		lis3->irq_cfg = LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY;
+		lis3->read(lis3, CTRL_REG3, &ctrl_reg_data);
+		lis3->write(lis3, CTRL_REG3, (ctrl_reg_data &
+				~(LIS3_IRQ1_MASK | LIS3_IRQ2_MASK)) |
+				(LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY));
+	}
+
 	lis3->read(lis3, CTRL_REG1, &reg);
 	lis3->write(lis3, CTRL_REG1, (reg | selftest));
 	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
@@ -223,13 +246,33 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
 	results[2] = z - lis3->read_data(lis3, OUTZ);
 
 	ret = 0;
+
+	if (lis3_dev.whoami == WAI_8B) {
+		/* Restore original interrupt configuration */
+		atomic_dec(&lis3_dev.wake_thread);
+		lis3->write(lis3, CTRL_REG3, ctrl_reg_data);
+		lis3->irq_cfg = irq_cfg;
+
+		if ((irq_cfg & LIS3_IRQ1_MASK) &&
+			lis3->data_ready_count[IRQ_LINE0] < 2) {
+			ret = SELFTEST_IRQ;
+			goto fail;
+		}
+
+		if ((irq_cfg & LIS3_IRQ2_MASK) &&
+			lis3->data_ready_count[IRQ_LINE1] < 2) {
+			ret = SELFTEST_IRQ;
+			goto fail;
+		}
+	}
+
 	if (lis3->pdata) {
 		int i;
 		for (i = 0; i < 3; i++) {
 			/* Check against selftest acceptance limits */
 			if ((results[i] < lis3->pdata->st_min_limits[i]) ||
 			    (results[i] > lis3->pdata->st_max_limits[i])) {
-				ret = -EIO;
+				ret = SELFTEST_FAIL;
 				goto fail;
 			}
 		}
@@ -392,13 +435,24 @@ static void lis302dl_interrupt_handle_click(struct lis3lv02d *lis3)
 	mutex_unlock(&lis3->mutex);
 }
 
-static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
+static inline void lis302dl_data_ready(struct lis3lv02d *lis3, int index)
 {
+	int dummy;
 
+	/* Dummy read to ack interrupt */
+	lis3lv02d_get_xyz(lis3, &dummy, &dummy, &dummy);
+	lis3->data_ready_count[index]++;
+}
+
+static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
+{
 	struct lis3lv02d *lis3 = data;
+	u8 irq_cfg = lis3->irq_cfg & LIS3_IRQ1_MASK;
 
-	if ((lis3->irq_cfg & LIS3_IRQ1_MASK) == LIS3_IRQ1_CLICK)
+	if (irq_cfg == LIS3_IRQ1_CLICK)
 		lis302dl_interrupt_handle_click(lis3);
+	else if (unlikely(irq_cfg == LIS3_IRQ1_DATA_READY))
+		lis302dl_data_ready(lis3, IRQ_LINE0);
 	else
 		lis3lv02d_joystick_poll(lis3->idev);
 
@@ -407,11 +461,13 @@ static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
 
 static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data)
 {
-
 	struct lis3lv02d *lis3 = data;
+	u8 irq_cfg = lis3->irq_cfg & LIS3_IRQ2_MASK;
 
-	if ((lis3->irq_cfg & LIS3_IRQ2_MASK) == LIS3_IRQ2_CLICK)
+	if (irq_cfg == LIS3_IRQ2_CLICK)
 		lis302dl_interrupt_handle_click(lis3);
+	else if (unlikely(irq_cfg == LIS3_IRQ2_DATA_READY))
+		lis302dl_data_ready(lis3, IRQ_LINE1);
 	else
 		lis3lv02d_joystick_poll(lis3->idev);
 
@@ -614,12 +670,27 @@ static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3)
 static ssize_t lis3lv02d_selftest_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
-	int result;
 	s16 values[3];
 
+	static const char ok[] = "OK";
+	static const char fail[] = "FAIL";
+	static const char irq[] = "FAIL_IRQ";
+	const char *res;
+
 	lis3lv02d_sysfs_poweron(&lis3_dev);
-	result = lis3lv02d_selftest(&lis3_dev, values);
-	return sprintf(buf, "%s %d %d %d\n", result == 0 ? "OK" : "FAIL",
+	switch (lis3lv02d_selftest(&lis3_dev, values)) {
+	case SELFTEST_FAIL:
+		res = fail;
+		break;
+	case SELFTEST_IRQ:
+		res = irq;
+		break;
+	case SELFTEST_OK:
+	default:
+		res = ok;
+		break;
+	}
+	return sprintf(buf, "%s %d %d %d\n", res,
 		values[0], values[1], values[2]);
 }
 
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index d3cb662..7b22cd9 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -254,7 +254,8 @@ struct lis3lv02d {
 	struct fasync_struct	*async_queue; /* queue for the misc device */
 	wait_queue_head_t	misc_wait; /* Wait queue for the misc device */
 	unsigned long		misc_opened; /* bit0: whether the device is open */
-	atomic_t                wake_thread;
+	int                     data_ready_count[2];
+	atomic_t		wake_thread;
 	unsigned char           irq_cfg;
 
 	struct lis3lv02d_platform_data *pdata;	/* for passing board config */
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [lm-sensors] [PATCH 10/12] hwmon: lis3: Enhance lis3 selftest with
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Configure chip to data ready mode in selftest and count received
interrupts to see that interrupt line(s) are working.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d.c |   87 ++++++++++++++++++++++++++++++++++++++++----
 drivers/hwmon/lis3lv02d.h |    3 +-
 2 files changed, 81 insertions(+), 9 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index 9fd946c..f0343f3 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -48,6 +48,13 @@
 
 #define LIS3_SYSFS_POWERDOWN_DELAY 5000 /* In milliseconds */
 
+#define SELFTEST_OK	       0
+#define SELFTEST_FAIL	       -1
+#define SELFTEST_IRQ	       -2
+
+#define IRQ_LINE0	       0
+#define IRQ_LINE1	       1
+
 /*
  * The sensor can also generate interrupts (DRDY) but it's pretty pointless
  * because they are generated even if the data do not change. So it's better
@@ -198,6 +205,8 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
 	s16 x, y, z;
 	u8 selftest;
 	int ret;
+	u8 ctrl_reg_data;
+	unsigned char irq_cfg;
 
 	mutex_lock(&lis3->mutex);
 	if (lis3_dev.whoami = WAI_12B)
@@ -205,6 +214,20 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
 	else
 		selftest = CTRL1_STP;
 
+	irq_cfg = lis3->irq_cfg;
+	if (lis3_dev.whoami = WAI_8B) {
+		lis3->data_ready_count[IRQ_LINE0] = 0;
+		lis3->data_ready_count[IRQ_LINE1] = 0;
+
+		/* Change interrupt cfg to data ready for selftest */
+		atomic_inc(&lis3_dev.wake_thread);
+		lis3->irq_cfg = LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY;
+		lis3->read(lis3, CTRL_REG3, &ctrl_reg_data);
+		lis3->write(lis3, CTRL_REG3, (ctrl_reg_data &
+				~(LIS3_IRQ1_MASK | LIS3_IRQ2_MASK)) |
+				(LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY));
+	}
+
 	lis3->read(lis3, CTRL_REG1, &reg);
 	lis3->write(lis3, CTRL_REG1, (reg | selftest));
 	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
@@ -223,13 +246,33 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
 	results[2] = z - lis3->read_data(lis3, OUTZ);
 
 	ret = 0;
+
+	if (lis3_dev.whoami = WAI_8B) {
+		/* Restore original interrupt configuration */
+		atomic_dec(&lis3_dev.wake_thread);
+		lis3->write(lis3, CTRL_REG3, ctrl_reg_data);
+		lis3->irq_cfg = irq_cfg;
+
+		if ((irq_cfg & LIS3_IRQ1_MASK) &&
+			lis3->data_ready_count[IRQ_LINE0] < 2) {
+			ret = SELFTEST_IRQ;
+			goto fail;
+		}
+
+		if ((irq_cfg & LIS3_IRQ2_MASK) &&
+			lis3->data_ready_count[IRQ_LINE1] < 2) {
+			ret = SELFTEST_IRQ;
+			goto fail;
+		}
+	}
+
 	if (lis3->pdata) {
 		int i;
 		for (i = 0; i < 3; i++) {
 			/* Check against selftest acceptance limits */
 			if ((results[i] < lis3->pdata->st_min_limits[i]) ||
 			    (results[i] > lis3->pdata->st_max_limits[i])) {
-				ret = -EIO;
+				ret = SELFTEST_FAIL;
 				goto fail;
 			}
 		}
@@ -392,13 +435,24 @@ static void lis302dl_interrupt_handle_click(struct lis3lv02d *lis3)
 	mutex_unlock(&lis3->mutex);
 }
 
-static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
+static inline void lis302dl_data_ready(struct lis3lv02d *lis3, int index)
 {
+	int dummy;
 
+	/* Dummy read to ack interrupt */
+	lis3lv02d_get_xyz(lis3, &dummy, &dummy, &dummy);
+	lis3->data_ready_count[index]++;
+}
+
+static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
+{
 	struct lis3lv02d *lis3 = data;
+	u8 irq_cfg = lis3->irq_cfg & LIS3_IRQ1_MASK;
 
-	if ((lis3->irq_cfg & LIS3_IRQ1_MASK) = LIS3_IRQ1_CLICK)
+	if (irq_cfg = LIS3_IRQ1_CLICK)
 		lis302dl_interrupt_handle_click(lis3);
+	else if (unlikely(irq_cfg = LIS3_IRQ1_DATA_READY))
+		lis302dl_data_ready(lis3, IRQ_LINE0);
 	else
 		lis3lv02d_joystick_poll(lis3->idev);
 
@@ -407,11 +461,13 @@ static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
 
 static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data)
 {
-
 	struct lis3lv02d *lis3 = data;
+	u8 irq_cfg = lis3->irq_cfg & LIS3_IRQ2_MASK;
 
-	if ((lis3->irq_cfg & LIS3_IRQ2_MASK) = LIS3_IRQ2_CLICK)
+	if (irq_cfg = LIS3_IRQ2_CLICK)
 		lis302dl_interrupt_handle_click(lis3);
+	else if (unlikely(irq_cfg = LIS3_IRQ2_DATA_READY))
+		lis302dl_data_ready(lis3, IRQ_LINE1);
 	else
 		lis3lv02d_joystick_poll(lis3->idev);
 
@@ -614,12 +670,27 @@ static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3)
 static ssize_t lis3lv02d_selftest_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
-	int result;
 	s16 values[3];
 
+	static const char ok[] = "OK";
+	static const char fail[] = "FAIL";
+	static const char irq[] = "FAIL_IRQ";
+	const char *res;
+
 	lis3lv02d_sysfs_poweron(&lis3_dev);
-	result = lis3lv02d_selftest(&lis3_dev, values);
-	return sprintf(buf, "%s %d %d %d\n", result = 0 ? "OK" : "FAIL",
+	switch (lis3lv02d_selftest(&lis3_dev, values)) {
+	case SELFTEST_FAIL:
+		res = fail;
+		break;
+	case SELFTEST_IRQ:
+		res = irq;
+		break;
+	case SELFTEST_OK:
+	default:
+		res = ok;
+		break;
+	}
+	return sprintf(buf, "%s %d %d %d\n", res,
 		values[0], values[1], values[2]);
 }
 
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index d3cb662..7b22cd9 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -254,7 +254,8 @@ struct lis3lv02d {
 	struct fasync_struct	*async_queue; /* queue for the misc device */
 	wait_queue_head_t	misc_wait; /* Wait queue for the misc device */
 	unsigned long		misc_opened; /* bit0: whether the device is open */
-	atomic_t                wake_thread;
+	int                     data_ready_count[2];
+	atomic_t		wake_thread;
 	unsigned char           irq_cfg;
 
 	struct lis3lv02d_platform_data *pdata;	/* for passing board config */
-- 
1.6.0.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH 11/12] hwmon: lis3: Short explanations of platform data fields
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Short documentation at kernel doc format.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 include/linux/lis3lv02d.h |   41 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
index c949612..da294cd 100644
--- a/include/linux/lis3lv02d.h
+++ b/include/linux/lis3lv02d.h
@@ -1,6 +1,47 @@
 #ifndef __LIS3LV02D_H_
 #define __LIS3LV02D_H_
 
+/**
+ * struct lis3lv02d_platform_data - lis3 chip family platform data
+ * @click_flags:       Click detection unit configuration
+ * @click_thresh_x:    Click detection unit x axis treshold
+ * @click_thresh_y:    Click detection unit y axis treshold
+ * @click_thresh_z:    Click detection unit z axis treshold
+ * @click_time_limit:  Click detection unit time parameter
+ * @click_latency:     Click detection unit latency parameter
+ * @click_window:      Click detection unit window parameter
+ * @irq_cfg:	       On chip irq configuration (click / data available / wu)
+ * @irq_flags1:	       Additional irq triggering flags for irq channel 0
+ * @irq_flags2:	       Additional irq triggering flags for irq channel 1
+ * @duration1:	       Wake up unit 1 duration parameter
+ * @duration2:	       Wake up unit 2 duration parameter
+ * @wakeup_flags:      Wakeup unit 1 flags
+ * @wakeup_thresh:     Wakeup unit 1 threshold value
+ * @wakeup_flags2:     Wakeup unit 2 flags
+ * @wakeup_thresh2:    Wakeup unit 2 threshold value
+ * @hipass_ctrl:       Hi-pass filter control
+ * @axis_x:	       Remap parameter for x-axis
+ * @axis_y:	       Remap parameter for y-axis
+ * @axis_z:	       Remap parameter for z-axis
+ * @driver_features:   Enable bits for different features. Disabled by default
+ * @default_rate:      Default sampling rate. 0 means reset default
+ * @setup_resources:   Interrupt line setup call back function
+ * @release_resources: Interrupt line release call back function
+ * @st_min_limits[3]:  Selftest acceptance minimum values
+ * @st_max_limits[3]:  Selftest accepratnce maximum values
+ * @irq2:	       Irq line 2 number
+ *
+ * Platform data is used to setup the sensor chip. Meaning of the different
+ * chip features can be found from the data sheet. Currently the data is used
+ * only for the 8 bit device. The 8 bit device has two wake up / free fall
+ * detection units and click detection unit. There are plenty of ways to
+ * configure the chip which makes is quite impossible to explain meaning of the
+ * fields here. Behaviour of the detection blocks varies heavily depending
+ * on the configuration. Irq_flags can be used to enable interrupt detection
+ * on the both edges. With proper chip configuration this produces interrupt
+ * when some trigger starts and when it goes away.
+ */
+
 struct lis3lv02d_platform_data {
 	/* please note: the 'click' feature is only supported for
 	 * LIS[32]02DL variants of the chip and will be ignored for
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH 11/12] hwmon: lis3: Short explanations of platform data fields
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel-VkQ1JFuSMpfAbQlEx87xDw, khali-PUYAD+kWke1g9hUCZPvPmw,
	guenter.roeck-IzeFyvvaP7pWk0Htik3J/w,
	jic23-KWPb1pKIrIJaa/9Udqfwiw
  Cc: lm-sensors-GZX6beZjE8VD60Wz+7aTrA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Short documentation at kernel doc format.

Signed-off-by: Samu Onkalo <samu.p.onkalo-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
---
 include/linux/lis3lv02d.h |   41 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
index c949612..da294cd 100644
--- a/include/linux/lis3lv02d.h
+++ b/include/linux/lis3lv02d.h
@@ -1,6 +1,47 @@
 #ifndef __LIS3LV02D_H_
 #define __LIS3LV02D_H_
 
+/**
+ * struct lis3lv02d_platform_data - lis3 chip family platform data
+ * @click_flags:       Click detection unit configuration
+ * @click_thresh_x:    Click detection unit x axis treshold
+ * @click_thresh_y:    Click detection unit y axis treshold
+ * @click_thresh_z:    Click detection unit z axis treshold
+ * @click_time_limit:  Click detection unit time parameter
+ * @click_latency:     Click detection unit latency parameter
+ * @click_window:      Click detection unit window parameter
+ * @irq_cfg:	       On chip irq configuration (click / data available / wu)
+ * @irq_flags1:	       Additional irq triggering flags for irq channel 0
+ * @irq_flags2:	       Additional irq triggering flags for irq channel 1
+ * @duration1:	       Wake up unit 1 duration parameter
+ * @duration2:	       Wake up unit 2 duration parameter
+ * @wakeup_flags:      Wakeup unit 1 flags
+ * @wakeup_thresh:     Wakeup unit 1 threshold value
+ * @wakeup_flags2:     Wakeup unit 2 flags
+ * @wakeup_thresh2:    Wakeup unit 2 threshold value
+ * @hipass_ctrl:       Hi-pass filter control
+ * @axis_x:	       Remap parameter for x-axis
+ * @axis_y:	       Remap parameter for y-axis
+ * @axis_z:	       Remap parameter for z-axis
+ * @driver_features:   Enable bits for different features. Disabled by default
+ * @default_rate:      Default sampling rate. 0 means reset default
+ * @setup_resources:   Interrupt line setup call back function
+ * @release_resources: Interrupt line release call back function
+ * @st_min_limits[3]:  Selftest acceptance minimum values
+ * @st_max_limits[3]:  Selftest accepratnce maximum values
+ * @irq2:	       Irq line 2 number
+ *
+ * Platform data is used to setup the sensor chip. Meaning of the different
+ * chip features can be found from the data sheet. Currently the data is used
+ * only for the 8 bit device. The 8 bit device has two wake up / free fall
+ * detection units and click detection unit. There are plenty of ways to
+ * configure the chip which makes is quite impossible to explain meaning of the
+ * fields here. Behaviour of the detection blocks varies heavily depending
+ * on the configuration. Irq_flags can be used to enable interrupt detection
+ * on the both edges. With proper chip configuration this produces interrupt
+ * when some trigger starts and when it goes away.
+ */
+
 struct lis3lv02d_platform_data {
 	/* please note: the 'click' feature is only supported for
 	 * LIS[32]02DL variants of the chip and will be ignored for
-- 
1.6.0.4

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [lm-sensors] [PATCH 11/12] hwmon: lis3: Short explanations of
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

Short documentation at kernel doc format.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 include/linux/lis3lv02d.h |   41 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
index c949612..da294cd 100644
--- a/include/linux/lis3lv02d.h
+++ b/include/linux/lis3lv02d.h
@@ -1,6 +1,47 @@
 #ifndef __LIS3LV02D_H_
 #define __LIS3LV02D_H_
 
+/**
+ * struct lis3lv02d_platform_data - lis3 chip family platform data
+ * @click_flags:       Click detection unit configuration
+ * @click_thresh_x:    Click detection unit x axis treshold
+ * @click_thresh_y:    Click detection unit y axis treshold
+ * @click_thresh_z:    Click detection unit z axis treshold
+ * @click_time_limit:  Click detection unit time parameter
+ * @click_latency:     Click detection unit latency parameter
+ * @click_window:      Click detection unit window parameter
+ * @irq_cfg:	       On chip irq configuration (click / data available / wu)
+ * @irq_flags1:	       Additional irq triggering flags for irq channel 0
+ * @irq_flags2:	       Additional irq triggering flags for irq channel 1
+ * @duration1:	       Wake up unit 1 duration parameter
+ * @duration2:	       Wake up unit 2 duration parameter
+ * @wakeup_flags:      Wakeup unit 1 flags
+ * @wakeup_thresh:     Wakeup unit 1 threshold value
+ * @wakeup_flags2:     Wakeup unit 2 flags
+ * @wakeup_thresh2:    Wakeup unit 2 threshold value
+ * @hipass_ctrl:       Hi-pass filter control
+ * @axis_x:	       Remap parameter for x-axis
+ * @axis_y:	       Remap parameter for y-axis
+ * @axis_z:	       Remap parameter for z-axis
+ * @driver_features:   Enable bits for different features. Disabled by default
+ * @default_rate:      Default sampling rate. 0 means reset default
+ * @setup_resources:   Interrupt line setup call back function
+ * @release_resources: Interrupt line release call back function
+ * @st_min_limits[3]:  Selftest acceptance minimum values
+ * @st_max_limits[3]:  Selftest accepratnce maximum values
+ * @irq2:	       Irq line 2 number
+ *
+ * Platform data is used to setup the sensor chip. Meaning of the different
+ * chip features can be found from the data sheet. Currently the data is used
+ * only for the 8 bit device. The 8 bit device has two wake up / free fall
+ * detection units and click detection unit. There are plenty of ways to
+ * configure the chip which makes is quite impossible to explain meaning of the
+ * fields here. Behaviour of the detection blocks varies heavily depending
+ * on the configuration. Irq_flags can be used to enable interrupt detection
+ * on the both edges. With proper chip configuration this produces interrupt
+ * when some trigger starts and when it goes away.
+ */
+
 struct lis3lv02d_platform_data {
 	/* please note: the 'click' feature is only supported for
 	 * LIS[32]02DL variants of the chip and will be ignored for
-- 
1.6.0.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH 12/12] hwmon: lis3: Release resources is case of failure
  2010-10-22 11:57 ` [lm-sensors] " Samu Onkalo
  (?)
@ 2010-10-22 11:57   ` Samu Onkalo
  -1 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

If lis3lv02d_init_device fails, HW resources were not released
properly. In case of failure call release_resources if available.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d_i2c.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index 61c109b..94d5bde 100644
--- a/drivers/hwmon/lis3lv02d_i2c.c
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -161,7 +161,12 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
 
 	if (lis3_dev.reg_ctrl)
 		lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF);
+
+	if (ret == 0)
+		return 0;
 fail:
+	if (pdata && pdata->release_resources)
+		pdata->release_resources();
 	return ret;
 }
 
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [PATCH 12/12] hwmon: lis3: Release resources is case of failure
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: linux-kernel, linux-i2c, lm-sensors

If lis3lv02d_init_device fails, HW resources were not released
properly. In case of failure call release_resources if available.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d_i2c.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index 61c109b..94d5bde 100644
--- a/drivers/hwmon/lis3lv02d_i2c.c
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -161,7 +161,12 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
 
 	if (lis3_dev.reg_ctrl)
 		lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF);
+
+	if (ret == 0)
+		return 0;
 fail:
+	if (pdata && pdata->release_resources)
+		pdata->release_resources();
 	return ret;
 }
 
-- 
1.6.0.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [lm-sensors] [PATCH 12/12] hwmon: lis3: Release resources is case
@ 2010-10-22 11:57   ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-22 11:57 UTC (permalink / raw)
  To: eric.piel, khali, guenter.roeck, jic23
  Cc: lm-sensors, linux-i2c, linux-kernel

If lis3lv02d_init_device fails, HW resources were not released
properly. In case of failure call release_resources if available.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 drivers/hwmon/lis3lv02d_i2c.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index 61c109b..94d5bde 100644
--- a/drivers/hwmon/lis3lv02d_i2c.c
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -161,7 +161,12 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
 
 	if (lis3_dev.reg_ctrl)
 		lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF);
+
+	if (ret = 0)
+		return 0;
 fail:
+	if (pdata && pdata->release_resources)
+		pdata->release_resources();
 	return ret;
 }
 
-- 
1.6.0.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [PATCH 02/12] hwmon: lis3: regulator control
@ 2010-10-22 16:11     ` Jonathan Cameron
  0 siblings, 0 replies; 101+ messages in thread
From: Jonathan Cameron @ 2010-10-22 16:11 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: eric.piel, khali, guenter.roeck, lm-sensors, linux-i2c, linux-kernel

On 10/22/10 12:57, Samu Onkalo wrote:
> Based on pm_runtime control, turn lis3 regulators on and off.
> Perform context save and restore on transitions.
> 
> Feature is optional and must be enabled in platform data.
Answers all my queries on the previous version
> 
> Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
> ---
>  drivers/hwmon/lis3lv02d.c     |   52 ++++++++++++++++++++++++++++++++++++++
>  drivers/hwmon/lis3lv02d.h     |   12 +++++++++
>  drivers/hwmon/lis3lv02d_i2c.c |   55 ++++++++++++++++++++++++++++++++++++++++-
>  include/linux/lis3lv02d.h     |    2 +
>  4 files changed, 120 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index 412ddc3..ade6f3a 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -31,6 +31,7 @@
>  #include <linux/delay.h>
>  #include <linux/wait.h>
>  #include <linux/poll.h>
> +#include <linux/slab.h>
>  #include <linux/freezer.h>
>  #include <linux/uaccess.h>
>  #include <linux/miscdevice.h>
> @@ -223,10 +224,46 @@ fail:
>  	return ret;
>  }
>  
> +/*
> + * Order of registers in the list affects to order of the restore process.
> + * Perhaps it is a good idea to set interrupt enable register as a last one
> + * after all other configurations
> + */
> +static u8 lis3_wai8_regs[] = { FF_WU_CFG_1, FF_WU_THS_1, FF_WU_DURATION_1,
> +			       FF_WU_CFG_2, FF_WU_THS_2, FF_WU_DURATION_2,
> +			       CLICK_CFG, CLICK_SRC, CLICK_THSY_X, CLICK_THSZ,
> +			       CLICK_TIMELIMIT, CLICK_LATENCY, CLICK_WINDOW,
> +			       CTRL_REG1, CTRL_REG2, CTRL_REG3};
> +
> +static u8 lis3_wai12_regs[] = {FF_WU_CFG, FF_WU_THS_L, FF_WU_THS_H,
> +			       FF_WU_DURATION, DD_CFG, DD_THSI_L, DD_THSI_H,
> +			       DD_THSE_L, DD_THSE_H,
> +			       CTRL_REG1, CTRL_REG3, CTRL_REG2};
> +
> +static inline void lis3_context_save(struct lis3lv02d *lis3)
> +{
> +	int i;
> +	for (i = 0; i < lis3->regs_size; i++)
> +		lis3->read(lis3, lis3->regs[i], &lis3->reg_cache[i]);
> +	lis3->regs_stored = true;
> +}
> +
> +static inline void lis3_context_restore(struct lis3lv02d *lis3)
> +{
> +	int i;
> +	if (lis3->regs_stored)
> +		for (i = 0; i < lis3->regs_size; i++)
> +			lis3->write(lis3, lis3->regs[i], lis3->reg_cache[i]);
> +}
> +
>  void lis3lv02d_poweroff(struct lis3lv02d *lis3)
>  {
> +	if (lis3->reg_ctrl)
> +		lis3_context_save(lis3);
>  	/* disable X,Y,Z axis and power down */
>  	lis3->write(lis3, CTRL_REG1, 0x00);
> +	if (lis3->reg_ctrl)
> +		lis3->reg_ctrl(lis3, LIS3_REG_OFF);
>  }
>  EXPORT_SYMBOL_GPL(lis3lv02d_poweroff);
>  
> @@ -249,6 +286,8 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3)
>  		reg |= CTRL2_BDU;
>  		lis3->write(lis3, CTRL_REG2, reg);
>  	}
> +	if (lis3->reg_ctrl)
> +		lis3_context_restore(lis3);
>  }
>  EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
>  
> @@ -640,6 +679,7 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
>  		pm_runtime_disable(lis3->pm_dev);
>  		pm_runtime_set_suspended(lis3->pm_dev);
>  	}
> +	kfree(lis3->reg_cache);
>  	return 0;
>  }
>  EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
> @@ -719,6 +759,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  		dev->odrs = lis3_12_rates;
>  		dev->odr_mask = CTRL1_DF0 | CTRL1_DF1;
>  		dev->scale = LIS3_SENSITIVITY_12B;
> +		dev->regs = lis3_wai12_regs;
> +		dev->regs_size = ARRAY_SIZE(lis3_wai12_regs);
>  		break;
>  	case WAI_8B:
>  		printk(KERN_INFO DRIVER_NAME ": 8 bits sensor found\n");
> @@ -728,6 +770,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  		dev->odrs = lis3_8_rates;
>  		dev->odr_mask = CTRL1_DR;
>  		dev->scale = LIS3_SENSITIVITY_8B;
> +		dev->regs = lis3_wai8_regs;
> +		dev->regs_size = ARRAY_SIZE(lis3_wai8_regs);
>  		break;
>  	default:
>  		printk(KERN_ERR DRIVER_NAME
> @@ -735,6 +779,14 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  		return -EINVAL;
>  	}
>  
> +	dev->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs),
> +				     sizeof(lis3_wai12_regs)), GFP_KERNEL);
> +
> +	if (dev->reg_cache == NULL) {
> +		printk(KERN_ERR DRIVER_NAME "out of memory\n");
> +		return -ENOMEM;
> +	}
> +
>  	mutex_init(&dev->mutex);
>  
>  	lis3lv02d_add_fs(dev);
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 3e8a208..7661e59 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -20,6 +20,7 @@
>   */
>  #include <linux/platform_device.h>
>  #include <linux/input-polldev.h>
> +#include <linux/regulator/consumer.h>
>  
>  /*
>   * This driver tries to support the "digital" accelerometer chips from
> @@ -206,6 +207,11 @@ enum lis3lv02d_click_src_8b {
>  	CLICK_IA	= 0x40,
>  };
>  
> +enum lis3lv02d_reg_state {
> +	LIS3_REG_OFF	= 0x00,
> +	LIS3_REG_ON	= 0x01,
> +};
> +
>  struct axis_conversion {
>  	s8	x;
>  	s8	y;
> @@ -218,8 +224,13 @@ struct lis3lv02d {
>  	int (*init) (struct lis3lv02d *lis3);
>  	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
>  	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
> +	int (*reg_ctrl) (struct lis3lv02d *lis3, bool state);
>  
>  	int                     *odrs;     /* Supported output data rates */
> +	u8			*regs;	   /* Regs to store / restore */
> +	int			regs_size;
> +	u8                      *reg_cache;
> +	bool			regs_stored;
>  	u8                      odr_mask;  /* ODR bit mask */
>  	u8			whoami;    /* indicates measurement precision */
>  	s16 (*read_data) (struct lis3lv02d *lis3, int reg);
> @@ -232,6 +243,7 @@ struct lis3lv02d {
>  
>  	struct input_polled_dev	*idev;     /* input device */
>  	struct platform_device	*pdev;     /* platform device */
> +	struct regulator_bulk_data regulators[2];
>  	atomic_t		count;     /* interrupt count after last read */
>  	struct axis_conversion	ac;        /* hw -> logical axis */
>  	int			mapped_btns[3];
> diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
> index 6e965d7..98983cc 100644
> --- a/drivers/hwmon/lis3lv02d_i2c.c
> +++ b/drivers/hwmon/lis3lv02d_i2c.c
> @@ -30,10 +30,29 @@
>  #include <linux/err.h>
>  #include <linux/i2c.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/delay.h>
>  #include "lis3lv02d.h"
>  
>  #define DRV_NAME 	"lis3lv02d_i2c"
>  
> +static const char reg_vdd[]    = "Vdd";
> +static const char reg_vdd_io[] = "Vdd_IO";
> +
> +static int lis3_reg_ctrl(struct lis3lv02d *lis3, bool state)
> +{
> +	int ret;
> +	if (state == LIS3_REG_OFF) {
> +		ret = regulator_bulk_disable(ARRAY_SIZE(lis3->regulators),
> +					lis3->regulators);
> +	} else {
> +		ret = regulator_bulk_enable(ARRAY_SIZE(lis3->regulators),
> +					lis3->regulators);
> +		/* Chip needs time to wakeup. Not mentioned in datasheet */
> +		usleep_range(10000, 20000);
> +	}
> +	return ret;
> +}
> +
>  static inline s32 lis3_i2c_write(struct lis3lv02d *lis3, int reg, u8 value)
>  {
>  	struct i2c_client *c = lis3->bus_priv;
> @@ -52,6 +71,13 @@ static int lis3_i2c_init(struct lis3lv02d *lis3)
>  	u8 reg;
>  	int ret;
>  
> +	if (lis3->reg_ctrl)
> +		lis3_reg_ctrl(lis3, LIS3_REG_ON);
> +
> +	lis3->read(lis3, WHO_AM_I, &reg);
> +	if (reg != lis3->whoami)
> +		printk(KERN_ERR "lis3: power on failure\n");
> +
>  	/* power up the device */
>  	ret = lis3->read(lis3, CTRL_REG1, &reg);
>  	if (ret < 0)
> @@ -73,6 +99,10 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>  	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
>  
>  	if (pdata) {
> +		/* Regulator control is optional */
> +		if (pdata->driver_features & LIS3_USE_REGULATOR_CTRL)
> +			lis3_dev.reg_ctrl = lis3_reg_ctrl;
> +
>  		if (pdata->axis_x)
>  			lis3lv02d_axis_map.x = pdata->axis_x;
>  
> @@ -89,6 +119,16 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>  			goto fail;
>  	}
>  
> +	if (lis3_dev.reg_ctrl) {
> +		lis3_dev.regulators[0].supply = reg_vdd;
> +		lis3_dev.regulators[1].supply = reg_vdd_io;
> +		ret = regulator_bulk_get(&client->dev,
> +					ARRAY_SIZE(lis3_dev.regulators),
> +					lis3_dev.regulators);
> +		if (ret < 0)
> +			goto fail;
> +	}
> +
>  	lis3_dev.pdata	  = pdata;
>  	lis3_dev.bus_priv = client;
>  	lis3_dev.init	  = lis3_i2c_init;
> @@ -99,21 +139,34 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>  	lis3_dev.pm_dev	  = &client->dev;
>  
>  	i2c_set_clientdata(client, &lis3_dev);
> +
> +	/* Provide power over the init call */
> +	if (lis3_dev.reg_ctrl)
> +		lis3_reg_ctrl(&lis3_dev, LIS3_REG_ON);
> +
>  	ret = lis3lv02d_init_device(&lis3_dev);
> +
> +	if (lis3_dev.reg_ctrl)
> +		lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF);
>  fail:
>  	return ret;
>  }
>  
>  static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
>  {
> +	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>  	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
>  
>  	if (pdata && pdata->release_resources)
>  		pdata->release_resources();
>  
>  	lis3lv02d_joystick_disable();
> +	lis3lv02d_remove_fs(&lis3_dev);
>  
> -	return lis3lv02d_remove_fs(&lis3_dev);
> +	if (lis3_dev.reg_ctrl)
> +		regulator_bulk_free(ARRAY_SIZE(lis3->regulators),
> +				lis3_dev.regulators);
> +	return 0;
>  }
>  
>  #ifdef CONFIG_PM
> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
> index 0e8a346..c4a4a52 100644
> --- a/include/linux/lis3lv02d.h
> +++ b/include/linux/lis3lv02d.h
> @@ -64,6 +64,8 @@ struct lis3lv02d_platform_data {
>  	s8 axis_x;
>  	s8 axis_y;
>  	s8 axis_z;
> +#define LIS3_USE_REGULATOR_CTRL 0x01
> +	u16 driver_features;
>  	int (*setup_resources)(void);
>  	int (*release_resources)(void);
>  	/* Limits for selftest are specified in chip data sheet */


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 02/12] hwmon: lis3: regulator control
@ 2010-10-22 16:11     ` Jonathan Cameron
  0 siblings, 0 replies; 101+ messages in thread
From: Jonathan Cameron @ 2010-10-22 16:11 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: eric.piel-VkQ1JFuSMpfAbQlEx87xDw, khali-PUYAD+kWke1g9hUCZPvPmw,
	guenter.roeck-IzeFyvvaP7pWk0Htik3J/w,
	lm-sensors-GZX6beZjE8VD60Wz+7aTrA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 10/22/10 12:57, Samu Onkalo wrote:
> Based on pm_runtime control, turn lis3 regulators on and off.
> Perform context save and restore on transitions.
> 
> Feature is optional and must be enabled in platform data.
Answers all my queries on the previous version
> 
> Signed-off-by: Samu Onkalo <samu.p.onkalo-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
Acked-by: Jonathan Cameron <jic23-KWPb1pKIrIJaa/9Udqfwiw@public.gmane.org>
> ---
>  drivers/hwmon/lis3lv02d.c     |   52 ++++++++++++++++++++++++++++++++++++++
>  drivers/hwmon/lis3lv02d.h     |   12 +++++++++
>  drivers/hwmon/lis3lv02d_i2c.c |   55 ++++++++++++++++++++++++++++++++++++++++-
>  include/linux/lis3lv02d.h     |    2 +
>  4 files changed, 120 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index 412ddc3..ade6f3a 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -31,6 +31,7 @@
>  #include <linux/delay.h>
>  #include <linux/wait.h>
>  #include <linux/poll.h>
> +#include <linux/slab.h>
>  #include <linux/freezer.h>
>  #include <linux/uaccess.h>
>  #include <linux/miscdevice.h>
> @@ -223,10 +224,46 @@ fail:
>  	return ret;
>  }
>  
> +/*
> + * Order of registers in the list affects to order of the restore process.
> + * Perhaps it is a good idea to set interrupt enable register as a last one
> + * after all other configurations
> + */
> +static u8 lis3_wai8_regs[] = { FF_WU_CFG_1, FF_WU_THS_1, FF_WU_DURATION_1,
> +			       FF_WU_CFG_2, FF_WU_THS_2, FF_WU_DURATION_2,
> +			       CLICK_CFG, CLICK_SRC, CLICK_THSY_X, CLICK_THSZ,
> +			       CLICK_TIMELIMIT, CLICK_LATENCY, CLICK_WINDOW,
> +			       CTRL_REG1, CTRL_REG2, CTRL_REG3};
> +
> +static u8 lis3_wai12_regs[] = {FF_WU_CFG, FF_WU_THS_L, FF_WU_THS_H,
> +			       FF_WU_DURATION, DD_CFG, DD_THSI_L, DD_THSI_H,
> +			       DD_THSE_L, DD_THSE_H,
> +			       CTRL_REG1, CTRL_REG3, CTRL_REG2};
> +
> +static inline void lis3_context_save(struct lis3lv02d *lis3)
> +{
> +	int i;
> +	for (i = 0; i < lis3->regs_size; i++)
> +		lis3->read(lis3, lis3->regs[i], &lis3->reg_cache[i]);
> +	lis3->regs_stored = true;
> +}
> +
> +static inline void lis3_context_restore(struct lis3lv02d *lis3)
> +{
> +	int i;
> +	if (lis3->regs_stored)
> +		for (i = 0; i < lis3->regs_size; i++)
> +			lis3->write(lis3, lis3->regs[i], lis3->reg_cache[i]);
> +}
> +
>  void lis3lv02d_poweroff(struct lis3lv02d *lis3)
>  {
> +	if (lis3->reg_ctrl)
> +		lis3_context_save(lis3);
>  	/* disable X,Y,Z axis and power down */
>  	lis3->write(lis3, CTRL_REG1, 0x00);
> +	if (lis3->reg_ctrl)
> +		lis3->reg_ctrl(lis3, LIS3_REG_OFF);
>  }
>  EXPORT_SYMBOL_GPL(lis3lv02d_poweroff);
>  
> @@ -249,6 +286,8 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3)
>  		reg |= CTRL2_BDU;
>  		lis3->write(lis3, CTRL_REG2, reg);
>  	}
> +	if (lis3->reg_ctrl)
> +		lis3_context_restore(lis3);
>  }
>  EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
>  
> @@ -640,6 +679,7 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
>  		pm_runtime_disable(lis3->pm_dev);
>  		pm_runtime_set_suspended(lis3->pm_dev);
>  	}
> +	kfree(lis3->reg_cache);
>  	return 0;
>  }
>  EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
> @@ -719,6 +759,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  		dev->odrs = lis3_12_rates;
>  		dev->odr_mask = CTRL1_DF0 | CTRL1_DF1;
>  		dev->scale = LIS3_SENSITIVITY_12B;
> +		dev->regs = lis3_wai12_regs;
> +		dev->regs_size = ARRAY_SIZE(lis3_wai12_regs);
>  		break;
>  	case WAI_8B:
>  		printk(KERN_INFO DRIVER_NAME ": 8 bits sensor found\n");
> @@ -728,6 +770,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  		dev->odrs = lis3_8_rates;
>  		dev->odr_mask = CTRL1_DR;
>  		dev->scale = LIS3_SENSITIVITY_8B;
> +		dev->regs = lis3_wai8_regs;
> +		dev->regs_size = ARRAY_SIZE(lis3_wai8_regs);
>  		break;
>  	default:
>  		printk(KERN_ERR DRIVER_NAME
> @@ -735,6 +779,14 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  		return -EINVAL;
>  	}
>  
> +	dev->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs),
> +				     sizeof(lis3_wai12_regs)), GFP_KERNEL);
> +
> +	if (dev->reg_cache == NULL) {
> +		printk(KERN_ERR DRIVER_NAME "out of memory\n");
> +		return -ENOMEM;
> +	}
> +
>  	mutex_init(&dev->mutex);
>  
>  	lis3lv02d_add_fs(dev);
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 3e8a208..7661e59 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -20,6 +20,7 @@
>   */
>  #include <linux/platform_device.h>
>  #include <linux/input-polldev.h>
> +#include <linux/regulator/consumer.h>
>  
>  /*
>   * This driver tries to support the "digital" accelerometer chips from
> @@ -206,6 +207,11 @@ enum lis3lv02d_click_src_8b {
>  	CLICK_IA	= 0x40,
>  };
>  
> +enum lis3lv02d_reg_state {
> +	LIS3_REG_OFF	= 0x00,
> +	LIS3_REG_ON	= 0x01,
> +};
> +
>  struct axis_conversion {
>  	s8	x;
>  	s8	y;
> @@ -218,8 +224,13 @@ struct lis3lv02d {
>  	int (*init) (struct lis3lv02d *lis3);
>  	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
>  	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
> +	int (*reg_ctrl) (struct lis3lv02d *lis3, bool state);
>  
>  	int                     *odrs;     /* Supported output data rates */
> +	u8			*regs;	   /* Regs to store / restore */
> +	int			regs_size;
> +	u8                      *reg_cache;
> +	bool			regs_stored;
>  	u8                      odr_mask;  /* ODR bit mask */
>  	u8			whoami;    /* indicates measurement precision */
>  	s16 (*read_data) (struct lis3lv02d *lis3, int reg);
> @@ -232,6 +243,7 @@ struct lis3lv02d {
>  
>  	struct input_polled_dev	*idev;     /* input device */
>  	struct platform_device	*pdev;     /* platform device */
> +	struct regulator_bulk_data regulators[2];
>  	atomic_t		count;     /* interrupt count after last read */
>  	struct axis_conversion	ac;        /* hw -> logical axis */
>  	int			mapped_btns[3];
> diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
> index 6e965d7..98983cc 100644
> --- a/drivers/hwmon/lis3lv02d_i2c.c
> +++ b/drivers/hwmon/lis3lv02d_i2c.c
> @@ -30,10 +30,29 @@
>  #include <linux/err.h>
>  #include <linux/i2c.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/delay.h>
>  #include "lis3lv02d.h"
>  
>  #define DRV_NAME 	"lis3lv02d_i2c"
>  
> +static const char reg_vdd[]    = "Vdd";
> +static const char reg_vdd_io[] = "Vdd_IO";
> +
> +static int lis3_reg_ctrl(struct lis3lv02d *lis3, bool state)
> +{
> +	int ret;
> +	if (state == LIS3_REG_OFF) {
> +		ret = regulator_bulk_disable(ARRAY_SIZE(lis3->regulators),
> +					lis3->regulators);
> +	} else {
> +		ret = regulator_bulk_enable(ARRAY_SIZE(lis3->regulators),
> +					lis3->regulators);
> +		/* Chip needs time to wakeup. Not mentioned in datasheet */
> +		usleep_range(10000, 20000);
> +	}
> +	return ret;
> +}
> +
>  static inline s32 lis3_i2c_write(struct lis3lv02d *lis3, int reg, u8 value)
>  {
>  	struct i2c_client *c = lis3->bus_priv;
> @@ -52,6 +71,13 @@ static int lis3_i2c_init(struct lis3lv02d *lis3)
>  	u8 reg;
>  	int ret;
>  
> +	if (lis3->reg_ctrl)
> +		lis3_reg_ctrl(lis3, LIS3_REG_ON);
> +
> +	lis3->read(lis3, WHO_AM_I, &reg);
> +	if (reg != lis3->whoami)
> +		printk(KERN_ERR "lis3: power on failure\n");
> +
>  	/* power up the device */
>  	ret = lis3->read(lis3, CTRL_REG1, &reg);
>  	if (ret < 0)
> @@ -73,6 +99,10 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>  	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
>  
>  	if (pdata) {
> +		/* Regulator control is optional */
> +		if (pdata->driver_features & LIS3_USE_REGULATOR_CTRL)
> +			lis3_dev.reg_ctrl = lis3_reg_ctrl;
> +
>  		if (pdata->axis_x)
>  			lis3lv02d_axis_map.x = pdata->axis_x;
>  
> @@ -89,6 +119,16 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>  			goto fail;
>  	}
>  
> +	if (lis3_dev.reg_ctrl) {
> +		lis3_dev.regulators[0].supply = reg_vdd;
> +		lis3_dev.regulators[1].supply = reg_vdd_io;
> +		ret = regulator_bulk_get(&client->dev,
> +					ARRAY_SIZE(lis3_dev.regulators),
> +					lis3_dev.regulators);
> +		if (ret < 0)
> +			goto fail;
> +	}
> +
>  	lis3_dev.pdata	  = pdata;
>  	lis3_dev.bus_priv = client;
>  	lis3_dev.init	  = lis3_i2c_init;
> @@ -99,21 +139,34 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>  	lis3_dev.pm_dev	  = &client->dev;
>  
>  	i2c_set_clientdata(client, &lis3_dev);
> +
> +	/* Provide power over the init call */
> +	if (lis3_dev.reg_ctrl)
> +		lis3_reg_ctrl(&lis3_dev, LIS3_REG_ON);
> +
>  	ret = lis3lv02d_init_device(&lis3_dev);
> +
> +	if (lis3_dev.reg_ctrl)
> +		lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF);
>  fail:
>  	return ret;
>  }
>  
>  static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
>  {
> +	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>  	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
>  
>  	if (pdata && pdata->release_resources)
>  		pdata->release_resources();
>  
>  	lis3lv02d_joystick_disable();
> +	lis3lv02d_remove_fs(&lis3_dev);
>  
> -	return lis3lv02d_remove_fs(&lis3_dev);
> +	if (lis3_dev.reg_ctrl)
> +		regulator_bulk_free(ARRAY_SIZE(lis3->regulators),
> +				lis3_dev.regulators);
> +	return 0;
>  }
>  
>  #ifdef CONFIG_PM
> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
> index 0e8a346..c4a4a52 100644
> --- a/include/linux/lis3lv02d.h
> +++ b/include/linux/lis3lv02d.h
> @@ -64,6 +64,8 @@ struct lis3lv02d_platform_data {
>  	s8 axis_x;
>  	s8 axis_y;
>  	s8 axis_z;
> +#define LIS3_USE_REGULATOR_CTRL 0x01
> +	u16 driver_features;
>  	int (*setup_resources)(void);
>  	int (*release_resources)(void);
>  	/* Limits for selftest are specified in chip data sheet */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 02/12] hwmon: lis3: regulator control
@ 2010-10-22 16:11     ` Jonathan Cameron
  0 siblings, 0 replies; 101+ messages in thread
From: Jonathan Cameron @ 2010-10-22 16:11 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: eric.piel, khali, guenter.roeck, lm-sensors, linux-i2c, linux-kernel

On 10/22/10 12:57, Samu Onkalo wrote:
> Based on pm_runtime control, turn lis3 regulators on and off.
> Perform context save and restore on transitions.
> 
> Feature is optional and must be enabled in platform data.
Answers all my queries on the previous version
> 
> Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
> ---
>  drivers/hwmon/lis3lv02d.c     |   52 ++++++++++++++++++++++++++++++++++++++
>  drivers/hwmon/lis3lv02d.h     |   12 +++++++++
>  drivers/hwmon/lis3lv02d_i2c.c |   55 ++++++++++++++++++++++++++++++++++++++++-
>  include/linux/lis3lv02d.h     |    2 +
>  4 files changed, 120 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index 412ddc3..ade6f3a 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -31,6 +31,7 @@
>  #include <linux/delay.h>
>  #include <linux/wait.h>
>  #include <linux/poll.h>
> +#include <linux/slab.h>
>  #include <linux/freezer.h>
>  #include <linux/uaccess.h>
>  #include <linux/miscdevice.h>
> @@ -223,10 +224,46 @@ fail:
>  	return ret;
>  }
>  
> +/*
> + * Order of registers in the list affects to order of the restore process.
> + * Perhaps it is a good idea to set interrupt enable register as a last one
> + * after all other configurations
> + */
> +static u8 lis3_wai8_regs[] = { FF_WU_CFG_1, FF_WU_THS_1, FF_WU_DURATION_1,
> +			       FF_WU_CFG_2, FF_WU_THS_2, FF_WU_DURATION_2,
> +			       CLICK_CFG, CLICK_SRC, CLICK_THSY_X, CLICK_THSZ,
> +			       CLICK_TIMELIMIT, CLICK_LATENCY, CLICK_WINDOW,
> +			       CTRL_REG1, CTRL_REG2, CTRL_REG3};
> +
> +static u8 lis3_wai12_regs[] = {FF_WU_CFG, FF_WU_THS_L, FF_WU_THS_H,
> +			       FF_WU_DURATION, DD_CFG, DD_THSI_L, DD_THSI_H,
> +			       DD_THSE_L, DD_THSE_H,
> +			       CTRL_REG1, CTRL_REG3, CTRL_REG2};
> +
> +static inline void lis3_context_save(struct lis3lv02d *lis3)
> +{
> +	int i;
> +	for (i = 0; i < lis3->regs_size; i++)
> +		lis3->read(lis3, lis3->regs[i], &lis3->reg_cache[i]);
> +	lis3->regs_stored = true;
> +}
> +
> +static inline void lis3_context_restore(struct lis3lv02d *lis3)
> +{
> +	int i;
> +	if (lis3->regs_stored)
> +		for (i = 0; i < lis3->regs_size; i++)
> +			lis3->write(lis3, lis3->regs[i], lis3->reg_cache[i]);
> +}
> +
>  void lis3lv02d_poweroff(struct lis3lv02d *lis3)
>  {
> +	if (lis3->reg_ctrl)
> +		lis3_context_save(lis3);
>  	/* disable X,Y,Z axis and power down */
>  	lis3->write(lis3, CTRL_REG1, 0x00);
> +	if (lis3->reg_ctrl)
> +		lis3->reg_ctrl(lis3, LIS3_REG_OFF);
>  }
>  EXPORT_SYMBOL_GPL(lis3lv02d_poweroff);
>  
> @@ -249,6 +286,8 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3)
>  		reg |= CTRL2_BDU;
>  		lis3->write(lis3, CTRL_REG2, reg);
>  	}
> +	if (lis3->reg_ctrl)
> +		lis3_context_restore(lis3);
>  }
>  EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
>  
> @@ -640,6 +679,7 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
>  		pm_runtime_disable(lis3->pm_dev);
>  		pm_runtime_set_suspended(lis3->pm_dev);
>  	}
> +	kfree(lis3->reg_cache);
>  	return 0;
>  }
>  EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
> @@ -719,6 +759,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  		dev->odrs = lis3_12_rates;
>  		dev->odr_mask = CTRL1_DF0 | CTRL1_DF1;
>  		dev->scale = LIS3_SENSITIVITY_12B;
> +		dev->regs = lis3_wai12_regs;
> +		dev->regs_size = ARRAY_SIZE(lis3_wai12_regs);
>  		break;
>  	case WAI_8B:
>  		printk(KERN_INFO DRIVER_NAME ": 8 bits sensor found\n");
> @@ -728,6 +770,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  		dev->odrs = lis3_8_rates;
>  		dev->odr_mask = CTRL1_DR;
>  		dev->scale = LIS3_SENSITIVITY_8B;
> +		dev->regs = lis3_wai8_regs;
> +		dev->regs_size = ARRAY_SIZE(lis3_wai8_regs);
>  		break;
>  	default:
>  		printk(KERN_ERR DRIVER_NAME
> @@ -735,6 +779,14 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  		return -EINVAL;
>  	}
>  
> +	dev->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs),
> +				     sizeof(lis3_wai12_regs)), GFP_KERNEL);
> +
> +	if (dev->reg_cache = NULL) {
> +		printk(KERN_ERR DRIVER_NAME "out of memory\n");
> +		return -ENOMEM;
> +	}
> +
>  	mutex_init(&dev->mutex);
>  
>  	lis3lv02d_add_fs(dev);
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 3e8a208..7661e59 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -20,6 +20,7 @@
>   */
>  #include <linux/platform_device.h>
>  #include <linux/input-polldev.h>
> +#include <linux/regulator/consumer.h>
>  
>  /*
>   * This driver tries to support the "digital" accelerometer chips from
> @@ -206,6 +207,11 @@ enum lis3lv02d_click_src_8b {
>  	CLICK_IA	= 0x40,
>  };
>  
> +enum lis3lv02d_reg_state {
> +	LIS3_REG_OFF	= 0x00,
> +	LIS3_REG_ON	= 0x01,
> +};
> +
>  struct axis_conversion {
>  	s8	x;
>  	s8	y;
> @@ -218,8 +224,13 @@ struct lis3lv02d {
>  	int (*init) (struct lis3lv02d *lis3);
>  	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
>  	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
> +	int (*reg_ctrl) (struct lis3lv02d *lis3, bool state);
>  
>  	int                     *odrs;     /* Supported output data rates */
> +	u8			*regs;	   /* Regs to store / restore */
> +	int			regs_size;
> +	u8                      *reg_cache;
> +	bool			regs_stored;
>  	u8                      odr_mask;  /* ODR bit mask */
>  	u8			whoami;    /* indicates measurement precision */
>  	s16 (*read_data) (struct lis3lv02d *lis3, int reg);
> @@ -232,6 +243,7 @@ struct lis3lv02d {
>  
>  	struct input_polled_dev	*idev;     /* input device */
>  	struct platform_device	*pdev;     /* platform device */
> +	struct regulator_bulk_data regulators[2];
>  	atomic_t		count;     /* interrupt count after last read */
>  	struct axis_conversion	ac;        /* hw -> logical axis */
>  	int			mapped_btns[3];
> diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
> index 6e965d7..98983cc 100644
> --- a/drivers/hwmon/lis3lv02d_i2c.c
> +++ b/drivers/hwmon/lis3lv02d_i2c.c
> @@ -30,10 +30,29 @@
>  #include <linux/err.h>
>  #include <linux/i2c.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/delay.h>
>  #include "lis3lv02d.h"
>  
>  #define DRV_NAME 	"lis3lv02d_i2c"
>  
> +static const char reg_vdd[]    = "Vdd";
> +static const char reg_vdd_io[] = "Vdd_IO";
> +
> +static int lis3_reg_ctrl(struct lis3lv02d *lis3, bool state)
> +{
> +	int ret;
> +	if (state = LIS3_REG_OFF) {
> +		ret = regulator_bulk_disable(ARRAY_SIZE(lis3->regulators),
> +					lis3->regulators);
> +	} else {
> +		ret = regulator_bulk_enable(ARRAY_SIZE(lis3->regulators),
> +					lis3->regulators);
> +		/* Chip needs time to wakeup. Not mentioned in datasheet */
> +		usleep_range(10000, 20000);
> +	}
> +	return ret;
> +}
> +
>  static inline s32 lis3_i2c_write(struct lis3lv02d *lis3, int reg, u8 value)
>  {
>  	struct i2c_client *c = lis3->bus_priv;
> @@ -52,6 +71,13 @@ static int lis3_i2c_init(struct lis3lv02d *lis3)
>  	u8 reg;
>  	int ret;
>  
> +	if (lis3->reg_ctrl)
> +		lis3_reg_ctrl(lis3, LIS3_REG_ON);
> +
> +	lis3->read(lis3, WHO_AM_I, &reg);
> +	if (reg != lis3->whoami)
> +		printk(KERN_ERR "lis3: power on failure\n");
> +
>  	/* power up the device */
>  	ret = lis3->read(lis3, CTRL_REG1, &reg);
>  	if (ret < 0)
> @@ -73,6 +99,10 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>  	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
>  
>  	if (pdata) {
> +		/* Regulator control is optional */
> +		if (pdata->driver_features & LIS3_USE_REGULATOR_CTRL)
> +			lis3_dev.reg_ctrl = lis3_reg_ctrl;
> +
>  		if (pdata->axis_x)
>  			lis3lv02d_axis_map.x = pdata->axis_x;
>  
> @@ -89,6 +119,16 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>  			goto fail;
>  	}
>  
> +	if (lis3_dev.reg_ctrl) {
> +		lis3_dev.regulators[0].supply = reg_vdd;
> +		lis3_dev.regulators[1].supply = reg_vdd_io;
> +		ret = regulator_bulk_get(&client->dev,
> +					ARRAY_SIZE(lis3_dev.regulators),
> +					lis3_dev.regulators);
> +		if (ret < 0)
> +			goto fail;
> +	}
> +
>  	lis3_dev.pdata	  = pdata;
>  	lis3_dev.bus_priv = client;
>  	lis3_dev.init	  = lis3_i2c_init;
> @@ -99,21 +139,34 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>  	lis3_dev.pm_dev	  = &client->dev;
>  
>  	i2c_set_clientdata(client, &lis3_dev);
> +
> +	/* Provide power over the init call */
> +	if (lis3_dev.reg_ctrl)
> +		lis3_reg_ctrl(&lis3_dev, LIS3_REG_ON);
> +
>  	ret = lis3lv02d_init_device(&lis3_dev);
> +
> +	if (lis3_dev.reg_ctrl)
> +		lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF);
>  fail:
>  	return ret;
>  }
>  
>  static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
>  {
> +	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>  	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
>  
>  	if (pdata && pdata->release_resources)
>  		pdata->release_resources();
>  
>  	lis3lv02d_joystick_disable();
> +	lis3lv02d_remove_fs(&lis3_dev);
>  
> -	return lis3lv02d_remove_fs(&lis3_dev);
> +	if (lis3_dev.reg_ctrl)
> +		regulator_bulk_free(ARRAY_SIZE(lis3->regulators),
> +				lis3_dev.regulators);
> +	return 0;
>  }
>  
>  #ifdef CONFIG_PM
> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
> index 0e8a346..c4a4a52 100644
> --- a/include/linux/lis3lv02d.h
> +++ b/include/linux/lis3lv02d.h
> @@ -64,6 +64,8 @@ struct lis3lv02d_platform_data {
>  	s8 axis_x;
>  	s8 axis_y;
>  	s8 axis_z;
> +#define LIS3_USE_REGULATOR_CTRL 0x01
> +	u16 driver_features;
>  	int (*setup_resources)(void);
>  	int (*release_resources)(void);
>  	/* Limits for selftest are specified in chip data sheet */


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 01/12] hwmon: lis3: pm_runtime support
@ 2010-10-22 16:13     ` Jonathan Cameron
  0 siblings, 0 replies; 101+ messages in thread
From: Jonathan Cameron @ 2010-10-22 16:13 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: eric.piel, khali, guenter.roeck, lm-sensors, linux-i2c, linux-kernel

On 10/22/10 12:57, Samu Onkalo wrote:
> Add pm_runtime support to lis3 core driver.
> Add pm_runtime support to lis3 i2c driver.
> 
> spi and hp_accel drivers are not yet supported. Old always
> on functionality remains for those.
> 
> For sysfs there is 5 second delay before turning off the
> chip to avoid long ramp up delay.
> 
I acked this last time around (after Samu answered some queries I had)
and I don't think it has changed.
> Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
> ---
>  drivers/hwmon/lis3lv02d.c     |   60 +++++++++++++++++++++++++++++++++++++++++
>  drivers/hwmon/lis3lv02d.h     |    1 +
>  drivers/hwmon/lis3lv02d_i2c.c |   54 ++++++++++++++++++++++++++++---------
>  3 files changed, 102 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index fc591ae..412ddc3 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -34,6 +34,7 @@
>  #include <linux/freezer.h>
>  #include <linux/uaccess.h>
>  #include <linux/miscdevice.h>
> +#include <linux/pm_runtime.h>
>  #include <asm/atomic.h>
>  #include "lis3lv02d.h"
>  
> @@ -43,6 +44,9 @@
>  #define MDPS_POLL_INTERVAL 50
>  #define MDPS_POLL_MIN	   0
>  #define MDPS_POLL_MAX	   2000
> +
> +#define LIS3_SYSFS_POWERDOWN_DELAY 5000 /* In milliseconds */
> +
>  /*
>   * The sensor can also generate interrupts (DRDY) but it's pretty pointless
>   * because they are generated even if the data do not change. So it's better
> @@ -262,6 +266,18 @@ static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev)
>  	mutex_unlock(&lis3_dev.mutex);
>  }
>  
> +static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
> +{
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_get_sync(lis3_dev.pm_dev);
> +}
> +
> +static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
> +{
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_put(lis3_dev.pm_dev);
> +}
> +
>  static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
>  {
>  	if (!test_bit(0, &lis3_dev.misc_opened))
> @@ -356,6 +372,9 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
>  	if (test_and_set_bit(0, &lis3_dev.misc_opened))
>  		return -EBUSY; /* already open */
>  
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_get_sync(lis3_dev.pm_dev);
> +
>  	atomic_set(&lis3_dev.count, 0);
>  	return 0;
>  }
> @@ -364,6 +383,8 @@ static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
>  {
>  	fasync_helper(-1, file, 0, &lis3_dev.async_queue);
>  	clear_bit(0, &lis3_dev.misc_opened); /* release the device */
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_put(lis3_dev.pm_dev);
>  	return 0;
>  }
>  
> @@ -460,6 +481,8 @@ int lis3lv02d_joystick_enable(void)
>  		return -ENOMEM;
>  
>  	lis3_dev.idev->poll = lis3lv02d_joystick_poll;
> +	lis3_dev.idev->open = lis3lv02d_joystick_open;
> +	lis3_dev.idev->close = lis3lv02d_joystick_close;
>  	lis3_dev.idev->poll_interval = MDPS_POLL_INTERVAL;
>  	lis3_dev.idev->poll_interval_min = MDPS_POLL_MIN;
>  	lis3_dev.idev->poll_interval_max = MDPS_POLL_MAX;
> @@ -512,12 +535,30 @@ void lis3lv02d_joystick_disable(void)
>  EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable);
>  
>  /* Sysfs stuff */
> +static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3)
> +{
> +	/*
> +	 * SYSFS functions are fast visitors so put-call
> +	 * immediately after the get-call. However, keep
> +	 * chip running for a while and schedule delayed
> +	 * suspend. This way periodic sysfs calls doesn't
> +	 * suffer from relatively long power up time.
> +	 */
> +
> +	if (lis3->pm_dev) {
> +		pm_runtime_get_sync(lis3->pm_dev);
> +		pm_runtime_put_noidle(lis3->pm_dev);
> +		pm_schedule_suspend(lis3->pm_dev, LIS3_SYSFS_POWERDOWN_DELAY);
> +	}
> +}
> +
>  static ssize_t lis3lv02d_selftest_show(struct device *dev,
>  				struct device_attribute *attr, char *buf)
>  {
>  	int result;
>  	s16 values[3];
>  
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>  	result = lis3lv02d_selftest(&lis3_dev, values);
>  	return sprintf(buf, "%s %d %d %d\n", result == 0 ? "OK" : "FAIL",
>  		values[0], values[1], values[2]);
> @@ -528,6 +569,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
>  {
>  	int x, y, z;
>  
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>  	mutex_lock(&lis3_dev.mutex);
>  	lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
>  	mutex_unlock(&lis3_dev.mutex);
> @@ -537,6 +579,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
>  static ssize_t lis3lv02d_rate_show(struct device *dev,
>  			struct device_attribute *attr, char *buf)
>  {
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>  	return sprintf(buf, "%d\n", lis3lv02d_get_odr());
>  }
>  
> @@ -549,6 +592,7 @@ static ssize_t lis3lv02d_rate_set(struct device *dev,
>  	if (strict_strtoul(buf, 0, &rate))
>  		return -EINVAL;
>  
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>  	if (lis3lv02d_set_odr(rate))
>  		return -EINVAL;
>  
> @@ -585,6 +629,17 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
>  {
>  	sysfs_remove_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group);
>  	platform_device_unregister(lis3->pdev);
> +	if (lis3->pm_dev) {
> +		/* Barrier after the sysfs remove */
> +		pm_runtime_barrier(lis3->pm_dev);
> +
> +		/* SYSFS may have left chip running. Turn off if necessary */
> +		if (!pm_runtime_suspended(lis3->pm_dev))
> +			lis3lv02d_poweroff(&lis3_dev);
> +
> +		pm_runtime_disable(lis3->pm_dev);
> +		pm_runtime_set_suspended(lis3->pm_dev);
> +	}
>  	return 0;
>  }
>  EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
> @@ -685,6 +740,11 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  	lis3lv02d_add_fs(dev);
>  	lis3lv02d_poweron(dev);
>  
> +	if (dev->pm_dev) {
> +		pm_runtime_set_active(dev->pm_dev);
> +		pm_runtime_enable(dev->pm_dev);
> +	}
> +
>  	if (lis3lv02d_joystick_enable())
>  		printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
>  
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 8540913..3e8a208 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -214,6 +214,7 @@ struct axis_conversion {
>  
>  struct lis3lv02d {
>  	void			*bus_priv; /* used by the bus layer only */
> +	struct device		*pm_dev; /* for pm_runtime purposes */
>  	int (*init) (struct lis3lv02d *lis3);
>  	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
>  	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
> diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
> index 8e5933b..6e965d7 100644
> --- a/drivers/hwmon/lis3lv02d_i2c.c
> +++ b/drivers/hwmon/lis3lv02d_i2c.c
> @@ -29,6 +29,7 @@
>  #include <linux/init.h>
>  #include <linux/err.h>
>  #include <linux/i2c.h>
> +#include <linux/pm_runtime.h>
>  #include "lis3lv02d.h"
>  
>  #define DRV_NAME 	"lis3lv02d_i2c"
> @@ -95,6 +96,7 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>  	lis3_dev.write	  = lis3_i2c_write;
>  	lis3_dev.irq	  = client->irq;
>  	lis3_dev.ac	  = lis3lv02d_axis_map;
> +	lis3_dev.pm_dev	  = &client->dev;
>  
>  	i2c_set_clientdata(client, &lis3_dev);
>  	ret = lis3lv02d_init_device(&lis3_dev);
> @@ -104,21 +106,20 @@ fail:
>  
>  static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
>  {
> -	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>  	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
>  
>  	if (pdata && pdata->release_resources)
>  		pdata->release_resources();
>  
>  	lis3lv02d_joystick_disable();
> -	lis3lv02d_poweroff(lis3);
>  
>  	return lis3lv02d_remove_fs(&lis3_dev);
>  }
>  
>  #ifdef CONFIG_PM
> -static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
> +static int lis3lv02d_i2c_suspend(struct device *dev)
>  {
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
>  	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>  
>  	if (!lis3->pdata || !lis3->pdata->wakeup_flags)
> @@ -126,18 +127,21 @@ static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
>  	return 0;
>  }
>  
> -static int lis3lv02d_i2c_resume(struct i2c_client *client)
> +static int lis3lv02d_i2c_resume(struct device *dev)
>  {
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
>  	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>  
> -	if (!lis3->pdata || !lis3->pdata->wakeup_flags)
> +	/*
> +	 * pm_runtime documentation says that devices should always
> +	 * be powered on at resume. Pm_runtime turns them off after system
> +	 * wide resume is complete.
> +	 */
> +	if (!lis3->pdata || !lis3->pdata->wakeup_flags ||
> +		pm_runtime_suspended(dev))
>  		lis3lv02d_poweron(lis3);
> -	return 0;
> -}
>  
> -static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
> -{
> -	lis3lv02d_i2c_suspend(client, PMSG_SUSPEND);
> +	return 0;
>  }
>  #else
>  #define lis3lv02d_i2c_suspend	NULL
> @@ -145,6 +149,24 @@ static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
>  #define lis3lv02d_i2c_shutdown	NULL
>  #endif
>  
> +static int lis3_i2c_runtime_suspend(struct device *dev)
> +{
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
> +	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
> +
> +	lis3lv02d_poweroff(lis3);
> +	return 0;
> +}
> +
> +static int lis3_i2c_runtime_resume(struct device *dev)
> +{
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
> +	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
> +
> +	lis3lv02d_poweron(lis3);
> +	return 0;
> +}
> +
>  static const struct i2c_device_id lis3lv02d_id[] = {
>  	{"lis3lv02d", 0 },
>  	{}
> @@ -152,14 +174,20 @@ static const struct i2c_device_id lis3lv02d_id[] = {
>  
>  MODULE_DEVICE_TABLE(i2c, lis3lv02d_id);
>  
> +static const struct dev_pm_ops lis3_pm_ops = {
> +	SET_SYSTEM_SLEEP_PM_OPS(lis3lv02d_i2c_suspend,
> +				lis3lv02d_i2c_resume)
> +	SET_RUNTIME_PM_OPS(lis3_i2c_runtime_suspend,
> +			   lis3_i2c_runtime_resume,
> +			   NULL)
> +};
> +
>  static struct i2c_driver lis3lv02d_i2c_driver = {
>  	.driver	 = {
>  		.name   = DRV_NAME,
>  		.owner  = THIS_MODULE,
> +		.pm     = &lis3_pm_ops,
>  	},
> -	.suspend = lis3lv02d_i2c_suspend,
> -	.shutdown = lis3lv02d_i2c_shutdown,
> -	.resume = lis3lv02d_i2c_resume,
>  	.probe	= lis3lv02d_i2c_probe,
>  	.remove	= __devexit_p(lis3lv02d_i2c_remove),
>  	.id_table = lis3lv02d_id,


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 01/12] hwmon: lis3: pm_runtime support
@ 2010-10-22 16:13     ` Jonathan Cameron
  0 siblings, 0 replies; 101+ messages in thread
From: Jonathan Cameron @ 2010-10-22 16:13 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: eric.piel-VkQ1JFuSMpfAbQlEx87xDw, khali-PUYAD+kWke1g9hUCZPvPmw,
	guenter.roeck-IzeFyvvaP7pWk0Htik3J/w,
	lm-sensors-GZX6beZjE8VD60Wz+7aTrA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 10/22/10 12:57, Samu Onkalo wrote:
> Add pm_runtime support to lis3 core driver.
> Add pm_runtime support to lis3 i2c driver.
> 
> spi and hp_accel drivers are not yet supported. Old always
> on functionality remains for those.
> 
> For sysfs there is 5 second delay before turning off the
> chip to avoid long ramp up delay.
> 
I acked this last time around (after Samu answered some queries I had)
and I don't think it has changed.
> Signed-off-by: Samu Onkalo <samu.p.onkalo-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
Acked-by: Jonathan Cameron <jic23-KWPb1pKIrIJaa/9Udqfwiw@public.gmane.org>
> ---
>  drivers/hwmon/lis3lv02d.c     |   60 +++++++++++++++++++++++++++++++++++++++++
>  drivers/hwmon/lis3lv02d.h     |    1 +
>  drivers/hwmon/lis3lv02d_i2c.c |   54 ++++++++++++++++++++++++++++---------
>  3 files changed, 102 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index fc591ae..412ddc3 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -34,6 +34,7 @@
>  #include <linux/freezer.h>
>  #include <linux/uaccess.h>
>  #include <linux/miscdevice.h>
> +#include <linux/pm_runtime.h>
>  #include <asm/atomic.h>
>  #include "lis3lv02d.h"
>  
> @@ -43,6 +44,9 @@
>  #define MDPS_POLL_INTERVAL 50
>  #define MDPS_POLL_MIN	   0
>  #define MDPS_POLL_MAX	   2000
> +
> +#define LIS3_SYSFS_POWERDOWN_DELAY 5000 /* In milliseconds */
> +
>  /*
>   * The sensor can also generate interrupts (DRDY) but it's pretty pointless
>   * because they are generated even if the data do not change. So it's better
> @@ -262,6 +266,18 @@ static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev)
>  	mutex_unlock(&lis3_dev.mutex);
>  }
>  
> +static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
> +{
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_get_sync(lis3_dev.pm_dev);
> +}
> +
> +static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
> +{
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_put(lis3_dev.pm_dev);
> +}
> +
>  static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
>  {
>  	if (!test_bit(0, &lis3_dev.misc_opened))
> @@ -356,6 +372,9 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
>  	if (test_and_set_bit(0, &lis3_dev.misc_opened))
>  		return -EBUSY; /* already open */
>  
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_get_sync(lis3_dev.pm_dev);
> +
>  	atomic_set(&lis3_dev.count, 0);
>  	return 0;
>  }
> @@ -364,6 +383,8 @@ static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
>  {
>  	fasync_helper(-1, file, 0, &lis3_dev.async_queue);
>  	clear_bit(0, &lis3_dev.misc_opened); /* release the device */
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_put(lis3_dev.pm_dev);
>  	return 0;
>  }
>  
> @@ -460,6 +481,8 @@ int lis3lv02d_joystick_enable(void)
>  		return -ENOMEM;
>  
>  	lis3_dev.idev->poll = lis3lv02d_joystick_poll;
> +	lis3_dev.idev->open = lis3lv02d_joystick_open;
> +	lis3_dev.idev->close = lis3lv02d_joystick_close;
>  	lis3_dev.idev->poll_interval = MDPS_POLL_INTERVAL;
>  	lis3_dev.idev->poll_interval_min = MDPS_POLL_MIN;
>  	lis3_dev.idev->poll_interval_max = MDPS_POLL_MAX;
> @@ -512,12 +535,30 @@ void lis3lv02d_joystick_disable(void)
>  EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable);
>  
>  /* Sysfs stuff */
> +static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3)
> +{
> +	/*
> +	 * SYSFS functions are fast visitors so put-call
> +	 * immediately after the get-call. However, keep
> +	 * chip running for a while and schedule delayed
> +	 * suspend. This way periodic sysfs calls doesn't
> +	 * suffer from relatively long power up time.
> +	 */
> +
> +	if (lis3->pm_dev) {
> +		pm_runtime_get_sync(lis3->pm_dev);
> +		pm_runtime_put_noidle(lis3->pm_dev);
> +		pm_schedule_suspend(lis3->pm_dev, LIS3_SYSFS_POWERDOWN_DELAY);
> +	}
> +}
> +
>  static ssize_t lis3lv02d_selftest_show(struct device *dev,
>  				struct device_attribute *attr, char *buf)
>  {
>  	int result;
>  	s16 values[3];
>  
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>  	result = lis3lv02d_selftest(&lis3_dev, values);
>  	return sprintf(buf, "%s %d %d %d\n", result == 0 ? "OK" : "FAIL",
>  		values[0], values[1], values[2]);
> @@ -528,6 +569,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
>  {
>  	int x, y, z;
>  
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>  	mutex_lock(&lis3_dev.mutex);
>  	lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
>  	mutex_unlock(&lis3_dev.mutex);
> @@ -537,6 +579,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
>  static ssize_t lis3lv02d_rate_show(struct device *dev,
>  			struct device_attribute *attr, char *buf)
>  {
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>  	return sprintf(buf, "%d\n", lis3lv02d_get_odr());
>  }
>  
> @@ -549,6 +592,7 @@ static ssize_t lis3lv02d_rate_set(struct device *dev,
>  	if (strict_strtoul(buf, 0, &rate))
>  		return -EINVAL;
>  
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>  	if (lis3lv02d_set_odr(rate))
>  		return -EINVAL;
>  
> @@ -585,6 +629,17 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
>  {
>  	sysfs_remove_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group);
>  	platform_device_unregister(lis3->pdev);
> +	if (lis3->pm_dev) {
> +		/* Barrier after the sysfs remove */
> +		pm_runtime_barrier(lis3->pm_dev);
> +
> +		/* SYSFS may have left chip running. Turn off if necessary */
> +		if (!pm_runtime_suspended(lis3->pm_dev))
> +			lis3lv02d_poweroff(&lis3_dev);
> +
> +		pm_runtime_disable(lis3->pm_dev);
> +		pm_runtime_set_suspended(lis3->pm_dev);
> +	}
>  	return 0;
>  }
>  EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
> @@ -685,6 +740,11 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  	lis3lv02d_add_fs(dev);
>  	lis3lv02d_poweron(dev);
>  
> +	if (dev->pm_dev) {
> +		pm_runtime_set_active(dev->pm_dev);
> +		pm_runtime_enable(dev->pm_dev);
> +	}
> +
>  	if (lis3lv02d_joystick_enable())
>  		printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
>  
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 8540913..3e8a208 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -214,6 +214,7 @@ struct axis_conversion {
>  
>  struct lis3lv02d {
>  	void			*bus_priv; /* used by the bus layer only */
> +	struct device		*pm_dev; /* for pm_runtime purposes */
>  	int (*init) (struct lis3lv02d *lis3);
>  	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
>  	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
> diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
> index 8e5933b..6e965d7 100644
> --- a/drivers/hwmon/lis3lv02d_i2c.c
> +++ b/drivers/hwmon/lis3lv02d_i2c.c
> @@ -29,6 +29,7 @@
>  #include <linux/init.h>
>  #include <linux/err.h>
>  #include <linux/i2c.h>
> +#include <linux/pm_runtime.h>
>  #include "lis3lv02d.h"
>  
>  #define DRV_NAME 	"lis3lv02d_i2c"
> @@ -95,6 +96,7 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>  	lis3_dev.write	  = lis3_i2c_write;
>  	lis3_dev.irq	  = client->irq;
>  	lis3_dev.ac	  = lis3lv02d_axis_map;
> +	lis3_dev.pm_dev	  = &client->dev;
>  
>  	i2c_set_clientdata(client, &lis3_dev);
>  	ret = lis3lv02d_init_device(&lis3_dev);
> @@ -104,21 +106,20 @@ fail:
>  
>  static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
>  {
> -	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>  	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
>  
>  	if (pdata && pdata->release_resources)
>  		pdata->release_resources();
>  
>  	lis3lv02d_joystick_disable();
> -	lis3lv02d_poweroff(lis3);
>  
>  	return lis3lv02d_remove_fs(&lis3_dev);
>  }
>  
>  #ifdef CONFIG_PM
> -static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
> +static int lis3lv02d_i2c_suspend(struct device *dev)
>  {
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
>  	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>  
>  	if (!lis3->pdata || !lis3->pdata->wakeup_flags)
> @@ -126,18 +127,21 @@ static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
>  	return 0;
>  }
>  
> -static int lis3lv02d_i2c_resume(struct i2c_client *client)
> +static int lis3lv02d_i2c_resume(struct device *dev)
>  {
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
>  	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>  
> -	if (!lis3->pdata || !lis3->pdata->wakeup_flags)
> +	/*
> +	 * pm_runtime documentation says that devices should always
> +	 * be powered on at resume. Pm_runtime turns them off after system
> +	 * wide resume is complete.
> +	 */
> +	if (!lis3->pdata || !lis3->pdata->wakeup_flags ||
> +		pm_runtime_suspended(dev))
>  		lis3lv02d_poweron(lis3);
> -	return 0;
> -}
>  
> -static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
> -{
> -	lis3lv02d_i2c_suspend(client, PMSG_SUSPEND);
> +	return 0;
>  }
>  #else
>  #define lis3lv02d_i2c_suspend	NULL
> @@ -145,6 +149,24 @@ static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
>  #define lis3lv02d_i2c_shutdown	NULL
>  #endif
>  
> +static int lis3_i2c_runtime_suspend(struct device *dev)
> +{
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
> +	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
> +
> +	lis3lv02d_poweroff(lis3);
> +	return 0;
> +}
> +
> +static int lis3_i2c_runtime_resume(struct device *dev)
> +{
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
> +	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
> +
> +	lis3lv02d_poweron(lis3);
> +	return 0;
> +}
> +
>  static const struct i2c_device_id lis3lv02d_id[] = {
>  	{"lis3lv02d", 0 },
>  	{}
> @@ -152,14 +174,20 @@ static const struct i2c_device_id lis3lv02d_id[] = {
>  
>  MODULE_DEVICE_TABLE(i2c, lis3lv02d_id);
>  
> +static const struct dev_pm_ops lis3_pm_ops = {
> +	SET_SYSTEM_SLEEP_PM_OPS(lis3lv02d_i2c_suspend,
> +				lis3lv02d_i2c_resume)
> +	SET_RUNTIME_PM_OPS(lis3_i2c_runtime_suspend,
> +			   lis3_i2c_runtime_resume,
> +			   NULL)
> +};
> +
>  static struct i2c_driver lis3lv02d_i2c_driver = {
>  	.driver	 = {
>  		.name   = DRV_NAME,
>  		.owner  = THIS_MODULE,
> +		.pm     = &lis3_pm_ops,
>  	},
> -	.suspend = lis3lv02d_i2c_suspend,
> -	.shutdown = lis3lv02d_i2c_shutdown,
> -	.resume = lis3lv02d_i2c_resume,
>  	.probe	= lis3lv02d_i2c_probe,
>  	.remove	= __devexit_p(lis3lv02d_i2c_remove),
>  	.id_table = lis3lv02d_id,

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 01/12] hwmon: lis3: pm_runtime support
@ 2010-10-22 16:13     ` Jonathan Cameron
  0 siblings, 0 replies; 101+ messages in thread
From: Jonathan Cameron @ 2010-10-22 16:13 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: eric.piel, khali, guenter.roeck, lm-sensors, linux-i2c, linux-kernel

On 10/22/10 12:57, Samu Onkalo wrote:
> Add pm_runtime support to lis3 core driver.
> Add pm_runtime support to lis3 i2c driver.
> 
> spi and hp_accel drivers are not yet supported. Old always
> on functionality remains for those.
> 
> For sysfs there is 5 second delay before turning off the
> chip to avoid long ramp up delay.
> 
I acked this last time around (after Samu answered some queries I had)
and I don't think it has changed.
> Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
> ---
>  drivers/hwmon/lis3lv02d.c     |   60 +++++++++++++++++++++++++++++++++++++++++
>  drivers/hwmon/lis3lv02d.h     |    1 +
>  drivers/hwmon/lis3lv02d_i2c.c |   54 ++++++++++++++++++++++++++++---------
>  3 files changed, 102 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index fc591ae..412ddc3 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -34,6 +34,7 @@
>  #include <linux/freezer.h>
>  #include <linux/uaccess.h>
>  #include <linux/miscdevice.h>
> +#include <linux/pm_runtime.h>
>  #include <asm/atomic.h>
>  #include "lis3lv02d.h"
>  
> @@ -43,6 +44,9 @@
>  #define MDPS_POLL_INTERVAL 50
>  #define MDPS_POLL_MIN	   0
>  #define MDPS_POLL_MAX	   2000
> +
> +#define LIS3_SYSFS_POWERDOWN_DELAY 5000 /* In milliseconds */
> +
>  /*
>   * The sensor can also generate interrupts (DRDY) but it's pretty pointless
>   * because they are generated even if the data do not change. So it's better
> @@ -262,6 +266,18 @@ static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev)
>  	mutex_unlock(&lis3_dev.mutex);
>  }
>  
> +static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
> +{
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_get_sync(lis3_dev.pm_dev);
> +}
> +
> +static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
> +{
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_put(lis3_dev.pm_dev);
> +}
> +
>  static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
>  {
>  	if (!test_bit(0, &lis3_dev.misc_opened))
> @@ -356,6 +372,9 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
>  	if (test_and_set_bit(0, &lis3_dev.misc_opened))
>  		return -EBUSY; /* already open */
>  
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_get_sync(lis3_dev.pm_dev);
> +
>  	atomic_set(&lis3_dev.count, 0);
>  	return 0;
>  }
> @@ -364,6 +383,8 @@ static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
>  {
>  	fasync_helper(-1, file, 0, &lis3_dev.async_queue);
>  	clear_bit(0, &lis3_dev.misc_opened); /* release the device */
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_put(lis3_dev.pm_dev);
>  	return 0;
>  }
>  
> @@ -460,6 +481,8 @@ int lis3lv02d_joystick_enable(void)
>  		return -ENOMEM;
>  
>  	lis3_dev.idev->poll = lis3lv02d_joystick_poll;
> +	lis3_dev.idev->open = lis3lv02d_joystick_open;
> +	lis3_dev.idev->close = lis3lv02d_joystick_close;
>  	lis3_dev.idev->poll_interval = MDPS_POLL_INTERVAL;
>  	lis3_dev.idev->poll_interval_min = MDPS_POLL_MIN;
>  	lis3_dev.idev->poll_interval_max = MDPS_POLL_MAX;
> @@ -512,12 +535,30 @@ void lis3lv02d_joystick_disable(void)
>  EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable);
>  
>  /* Sysfs stuff */
> +static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3)
> +{
> +	/*
> +	 * SYSFS functions are fast visitors so put-call
> +	 * immediately after the get-call. However, keep
> +	 * chip running for a while and schedule delayed
> +	 * suspend. This way periodic sysfs calls doesn't
> +	 * suffer from relatively long power up time.
> +	 */
> +
> +	if (lis3->pm_dev) {
> +		pm_runtime_get_sync(lis3->pm_dev);
> +		pm_runtime_put_noidle(lis3->pm_dev);
> +		pm_schedule_suspend(lis3->pm_dev, LIS3_SYSFS_POWERDOWN_DELAY);
> +	}
> +}
> +
>  static ssize_t lis3lv02d_selftest_show(struct device *dev,
>  				struct device_attribute *attr, char *buf)
>  {
>  	int result;
>  	s16 values[3];
>  
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>  	result = lis3lv02d_selftest(&lis3_dev, values);
>  	return sprintf(buf, "%s %d %d %d\n", result = 0 ? "OK" : "FAIL",
>  		values[0], values[1], values[2]);
> @@ -528,6 +569,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
>  {
>  	int x, y, z;
>  
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>  	mutex_lock(&lis3_dev.mutex);
>  	lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
>  	mutex_unlock(&lis3_dev.mutex);
> @@ -537,6 +579,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
>  static ssize_t lis3lv02d_rate_show(struct device *dev,
>  			struct device_attribute *attr, char *buf)
>  {
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>  	return sprintf(buf, "%d\n", lis3lv02d_get_odr());
>  }
>  
> @@ -549,6 +592,7 @@ static ssize_t lis3lv02d_rate_set(struct device *dev,
>  	if (strict_strtoul(buf, 0, &rate))
>  		return -EINVAL;
>  
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>  	if (lis3lv02d_set_odr(rate))
>  		return -EINVAL;
>  
> @@ -585,6 +629,17 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
>  {
>  	sysfs_remove_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group);
>  	platform_device_unregister(lis3->pdev);
> +	if (lis3->pm_dev) {
> +		/* Barrier after the sysfs remove */
> +		pm_runtime_barrier(lis3->pm_dev);
> +
> +		/* SYSFS may have left chip running. Turn off if necessary */
> +		if (!pm_runtime_suspended(lis3->pm_dev))
> +			lis3lv02d_poweroff(&lis3_dev);
> +
> +		pm_runtime_disable(lis3->pm_dev);
> +		pm_runtime_set_suspended(lis3->pm_dev);
> +	}
>  	return 0;
>  }
>  EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
> @@ -685,6 +740,11 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  	lis3lv02d_add_fs(dev);
>  	lis3lv02d_poweron(dev);
>  
> +	if (dev->pm_dev) {
> +		pm_runtime_set_active(dev->pm_dev);
> +		pm_runtime_enable(dev->pm_dev);
> +	}
> +
>  	if (lis3lv02d_joystick_enable())
>  		printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
>  
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 8540913..3e8a208 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -214,6 +214,7 @@ struct axis_conversion {
>  
>  struct lis3lv02d {
>  	void			*bus_priv; /* used by the bus layer only */
> +	struct device		*pm_dev; /* for pm_runtime purposes */
>  	int (*init) (struct lis3lv02d *lis3);
>  	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
>  	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
> diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
> index 8e5933b..6e965d7 100644
> --- a/drivers/hwmon/lis3lv02d_i2c.c
> +++ b/drivers/hwmon/lis3lv02d_i2c.c
> @@ -29,6 +29,7 @@
>  #include <linux/init.h>
>  #include <linux/err.h>
>  #include <linux/i2c.h>
> +#include <linux/pm_runtime.h>
>  #include "lis3lv02d.h"
>  
>  #define DRV_NAME 	"lis3lv02d_i2c"
> @@ -95,6 +96,7 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>  	lis3_dev.write	  = lis3_i2c_write;
>  	lis3_dev.irq	  = client->irq;
>  	lis3_dev.ac	  = lis3lv02d_axis_map;
> +	lis3_dev.pm_dev	  = &client->dev;
>  
>  	i2c_set_clientdata(client, &lis3_dev);
>  	ret = lis3lv02d_init_device(&lis3_dev);
> @@ -104,21 +106,20 @@ fail:
>  
>  static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
>  {
> -	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>  	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
>  
>  	if (pdata && pdata->release_resources)
>  		pdata->release_resources();
>  
>  	lis3lv02d_joystick_disable();
> -	lis3lv02d_poweroff(lis3);
>  
>  	return lis3lv02d_remove_fs(&lis3_dev);
>  }
>  
>  #ifdef CONFIG_PM
> -static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
> +static int lis3lv02d_i2c_suspend(struct device *dev)
>  {
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
>  	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>  
>  	if (!lis3->pdata || !lis3->pdata->wakeup_flags)
> @@ -126,18 +127,21 @@ static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
>  	return 0;
>  }
>  
> -static int lis3lv02d_i2c_resume(struct i2c_client *client)
> +static int lis3lv02d_i2c_resume(struct device *dev)
>  {
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
>  	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>  
> -	if (!lis3->pdata || !lis3->pdata->wakeup_flags)
> +	/*
> +	 * pm_runtime documentation says that devices should always
> +	 * be powered on at resume. Pm_runtime turns them off after system
> +	 * wide resume is complete.
> +	 */
> +	if (!lis3->pdata || !lis3->pdata->wakeup_flags ||
> +		pm_runtime_suspended(dev))
>  		lis3lv02d_poweron(lis3);
> -	return 0;
> -}
>  
> -static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
> -{
> -	lis3lv02d_i2c_suspend(client, PMSG_SUSPEND);
> +	return 0;
>  }
>  #else
>  #define lis3lv02d_i2c_suspend	NULL
> @@ -145,6 +149,24 @@ static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
>  #define lis3lv02d_i2c_shutdown	NULL
>  #endif
>  
> +static int lis3_i2c_runtime_suspend(struct device *dev)
> +{
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
> +	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
> +
> +	lis3lv02d_poweroff(lis3);
> +	return 0;
> +}
> +
> +static int lis3_i2c_runtime_resume(struct device *dev)
> +{
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
> +	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
> +
> +	lis3lv02d_poweron(lis3);
> +	return 0;
> +}
> +
>  static const struct i2c_device_id lis3lv02d_id[] = {
>  	{"lis3lv02d", 0 },
>  	{}
> @@ -152,14 +174,20 @@ static const struct i2c_device_id lis3lv02d_id[] = {
>  
>  MODULE_DEVICE_TABLE(i2c, lis3lv02d_id);
>  
> +static const struct dev_pm_ops lis3_pm_ops = {
> +	SET_SYSTEM_SLEEP_PM_OPS(lis3lv02d_i2c_suspend,
> +				lis3lv02d_i2c_resume)
> +	SET_RUNTIME_PM_OPS(lis3_i2c_runtime_suspend,
> +			   lis3_i2c_runtime_resume,
> +			   NULL)
> +};
> +
>  static struct i2c_driver lis3lv02d_i2c_driver = {
>  	.driver	 = {
>  		.name   = DRV_NAME,
>  		.owner  = THIS_MODULE,
> +		.pm     = &lis3_pm_ops,
>  	},
> -	.suspend = lis3lv02d_i2c_suspend,
> -	.shutdown = lis3lv02d_i2c_shutdown,
> -	.resume = lis3lv02d_i2c_resume,
>  	.probe	= lis3lv02d_i2c_probe,
>  	.remove	= __devexit_p(lis3lv02d_i2c_remove),
>  	.id_table = lis3lv02d_id,


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 07/12] hwmon: lis3: New parameters to platform data
@ 2010-10-22 16:17     ` Jonathan Cameron
  0 siblings, 0 replies; 101+ messages in thread
From: Jonathan Cameron @ 2010-10-22 16:17 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: eric.piel, khali, guenter.roeck, lm-sensors, linux-i2c, linux-kernel

On 10/22/10 12:57, Samu Onkalo wrote:
> Added default output data rate setting to platform data.
> If default rate is 0, reset default value is used.
> Added control for duration via platform data.
> Added possibility to configure interrupts to trig on
> both rising and falling edge. The lis3 WU unit can be
> configured quite many ways and with some configurations it
> is quite handy to get coordinate refresh when some
> event trigs and when it reason goes away.

Per patch description of what changed would have made reviewing
easier (for lazy people like me ;)
> 
> Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
> ---
>  drivers/hwmon/lis3lv02d.c |   21 ++++++++++++++-------
>  include/linux/lis3lv02d.h |    6 +++++-
>  2 files changed, 19 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index b44d4c5..d66cbe1 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -706,16 +706,16 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
>  	if (p->wakeup_flags) {
>  		dev->write(dev, FF_WU_CFG_1, p->wakeup_flags);
>  		dev->write(dev, FF_WU_THS_1, p->wakeup_thresh & 0x7f);
> -		/* default to 2.5ms for now */
> -		dev->write(dev, FF_WU_DURATION_1, 1);
> +		/* pdata value + 1 to keep this backward compatible*/
> +		dev->write(dev, FF_WU_DURATION_1, p->duration1 + 1);
>  		ctrl2 ^= HP_FF_WU1; /* Xor to keep compatible with old pdata*/
>  	}
>  
>  	if (p->wakeup_flags2) {
>  		dev->write(dev, FF_WU_CFG_2, p->wakeup_flags2);
>  		dev->write(dev, FF_WU_THS_2, p->wakeup_thresh2 & 0x7f);
> -		/* default to 2.5ms for now */
> -		dev->write(dev, FF_WU_DURATION_2, 1);
> +		/* pdata value + 1 to keep this backward compatible*/
> +		dev->write(dev, FF_WU_DURATION_2, p->duration2 + 1);
>  		ctrl2 ^= HP_FF_WU2; /* Xor to keep compatible with old pdata*/
>  	}
>  	/* Configure hipass filters */
> @@ -725,8 +725,8 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
>  		err = request_threaded_irq(p->irq2,
>  					NULL,
>  					lis302dl_interrupt_thread2_8b,
> -					IRQF_TRIGGER_RISING |
> -					IRQF_ONESHOT,
> +					IRQF_TRIGGER_RISING | IRQF_ONESHOT |
> +					(p->irq_flags2 & IRQF_TRIGGER_MASK),
>  					DRIVER_NAME, &lis3_dev);
>  		if (err < 0)
>  			printk(KERN_ERR DRIVER_NAME
> @@ -742,6 +742,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  {
>  	int err;
>  	irq_handler_t thread_fn;
> +	int irq_flags = 0;
>  
>  	dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I);
>  
> @@ -804,9 +805,14 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  		if (dev->whoami == WAI_8B)
>  			lis3lv02d_8b_configure(dev, p);
>  
> +		irq_flags = p->irq_flags1 & IRQF_TRIGGER_MASK;
> +
>  		dev->irq_cfg = p->irq_cfg;
>  		if (p->irq_cfg)
>  			dev->write(dev, CTRL_REG3, p->irq_cfg);
> +
> +		if (p->default_rate)
> +			lis3lv02d_set_odr(p->default_rate);
>  	}
>  
>  	/* bail if we did not get an IRQ from the bus layer */
> @@ -834,7 +840,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  
>  	err = request_threaded_irq(dev->irq, lis302dl_interrupt,
>  				thread_fn,
> -				IRQF_TRIGGER_RISING | IRQF_ONESHOT,
> +				IRQF_TRIGGER_RISING | IRQF_ONESHOT |
> +				irq_flags,
>  				DRIVER_NAME, &lis3_dev);
>  
>  	if (err < 0) {
> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
> index c4a4a52..18d578f 100644
> --- a/include/linux/lis3lv02d.h
> +++ b/include/linux/lis3lv02d.h
> @@ -36,7 +36,10 @@ struct lis3lv02d_platform_data {
>  #define LIS3_IRQ_OPEN_DRAIN	(1 << 6)
>  #define LIS3_IRQ_ACTIVE_LOW	(1 << 7)
>  	unsigned char irq_cfg;
> -
> +	unsigned char irq_flags1; /* Additional irq edge / level flags */
> +	unsigned char irq_flags2; /* Additional irq edge / level flags */
> +	unsigned char duration1;
> +	unsigned char duration2;
>  #define LIS3_WAKEUP_X_LO	(1 << 0)
>  #define LIS3_WAKEUP_X_HI	(1 << 1)
>  #define LIS3_WAKEUP_Y_LO	(1 << 2)
> @@ -66,6 +69,7 @@ struct lis3lv02d_platform_data {
>  	s8 axis_z;
>  #define LIS3_USE_REGULATOR_CTRL 0x01
>  	u16 driver_features;
> +	int default_rate;
>  	int (*setup_resources)(void);
>  	int (*release_resources)(void);
>  	/* Limits for selftest are specified in chip data sheet */


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 07/12] hwmon: lis3: New parameters to platform data
@ 2010-10-22 16:17     ` Jonathan Cameron
  0 siblings, 0 replies; 101+ messages in thread
From: Jonathan Cameron @ 2010-10-22 16:17 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: eric.piel-VkQ1JFuSMpfAbQlEx87xDw, khali-PUYAD+kWke1g9hUCZPvPmw,
	guenter.roeck-IzeFyvvaP7pWk0Htik3J/w,
	lm-sensors-GZX6beZjE8VD60Wz+7aTrA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 10/22/10 12:57, Samu Onkalo wrote:
> Added default output data rate setting to platform data.
> If default rate is 0, reset default value is used.
> Added control for duration via platform data.
> Added possibility to configure interrupts to trig on
> both rising and falling edge. The lis3 WU unit can be
> configured quite many ways and with some configurations it
> is quite handy to get coordinate refresh when some
> event trigs and when it reason goes away.

Per patch description of what changed would have made reviewing
easier (for lazy people like me ;)
> 
> Signed-off-by: Samu Onkalo <samu.p.onkalo-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
Acked-by: Jonathan Cameron <jic23-KWPb1pKIrIJaa/9Udqfwiw@public.gmane.org>
> ---
>  drivers/hwmon/lis3lv02d.c |   21 ++++++++++++++-------
>  include/linux/lis3lv02d.h |    6 +++++-
>  2 files changed, 19 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index b44d4c5..d66cbe1 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -706,16 +706,16 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
>  	if (p->wakeup_flags) {
>  		dev->write(dev, FF_WU_CFG_1, p->wakeup_flags);
>  		dev->write(dev, FF_WU_THS_1, p->wakeup_thresh & 0x7f);
> -		/* default to 2.5ms for now */
> -		dev->write(dev, FF_WU_DURATION_1, 1);
> +		/* pdata value + 1 to keep this backward compatible*/
> +		dev->write(dev, FF_WU_DURATION_1, p->duration1 + 1);
>  		ctrl2 ^= HP_FF_WU1; /* Xor to keep compatible with old pdata*/
>  	}
>  
>  	if (p->wakeup_flags2) {
>  		dev->write(dev, FF_WU_CFG_2, p->wakeup_flags2);
>  		dev->write(dev, FF_WU_THS_2, p->wakeup_thresh2 & 0x7f);
> -		/* default to 2.5ms for now */
> -		dev->write(dev, FF_WU_DURATION_2, 1);
> +		/* pdata value + 1 to keep this backward compatible*/
> +		dev->write(dev, FF_WU_DURATION_2, p->duration2 + 1);
>  		ctrl2 ^= HP_FF_WU2; /* Xor to keep compatible with old pdata*/
>  	}
>  	/* Configure hipass filters */
> @@ -725,8 +725,8 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
>  		err = request_threaded_irq(p->irq2,
>  					NULL,
>  					lis302dl_interrupt_thread2_8b,
> -					IRQF_TRIGGER_RISING |
> -					IRQF_ONESHOT,
> +					IRQF_TRIGGER_RISING | IRQF_ONESHOT |
> +					(p->irq_flags2 & IRQF_TRIGGER_MASK),
>  					DRIVER_NAME, &lis3_dev);
>  		if (err < 0)
>  			printk(KERN_ERR DRIVER_NAME
> @@ -742,6 +742,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  {
>  	int err;
>  	irq_handler_t thread_fn;
> +	int irq_flags = 0;
>  
>  	dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I);
>  
> @@ -804,9 +805,14 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  		if (dev->whoami == WAI_8B)
>  			lis3lv02d_8b_configure(dev, p);
>  
> +		irq_flags = p->irq_flags1 & IRQF_TRIGGER_MASK;
> +
>  		dev->irq_cfg = p->irq_cfg;
>  		if (p->irq_cfg)
>  			dev->write(dev, CTRL_REG3, p->irq_cfg);
> +
> +		if (p->default_rate)
> +			lis3lv02d_set_odr(p->default_rate);
>  	}
>  
>  	/* bail if we did not get an IRQ from the bus layer */
> @@ -834,7 +840,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  
>  	err = request_threaded_irq(dev->irq, lis302dl_interrupt,
>  				thread_fn,
> -				IRQF_TRIGGER_RISING | IRQF_ONESHOT,
> +				IRQF_TRIGGER_RISING | IRQF_ONESHOT |
> +				irq_flags,
>  				DRIVER_NAME, &lis3_dev);
>  
>  	if (err < 0) {
> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
> index c4a4a52..18d578f 100644
> --- a/include/linux/lis3lv02d.h
> +++ b/include/linux/lis3lv02d.h
> @@ -36,7 +36,10 @@ struct lis3lv02d_platform_data {
>  #define LIS3_IRQ_OPEN_DRAIN	(1 << 6)
>  #define LIS3_IRQ_ACTIVE_LOW	(1 << 7)
>  	unsigned char irq_cfg;
> -
> +	unsigned char irq_flags1; /* Additional irq edge / level flags */
> +	unsigned char irq_flags2; /* Additional irq edge / level flags */
> +	unsigned char duration1;
> +	unsigned char duration2;
>  #define LIS3_WAKEUP_X_LO	(1 << 0)
>  #define LIS3_WAKEUP_X_HI	(1 << 1)
>  #define LIS3_WAKEUP_Y_LO	(1 << 2)
> @@ -66,6 +69,7 @@ struct lis3lv02d_platform_data {
>  	s8 axis_z;
>  #define LIS3_USE_REGULATOR_CTRL 0x01
>  	u16 driver_features;
> +	int default_rate;
>  	int (*setup_resources)(void);
>  	int (*release_resources)(void);
>  	/* Limits for selftest are specified in chip data sheet */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 07/12] hwmon: lis3: New parameters to
@ 2010-10-22 16:17     ` Jonathan Cameron
  0 siblings, 0 replies; 101+ messages in thread
From: Jonathan Cameron @ 2010-10-22 16:17 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: eric.piel, khali, guenter.roeck, lm-sensors, linux-i2c, linux-kernel

On 10/22/10 12:57, Samu Onkalo wrote:
> Added default output data rate setting to platform data.
> If default rate is 0, reset default value is used.
> Added control for duration via platform data.
> Added possibility to configure interrupts to trig on
> both rising and falling edge. The lis3 WU unit can be
> configured quite many ways and with some configurations it
> is quite handy to get coordinate refresh when some
> event trigs and when it reason goes away.

Per patch description of what changed would have made reviewing
easier (for lazy people like me ;)
> 
> Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
> ---
>  drivers/hwmon/lis3lv02d.c |   21 ++++++++++++++-------
>  include/linux/lis3lv02d.h |    6 +++++-
>  2 files changed, 19 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index b44d4c5..d66cbe1 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -706,16 +706,16 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
>  	if (p->wakeup_flags) {
>  		dev->write(dev, FF_WU_CFG_1, p->wakeup_flags);
>  		dev->write(dev, FF_WU_THS_1, p->wakeup_thresh & 0x7f);
> -		/* default to 2.5ms for now */
> -		dev->write(dev, FF_WU_DURATION_1, 1);
> +		/* pdata value + 1 to keep this backward compatible*/
> +		dev->write(dev, FF_WU_DURATION_1, p->duration1 + 1);
>  		ctrl2 ^= HP_FF_WU1; /* Xor to keep compatible with old pdata*/
>  	}
>  
>  	if (p->wakeup_flags2) {
>  		dev->write(dev, FF_WU_CFG_2, p->wakeup_flags2);
>  		dev->write(dev, FF_WU_THS_2, p->wakeup_thresh2 & 0x7f);
> -		/* default to 2.5ms for now */
> -		dev->write(dev, FF_WU_DURATION_2, 1);
> +		/* pdata value + 1 to keep this backward compatible*/
> +		dev->write(dev, FF_WU_DURATION_2, p->duration2 + 1);
>  		ctrl2 ^= HP_FF_WU2; /* Xor to keep compatible with old pdata*/
>  	}
>  	/* Configure hipass filters */
> @@ -725,8 +725,8 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
>  		err = request_threaded_irq(p->irq2,
>  					NULL,
>  					lis302dl_interrupt_thread2_8b,
> -					IRQF_TRIGGER_RISING |
> -					IRQF_ONESHOT,
> +					IRQF_TRIGGER_RISING | IRQF_ONESHOT |
> +					(p->irq_flags2 & IRQF_TRIGGER_MASK),
>  					DRIVER_NAME, &lis3_dev);
>  		if (err < 0)
>  			printk(KERN_ERR DRIVER_NAME
> @@ -742,6 +742,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  {
>  	int err;
>  	irq_handler_t thread_fn;
> +	int irq_flags = 0;
>  
>  	dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I);
>  
> @@ -804,9 +805,14 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  		if (dev->whoami = WAI_8B)
>  			lis3lv02d_8b_configure(dev, p);
>  
> +		irq_flags = p->irq_flags1 & IRQF_TRIGGER_MASK;
> +
>  		dev->irq_cfg = p->irq_cfg;
>  		if (p->irq_cfg)
>  			dev->write(dev, CTRL_REG3, p->irq_cfg);
> +
> +		if (p->default_rate)
> +			lis3lv02d_set_odr(p->default_rate);
>  	}
>  
>  	/* bail if we did not get an IRQ from the bus layer */
> @@ -834,7 +840,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>  
>  	err = request_threaded_irq(dev->irq, lis302dl_interrupt,
>  				thread_fn,
> -				IRQF_TRIGGER_RISING | IRQF_ONESHOT,
> +				IRQF_TRIGGER_RISING | IRQF_ONESHOT |
> +				irq_flags,
>  				DRIVER_NAME, &lis3_dev);
>  
>  	if (err < 0) {
> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
> index c4a4a52..18d578f 100644
> --- a/include/linux/lis3lv02d.h
> +++ b/include/linux/lis3lv02d.h
> @@ -36,7 +36,10 @@ struct lis3lv02d_platform_data {
>  #define LIS3_IRQ_OPEN_DRAIN	(1 << 6)
>  #define LIS3_IRQ_ACTIVE_LOW	(1 << 7)
>  	unsigned char irq_cfg;
> -
> +	unsigned char irq_flags1; /* Additional irq edge / level flags */
> +	unsigned char irq_flags2; /* Additional irq edge / level flags */
> +	unsigned char duration1;
> +	unsigned char duration2;
>  #define LIS3_WAKEUP_X_LO	(1 << 0)
>  #define LIS3_WAKEUP_X_HI	(1 << 1)
>  #define LIS3_WAKEUP_Y_LO	(1 << 2)
> @@ -66,6 +69,7 @@ struct lis3lv02d_platform_data {
>  	s8 axis_z;
>  #define LIS3_USE_REGULATOR_CTRL 0x01
>  	u16 driver_features;
> +	int default_rate;
>  	int (*setup_resources)(void);
>  	int (*release_resources)(void);
>  	/* Limits for selftest are specified in chip data sheet */


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 09/12] hwmon: lis3: use block read to access data registers
  2010-10-22 11:57   ` [lm-sensors] [PATCH 09/12] hwmon: lis3: use block read to access Samu Onkalo
@ 2010-10-22 16:20     ` Jonathan Cameron
  -1 siblings, 0 replies; 101+ messages in thread
From: Jonathan Cameron @ 2010-10-22 16:20 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: eric.piel, khali, guenter.roeck, lm-sensors, linux-i2c, linux-kernel

On 10/22/10 12:57, Samu Onkalo wrote:
> Add optional blockread function to interface driver. If available
> the chip driver uses it for data register access. For 12 bit device
> it reads 6 bytes to get 3*16bit data. For 8 bit device it reads out
> 5 bytes since every second byte is dummy.
> This optimizes bus usage and reduces number of operations and
> interrupts needed for one data update.
> 
All good now.
> Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
> ---
>  drivers/hwmon/lis3lv02d.c     |   21 ++++++++++++++++++---
>  drivers/hwmon/lis3lv02d.h     |    1 +
>  drivers/hwmon/lis3lv02d_i2c.c |   13 +++++++++++++
>  include/linux/lis3lv02d.h     |    1 +
>  4 files changed, 33 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index 7555091..9fd946c 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -130,9 +130,24 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
>  	int position[3];
>  	int i;
>  
> -	position[0] = lis3->read_data(lis3, OUTX);
> -	position[1] = lis3->read_data(lis3, OUTY);
> -	position[2] = lis3->read_data(lis3, OUTZ);
> +	if (lis3->blkread) {
> +		if (lis3_dev.whoami == WAI_12B) {
> +			u16 data[3];
> +			lis3->blkread(lis3, OUTX_L, 6, (u8 *)data);
> +			for (i = 0; i < 3; i++)
> +				position[i] = (s16)le16_to_cpu(data[i]);
> +		} else {
> +			u8 data[5];
> +			/* Data: x, dummy, y, dummy, z */
> +			lis3->blkread(lis3, OUTX, 5, data);
> +			for (i = 0; i < 3; i++)
> +				position[i] = (s8)data[i * 2];
> +		}
> +	} else {
> +		position[0] = lis3->read_data(lis3, OUTX);
> +		position[1] = lis3->read_data(lis3, OUTY);
> +		position[2] = lis3->read_data(lis3, OUTZ);
> +	}
>  
>  	for (i = 0; i < 3; i++)
>  		position[i] = (position[i] * lis3->scale) / LIS3_ACCURACY;
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 2ac27b9..d3cb662 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -225,6 +225,7 @@ struct lis3lv02d {
>  	int (*init) (struct lis3lv02d *lis3);
>  	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
>  	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
> +	int (*blkread) (struct lis3lv02d *lis3, int reg, int len, u8 *ret);
>  	int (*reg_ctrl) (struct lis3lv02d *lis3, bool state);
>  
>  	int                     *odrs;     /* Supported output data rates */
> diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
> index 36171bf..61c109b 100644
> --- a/drivers/hwmon/lis3lv02d_i2c.c
> +++ b/drivers/hwmon/lis3lv02d_i2c.c
> @@ -66,6 +66,14 @@ static inline s32 lis3_i2c_read(struct lis3lv02d *lis3, int reg, u8 *v)
>  	return 0;
>  }
>  
> +static inline s32 lis3_i2c_blockread(struct lis3lv02d *lis3, int reg, int len,
> +				u8 *v)
> +{
> +	struct i2c_client *c = lis3->bus_priv;
> +	reg |= (1 << 7); /* 7th bit enables address auto incrementation */
> +	return i2c_smbus_read_i2c_block_data(c, reg, len, v);
> +}
> +
>  static int lis3_i2c_init(struct lis3lv02d *lis3)
>  {
>  	u8 reg;
> @@ -103,6 +111,11 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>  		if (pdata->driver_features & LIS3_USE_REGULATOR_CTRL)
>  			lis3_dev.reg_ctrl = lis3_reg_ctrl;
>  
> +		if ((pdata->driver_features & LIS3_USE_BLOCK_READ) &&
> +			(i2c_check_functionality(client->adapter,
> +						I2C_FUNC_SMBUS_I2C_BLOCK)))
> +			lis3_dev.blkread  = lis3_i2c_blockread;
> +
>  		if (pdata->axis_x)
>  			lis3lv02d_axis_map.x = pdata->axis_x;
>  
> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
> index 18d578f..c949612 100644
> --- a/include/linux/lis3lv02d.h
> +++ b/include/linux/lis3lv02d.h
> @@ -68,6 +68,7 @@ struct lis3lv02d_platform_data {
>  	s8 axis_y;
>  	s8 axis_z;
>  #define LIS3_USE_REGULATOR_CTRL 0x01
> +#define LIS3_USE_BLOCK_READ	0x02
>  	u16 driver_features;
>  	int default_rate;
>  	int (*setup_resources)(void);


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 09/12] hwmon: lis3: use block read to
@ 2010-10-22 16:20     ` Jonathan Cameron
  0 siblings, 0 replies; 101+ messages in thread
From: Jonathan Cameron @ 2010-10-22 16:20 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: eric.piel, khali, guenter.roeck, lm-sensors, linux-i2c, linux-kernel

On 10/22/10 12:57, Samu Onkalo wrote:
> Add optional blockread function to interface driver. If available
> the chip driver uses it for data register access. For 12 bit device
> it reads 6 bytes to get 3*16bit data. For 8 bit device it reads out
> 5 bytes since every second byte is dummy.
> This optimizes bus usage and reduces number of operations and
> interrupts needed for one data update.
> 
All good now.
> Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
> ---
>  drivers/hwmon/lis3lv02d.c     |   21 ++++++++++++++++++---
>  drivers/hwmon/lis3lv02d.h     |    1 +
>  drivers/hwmon/lis3lv02d_i2c.c |   13 +++++++++++++
>  include/linux/lis3lv02d.h     |    1 +
>  4 files changed, 33 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index 7555091..9fd946c 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -130,9 +130,24 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
>  	int position[3];
>  	int i;
>  
> -	position[0] = lis3->read_data(lis3, OUTX);
> -	position[1] = lis3->read_data(lis3, OUTY);
> -	position[2] = lis3->read_data(lis3, OUTZ);
> +	if (lis3->blkread) {
> +		if (lis3_dev.whoami = WAI_12B) {
> +			u16 data[3];
> +			lis3->blkread(lis3, OUTX_L, 6, (u8 *)data);
> +			for (i = 0; i < 3; i++)
> +				position[i] = (s16)le16_to_cpu(data[i]);
> +		} else {
> +			u8 data[5];
> +			/* Data: x, dummy, y, dummy, z */
> +			lis3->blkread(lis3, OUTX, 5, data);
> +			for (i = 0; i < 3; i++)
> +				position[i] = (s8)data[i * 2];
> +		}
> +	} else {
> +		position[0] = lis3->read_data(lis3, OUTX);
> +		position[1] = lis3->read_data(lis3, OUTY);
> +		position[2] = lis3->read_data(lis3, OUTZ);
> +	}
>  
>  	for (i = 0; i < 3; i++)
>  		position[i] = (position[i] * lis3->scale) / LIS3_ACCURACY;
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 2ac27b9..d3cb662 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -225,6 +225,7 @@ struct lis3lv02d {
>  	int (*init) (struct lis3lv02d *lis3);
>  	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
>  	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
> +	int (*blkread) (struct lis3lv02d *lis3, int reg, int len, u8 *ret);
>  	int (*reg_ctrl) (struct lis3lv02d *lis3, bool state);
>  
>  	int                     *odrs;     /* Supported output data rates */
> diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
> index 36171bf..61c109b 100644
> --- a/drivers/hwmon/lis3lv02d_i2c.c
> +++ b/drivers/hwmon/lis3lv02d_i2c.c
> @@ -66,6 +66,14 @@ static inline s32 lis3_i2c_read(struct lis3lv02d *lis3, int reg, u8 *v)
>  	return 0;
>  }
>  
> +static inline s32 lis3_i2c_blockread(struct lis3lv02d *lis3, int reg, int len,
> +				u8 *v)
> +{
> +	struct i2c_client *c = lis3->bus_priv;
> +	reg |= (1 << 7); /* 7th bit enables address auto incrementation */
> +	return i2c_smbus_read_i2c_block_data(c, reg, len, v);
> +}
> +
>  static int lis3_i2c_init(struct lis3lv02d *lis3)
>  {
>  	u8 reg;
> @@ -103,6 +111,11 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>  		if (pdata->driver_features & LIS3_USE_REGULATOR_CTRL)
>  			lis3_dev.reg_ctrl = lis3_reg_ctrl;
>  
> +		if ((pdata->driver_features & LIS3_USE_BLOCK_READ) &&
> +			(i2c_check_functionality(client->adapter,
> +						I2C_FUNC_SMBUS_I2C_BLOCK)))
> +			lis3_dev.blkread  = lis3_i2c_blockread;
> +
>  		if (pdata->axis_x)
>  			lis3lv02d_axis_map.x = pdata->axis_x;
>  
> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
> index 18d578f..c949612 100644
> --- a/include/linux/lis3lv02d.h
> +++ b/include/linux/lis3lv02d.h
> @@ -68,6 +68,7 @@ struct lis3lv02d_platform_data {
>  	s8 axis_y;
>  	s8 axis_z;
>  #define LIS3_USE_REGULATOR_CTRL 0x01
> +#define LIS3_USE_BLOCK_READ	0x02
>  	u16 driver_features;
>  	int default_rate;
>  	int (*setup_resources)(void);


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 11/12] hwmon: lis3: Short explanations of platform data fields
@ 2010-10-22 16:25     ` Jonathan Cameron
  0 siblings, 0 replies; 101+ messages in thread
From: Jonathan Cameron @ 2010-10-22 16:25 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: eric.piel, khali, guenter.roeck, lm-sensors, linux-i2c, linux-kernel

On 10/22/10 12:57, Samu Onkalo wrote:
> Short documentation at kernel doc format.
> 
Please check the use of tabs etc in the alignment of the documentation.
It might work out right, but looks a bit random currently.

Couple of typos.  Otherwise looks fine to me, but I'll only give
a reviewed by on this as I really don't know the devices well enough!
> Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
> ---
>  include/linux/lis3lv02d.h |   41 +++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 41 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
> index c949612..da294cd 100644
> --- a/include/linux/lis3lv02d.h
> +++ b/include/linux/lis3lv02d.h
> @@ -1,6 +1,47 @@
>  #ifndef __LIS3LV02D_H_
>  #define __LIS3LV02D_H_
>  
> +/**
> + * struct lis3lv02d_platform_data - lis3 chip family platform data
> + * @click_flags:       Click detection unit configuration
> + * @click_thresh_x:    Click detection unit x axis treshold
threshold
> + * @click_thresh_y:    Click detection unit y axis treshold
> + * @click_thresh_z:    Click detection unit z axis treshold
> + * @click_time_limit:  Click detection unit time parameter
> + * @click_latency:     Click detection unit latency parameter
> + * @click_window:      Click detection unit window parameter
> + * @irq_cfg:	       On chip irq configuration (click / data available / wu)
wu isn't a terribly helpful acronym, please put it in long hand.  iirc kernel
doc lets you use multiple lines for parameter descriptions...
> + * @irq_flags1:	       Additional irq triggering flags for irq channel 0
> + * @irq_flags2:	       Additional irq triggering flags for irq channel 1
> + * @duration1:	       Wake up unit 1 duration parameter
> + * @duration2:	       Wake up unit 2 duration parameter
> + * @wakeup_flags:      Wakeup unit 1 flags
> + * @wakeup_thresh:     Wakeup unit 1 threshold value
> + * @wakeup_flags2:     Wakeup unit 2 flags
> + * @wakeup_thresh2:    Wakeup unit 2 threshold value
> + * @hipass_ctrl:       Hi-pass filter control
High-pass
> + * @axis_x:	       Remap parameter for x-axis
> + * @axis_y:	       Remap parameter for y-axis
> + * @axis_z:	       Remap parameter for z-axis
> + * @driver_features:   Enable bits for different features. Disabled by default
> + * @default_rate:      Default sampling rate. 0 means reset default
> + * @setup_resources:   Interrupt line setup call back function
> + * @release_resources: Interrupt line release call back function
> + * @st_min_limits[3]:  Selftest acceptance minimum values
> + * @st_max_limits[3]:  Selftest accepratnce maximum values
acceptance
> + * @irq2:	       Irq line 2 number
> + *
> + * Platform data is used to setup the sensor chip. Meaning of the different
> + * chip features can be found from the data sheet. Currently the data is used
> + * only for the 8 bit device. The 8 bit device has two wake up / free fall
> + * detection units and click detection unit. There are plenty of ways to
> + * configure the chip which makes is quite impossible to explain meaning of the
> + * fields here. Behaviour of the detection blocks varies heavily depending
> + * on the configuration. Irq_flags can be used to enable interrupt detection
> + * on the both edges. With proper chip configuration this produces interrupt
> + * when some trigger starts and when it goes away.
> + */
> +
>  struct lis3lv02d_platform_data {
>  	/* please note: the 'click' feature is only supported for
>  	 * LIS[32]02DL variants of the chip and will be ignored for


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 11/12] hwmon: lis3: Short explanations of platform data fields
@ 2010-10-22 16:25     ` Jonathan Cameron
  0 siblings, 0 replies; 101+ messages in thread
From: Jonathan Cameron @ 2010-10-22 16:25 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: eric.piel-VkQ1JFuSMpfAbQlEx87xDw, khali-PUYAD+kWke1g9hUCZPvPmw,
	guenter.roeck-IzeFyvvaP7pWk0Htik3J/w,
	lm-sensors-GZX6beZjE8VD60Wz+7aTrA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On 10/22/10 12:57, Samu Onkalo wrote:
> Short documentation at kernel doc format.
> 
Please check the use of tabs etc in the alignment of the documentation.
It might work out right, but looks a bit random currently.

Couple of typos.  Otherwise looks fine to me, but I'll only give
a reviewed by on this as I really don't know the devices well enough!
> Signed-off-by: Samu Onkalo <samu.p.onkalo-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
> ---
>  include/linux/lis3lv02d.h |   41 +++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 41 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
> index c949612..da294cd 100644
> --- a/include/linux/lis3lv02d.h
> +++ b/include/linux/lis3lv02d.h
> @@ -1,6 +1,47 @@
>  #ifndef __LIS3LV02D_H_
>  #define __LIS3LV02D_H_
>  
> +/**
> + * struct lis3lv02d_platform_data - lis3 chip family platform data
> + * @click_flags:       Click detection unit configuration
> + * @click_thresh_x:    Click detection unit x axis treshold
threshold
> + * @click_thresh_y:    Click detection unit y axis treshold
> + * @click_thresh_z:    Click detection unit z axis treshold
> + * @click_time_limit:  Click detection unit time parameter
> + * @click_latency:     Click detection unit latency parameter
> + * @click_window:      Click detection unit window parameter
> + * @irq_cfg:	       On chip irq configuration (click / data available / wu)
wu isn't a terribly helpful acronym, please put it in long hand.  iirc kernel
doc lets you use multiple lines for parameter descriptions...
> + * @irq_flags1:	       Additional irq triggering flags for irq channel 0
> + * @irq_flags2:	       Additional irq triggering flags for irq channel 1
> + * @duration1:	       Wake up unit 1 duration parameter
> + * @duration2:	       Wake up unit 2 duration parameter
> + * @wakeup_flags:      Wakeup unit 1 flags
> + * @wakeup_thresh:     Wakeup unit 1 threshold value
> + * @wakeup_flags2:     Wakeup unit 2 flags
> + * @wakeup_thresh2:    Wakeup unit 2 threshold value
> + * @hipass_ctrl:       Hi-pass filter control
High-pass
> + * @axis_x:	       Remap parameter for x-axis
> + * @axis_y:	       Remap parameter for y-axis
> + * @axis_z:	       Remap parameter for z-axis
> + * @driver_features:   Enable bits for different features. Disabled by default
> + * @default_rate:      Default sampling rate. 0 means reset default
> + * @setup_resources:   Interrupt line setup call back function
> + * @release_resources: Interrupt line release call back function
> + * @st_min_limits[3]:  Selftest acceptance minimum values
> + * @st_max_limits[3]:  Selftest accepratnce maximum values
acceptance
> + * @irq2:	       Irq line 2 number
> + *
> + * Platform data is used to setup the sensor chip. Meaning of the different
> + * chip features can be found from the data sheet. Currently the data is used
> + * only for the 8 bit device. The 8 bit device has two wake up / free fall
> + * detection units and click detection unit. There are plenty of ways to
> + * configure the chip which makes is quite impossible to explain meaning of the
> + * fields here. Behaviour of the detection blocks varies heavily depending
> + * on the configuration. Irq_flags can be used to enable interrupt detection
> + * on the both edges. With proper chip configuration this produces interrupt
> + * when some trigger starts and when it goes away.
> + */
> +
>  struct lis3lv02d_platform_data {
>  	/* please note: the 'click' feature is only supported for
>  	 * LIS[32]02DL variants of the chip and will be ignored for

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 11/12] hwmon: lis3: Short explanations of
@ 2010-10-22 16:25     ` Jonathan Cameron
  0 siblings, 0 replies; 101+ messages in thread
From: Jonathan Cameron @ 2010-10-22 16:25 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: eric.piel, khali, guenter.roeck, lm-sensors, linux-i2c, linux-kernel

On 10/22/10 12:57, Samu Onkalo wrote:
> Short documentation at kernel doc format.
> 
Please check the use of tabs etc in the alignment of the documentation.
It might work out right, but looks a bit random currently.

Couple of typos.  Otherwise looks fine to me, but I'll only give
a reviewed by on this as I really don't know the devices well enough!
> Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
> ---
>  include/linux/lis3lv02d.h |   41 +++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 41 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
> index c949612..da294cd 100644
> --- a/include/linux/lis3lv02d.h
> +++ b/include/linux/lis3lv02d.h
> @@ -1,6 +1,47 @@
>  #ifndef __LIS3LV02D_H_
>  #define __LIS3LV02D_H_
>  
> +/**
> + * struct lis3lv02d_platform_data - lis3 chip family platform data
> + * @click_flags:       Click detection unit configuration
> + * @click_thresh_x:    Click detection unit x axis treshold
threshold
> + * @click_thresh_y:    Click detection unit y axis treshold
> + * @click_thresh_z:    Click detection unit z axis treshold
> + * @click_time_limit:  Click detection unit time parameter
> + * @click_latency:     Click detection unit latency parameter
> + * @click_window:      Click detection unit window parameter
> + * @irq_cfg:	       On chip irq configuration (click / data available / wu)
wu isn't a terribly helpful acronym, please put it in long hand.  iirc kernel
doc lets you use multiple lines for parameter descriptions...
> + * @irq_flags1:	       Additional irq triggering flags for irq channel 0
> + * @irq_flags2:	       Additional irq triggering flags for irq channel 1
> + * @duration1:	       Wake up unit 1 duration parameter
> + * @duration2:	       Wake up unit 2 duration parameter
> + * @wakeup_flags:      Wakeup unit 1 flags
> + * @wakeup_thresh:     Wakeup unit 1 threshold value
> + * @wakeup_flags2:     Wakeup unit 2 flags
> + * @wakeup_thresh2:    Wakeup unit 2 threshold value
> + * @hipass_ctrl:       Hi-pass filter control
High-pass
> + * @axis_x:	       Remap parameter for x-axis
> + * @axis_y:	       Remap parameter for y-axis
> + * @axis_z:	       Remap parameter for z-axis
> + * @driver_features:   Enable bits for different features. Disabled by default
> + * @default_rate:      Default sampling rate. 0 means reset default
> + * @setup_resources:   Interrupt line setup call back function
> + * @release_resources: Interrupt line release call back function
> + * @st_min_limits[3]:  Selftest acceptance minimum values
> + * @st_max_limits[3]:  Selftest accepratnce maximum values
acceptance
> + * @irq2:	       Irq line 2 number
> + *
> + * Platform data is used to setup the sensor chip. Meaning of the different
> + * chip features can be found from the data sheet. Currently the data is used
> + * only for the 8 bit device. The 8 bit device has two wake up / free fall
> + * detection units and click detection unit. There are plenty of ways to
> + * configure the chip which makes is quite impossible to explain meaning of the
> + * fields here. Behaviour of the detection blocks varies heavily depending
> + * on the configuration. Irq_flags can be used to enable interrupt detection
> + * on the both edges. With proper chip configuration this produces interrupt
> + * when some trigger starts and when it goes away.
> + */
> +
>  struct lis3lv02d_platform_data {
>  	/* please note: the 'click' feature is only supported for
>  	 * LIS[32]02DL variants of the chip and will be ignored for


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-22 20:08   ` Guenter Roeck
  0 siblings, 0 replies; 101+ messages in thread
From: Guenter Roeck @ 2010-10-22 20:08 UTC (permalink / raw)
  To: Samu Onkalo; +Cc: eric.piel, khali, jic23, lm-sensors, linux-i2c, linux-kernel

On Fri, 2010-10-22 at 07:57 -0400, Samu Onkalo wrote:
> Changes are tested only with I2C interface using 8bit sensor since I don't
> have other possibilities. Some features are not enabled
> by default since I can't test them with all possible configurations.
> Platform data contains field which controls new features.
> 
[ ... ]
> 
> Samu Onkalo (12):
>   hwmon: lis3: pm_runtime support
>   hwmon: lis3: regulator control
>   hwmon: lis3: Cleanup interrupt handling
>   hwmon: lis3: Update coordinates at polled device open
>   hwmon: lis3: Power on corrections
>   hwmon: lis3: restore axis enabled bits
>   hwmon: lis3: New parameters to platform data
>   hwmon: lis3: Adjust fuzziness for 8 bit device
>   hwmon: lis3: use block read to access data registers
>   hwmon: lis3: Enhance lis3 selftest with IRQ line test
>   hwmon: lis3: Short explanations of platform data fields
>   hwmon: lis3: Release resources is case of failure
> 
>  drivers/hwmon/lis3lv02d.c     |  304 ++++++++++++++++++++++++++++++++++------
>  drivers/hwmon/lis3lv02d.h     |   18 +++
>  drivers/hwmon/lis3lv02d_i2c.c |  127 +++++++++++++++--
>  drivers/hwmon/lis3lv02d_spi.c |    2 +-
>  include/linux/lis3lv02d.h     |   50 +++++++-
>  5 files changed, 439 insertions(+), 62 deletions(-)
> 
Eric, can you Ack this series ?

Guenter



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-22 20:08   ` Guenter Roeck
  0 siblings, 0 replies; 101+ messages in thread
From: Guenter Roeck @ 2010-10-22 20:08 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: eric.piel-VkQ1JFuSMpfAbQlEx87xDw, khali-PUYAD+kWke1g9hUCZPvPmw,
	jic23-KWPb1pKIrIJaa/9Udqfwiw, lm-sensors-GZX6beZjE8VD60Wz+7aTrA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Fri, 2010-10-22 at 07:57 -0400, Samu Onkalo wrote:
> Changes are tested only with I2C interface using 8bit sensor since I don't
> have other possibilities. Some features are not enabled
> by default since I can't test them with all possible configurations.
> Platform data contains field which controls new features.
> 
[ ... ]
> 
> Samu Onkalo (12):
>   hwmon: lis3: pm_runtime support
>   hwmon: lis3: regulator control
>   hwmon: lis3: Cleanup interrupt handling
>   hwmon: lis3: Update coordinates at polled device open
>   hwmon: lis3: Power on corrections
>   hwmon: lis3: restore axis enabled bits
>   hwmon: lis3: New parameters to platform data
>   hwmon: lis3: Adjust fuzziness for 8 bit device
>   hwmon: lis3: use block read to access data registers
>   hwmon: lis3: Enhance lis3 selftest with IRQ line test
>   hwmon: lis3: Short explanations of platform data fields
>   hwmon: lis3: Release resources is case of failure
> 
>  drivers/hwmon/lis3lv02d.c     |  304 ++++++++++++++++++++++++++++++++++------
>  drivers/hwmon/lis3lv02d.h     |   18 +++
>  drivers/hwmon/lis3lv02d_i2c.c |  127 +++++++++++++++--
>  drivers/hwmon/lis3lv02d_spi.c |    2 +-
>  include/linux/lis3lv02d.h     |   50 +++++++-
>  5 files changed, 439 insertions(+), 62 deletions(-)
> 
Eric, can you Ack this series ?

Guenter

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-22 20:08   ` Guenter Roeck
  0 siblings, 0 replies; 101+ messages in thread
From: Guenter Roeck @ 2010-10-22 20:08 UTC (permalink / raw)
  To: Samu Onkalo; +Cc: eric.piel, khali, jic23, lm-sensors, linux-i2c, linux-kernel

On Fri, 2010-10-22 at 07:57 -0400, Samu Onkalo wrote:
> Changes are tested only with I2C interface using 8bit sensor since I don't
> have other possibilities. Some features are not enabled
> by default since I can't test them with all possible configurations.
> Platform data contains field which controls new features.
> 
[ ... ]
> 
> Samu Onkalo (12):
>   hwmon: lis3: pm_runtime support
>   hwmon: lis3: regulator control
>   hwmon: lis3: Cleanup interrupt handling
>   hwmon: lis3: Update coordinates at polled device open
>   hwmon: lis3: Power on corrections
>   hwmon: lis3: restore axis enabled bits
>   hwmon: lis3: New parameters to platform data
>   hwmon: lis3: Adjust fuzziness for 8 bit device
>   hwmon: lis3: use block read to access data registers
>   hwmon: lis3: Enhance lis3 selftest with IRQ line test
>   hwmon: lis3: Short explanations of platform data fields
>   hwmon: lis3: Release resources is case of failure
> 
>  drivers/hwmon/lis3lv02d.c     |  304 ++++++++++++++++++++++++++++++++++------
>  drivers/hwmon/lis3lv02d.h     |   18 +++
>  drivers/hwmon/lis3lv02d_i2c.c |  127 +++++++++++++++--
>  drivers/hwmon/lis3lv02d_spi.c |    2 +-
>  include/linux/lis3lv02d.h     |   50 +++++++-
>  5 files changed, 439 insertions(+), 62 deletions(-)
> 
Eric, can you Ack this series ?

Guenter



_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 00/12] lis3 accelerator feature update
  2010-10-22 20:08   ` Guenter Roeck
@ 2010-10-22 23:44     ` Éric Piel
  -1 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-22 23:44 UTC (permalink / raw)
  To: guenter.roeck
  Cc: Samu Onkalo, khali, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 22:08, Guenter Roeck schreef:
> On Fri, 2010-10-22 at 07:57 -0400, Samu Onkalo wrote:
>> Changes are tested only with I2C interface using 8bit sensor since I don't
>> have other possibilities. Some features are not enabled
>> by default since I can't test them with all possible configurations.
>> Platform data contains field which controls new features.
>>
> [ ... ]
>>
>> Samu Onkalo (12):
>>   hwmon: lis3: pm_runtime support
>>   hwmon: lis3: regulator control
>>   hwmon: lis3: Cleanup interrupt handling
>>   hwmon: lis3: Update coordinates at polled device open
>>   hwmon: lis3: Power on corrections
>>   hwmon: lis3: restore axis enabled bits
>>   hwmon: lis3: New parameters to platform data
>>   hwmon: lis3: Adjust fuzziness for 8 bit device
>>   hwmon: lis3: use block read to access data registers
>>   hwmon: lis3: Enhance lis3 selftest with IRQ line test
>>   hwmon: lis3: Short explanations of platform data fields
>>   hwmon: lis3: Release resources is case of failure
>>
>>  drivers/hwmon/lis3lv02d.c     |  304 ++++++++++++++++++++++++++++++++++------
>>  drivers/hwmon/lis3lv02d.h     |   18 +++
>>  drivers/hwmon/lis3lv02d_i2c.c |  127 +++++++++++++++--
>>  drivers/hwmon/lis3lv02d_spi.c |    2 +-
>>  include/linux/lis3lv02d.h     |   50 +++++++-
>>  5 files changed, 439 insertions(+), 62 deletions(-)
>>
> Eric, can you Ack this series ?
Hi, I'll try to review, test and ack the series this weekend :-)

Eric

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-22 23:44     ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-22 23:44 UTC (permalink / raw)
  To: guenter.roeck
  Cc: Samu Onkalo, khali, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 22:08, Guenter Roeck schreef:
> On Fri, 2010-10-22 at 07:57 -0400, Samu Onkalo wrote:
>> Changes are tested only with I2C interface using 8bit sensor since I don't
>> have other possibilities. Some features are not enabled
>> by default since I can't test them with all possible configurations.
>> Platform data contains field which controls new features.
>>
> [ ... ]
>>
>> Samu Onkalo (12):
>>   hwmon: lis3: pm_runtime support
>>   hwmon: lis3: regulator control
>>   hwmon: lis3: Cleanup interrupt handling
>>   hwmon: lis3: Update coordinates at polled device open
>>   hwmon: lis3: Power on corrections
>>   hwmon: lis3: restore axis enabled bits
>>   hwmon: lis3: New parameters to platform data
>>   hwmon: lis3: Adjust fuzziness for 8 bit device
>>   hwmon: lis3: use block read to access data registers
>>   hwmon: lis3: Enhance lis3 selftest with IRQ line test
>>   hwmon: lis3: Short explanations of platform data fields
>>   hwmon: lis3: Release resources is case of failure
>>
>>  drivers/hwmon/lis3lv02d.c     |  304 ++++++++++++++++++++++++++++++++++------
>>  drivers/hwmon/lis3lv02d.h     |   18 +++
>>  drivers/hwmon/lis3lv02d_i2c.c |  127 +++++++++++++++--
>>  drivers/hwmon/lis3lv02d_spi.c |    2 +-
>>  include/linux/lis3lv02d.h     |   50 +++++++-
>>  5 files changed, 439 insertions(+), 62 deletions(-)
>>
> Eric, can you Ack this series ?
Hi, I'll try to review, test and ack the series this weekend :-)

Eric

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-23  1:05       ` Guenter Roeck
  0 siblings, 0 replies; 101+ messages in thread
From: Guenter Roeck @ 2010-10-23  1:05 UTC (permalink / raw)
  To: Éric Piel
  Cc: Samu Onkalo, khali, jic23, lm-sensors, linux-i2c, linux-kernel

On Fri, Oct 22, 2010 at 07:44:48PM -0400, Éric Piel wrote:
> Op 22-10-10 22:08, Guenter Roeck schreef:
> > On Fri, 2010-10-22 at 07:57 -0400, Samu Onkalo wrote:
> >> Changes are tested only with I2C interface using 8bit sensor since I don't
> >> have other possibilities. Some features are not enabled
> >> by default since I can't test them with all possible configurations.
> >> Platform data contains field which controls new features.
> >>
> > [ ... ]
> >>
> >> Samu Onkalo (12):
> >>   hwmon: lis3: pm_runtime support
> >>   hwmon: lis3: regulator control
> >>   hwmon: lis3: Cleanup interrupt handling
> >>   hwmon: lis3: Update coordinates at polled device open
> >>   hwmon: lis3: Power on corrections
> >>   hwmon: lis3: restore axis enabled bits
> >>   hwmon: lis3: New parameters to platform data
> >>   hwmon: lis3: Adjust fuzziness for 8 bit device
> >>   hwmon: lis3: use block read to access data registers
> >>   hwmon: lis3: Enhance lis3 selftest with IRQ line test
> >>   hwmon: lis3: Short explanations of platform data fields
> >>   hwmon: lis3: Release resources is case of failure
> >>
> >>  drivers/hwmon/lis3lv02d.c     |  304 ++++++++++++++++++++++++++++++++++------
> >>  drivers/hwmon/lis3lv02d.h     |   18 +++
> >>  drivers/hwmon/lis3lv02d_i2c.c |  127 +++++++++++++++--
> >>  drivers/hwmon/lis3lv02d_spi.c |    2 +-
> >>  include/linux/lis3lv02d.h     |   50 +++++++-
> >>  5 files changed, 439 insertions(+), 62 deletions(-)
> >>
> > Eric, can you Ack this series ?
> Hi, I'll try to review, test and ack the series this weekend :-)
> 
Thanks!

Guenter

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-23  1:05       ` Guenter Roeck
  0 siblings, 0 replies; 101+ messages in thread
From: Guenter Roeck @ 2010-10-23  1:05 UTC (permalink / raw)
  To: Éric Piel
  Cc: Samu Onkalo, khali-PUYAD+kWke1g9hUCZPvPmw,
	jic23-KWPb1pKIrIJaa/9Udqfwiw, lm-sensors-GZX6beZjE8VD60Wz+7aTrA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Fri, Oct 22, 2010 at 07:44:48PM -0400, Éric Piel wrote:
> Op 22-10-10 22:08, Guenter Roeck schreef:
> > On Fri, 2010-10-22 at 07:57 -0400, Samu Onkalo wrote:
> >> Changes are tested only with I2C interface using 8bit sensor since I don't
> >> have other possibilities. Some features are not enabled
> >> by default since I can't test them with all possible configurations.
> >> Platform data contains field which controls new features.
> >>
> > [ ... ]
> >>
> >> Samu Onkalo (12):
> >>   hwmon: lis3: pm_runtime support
> >>   hwmon: lis3: regulator control
> >>   hwmon: lis3: Cleanup interrupt handling
> >>   hwmon: lis3: Update coordinates at polled device open
> >>   hwmon: lis3: Power on corrections
> >>   hwmon: lis3: restore axis enabled bits
> >>   hwmon: lis3: New parameters to platform data
> >>   hwmon: lis3: Adjust fuzziness for 8 bit device
> >>   hwmon: lis3: use block read to access data registers
> >>   hwmon: lis3: Enhance lis3 selftest with IRQ line test
> >>   hwmon: lis3: Short explanations of platform data fields
> >>   hwmon: lis3: Release resources is case of failure
> >>
> >>  drivers/hwmon/lis3lv02d.c     |  304 ++++++++++++++++++++++++++++++++++------
> >>  drivers/hwmon/lis3lv02d.h     |   18 +++
> >>  drivers/hwmon/lis3lv02d_i2c.c |  127 +++++++++++++++--
> >>  drivers/hwmon/lis3lv02d_spi.c |    2 +-
> >>  include/linux/lis3lv02d.h     |   50 +++++++-
> >>  5 files changed, 439 insertions(+), 62 deletions(-)
> >>
> > Eric, can you Ack this series ?
> Hi, I'll try to review, test and ack the series this weekend :-)
> 
Thanks!

Guenter

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-23  1:05       ` Guenter Roeck
  0 siblings, 0 replies; 101+ messages in thread
From: Guenter Roeck @ 2010-10-23  1:05 UTC (permalink / raw)
  To: Éric Piel
  Cc: Samu Onkalo, khali, jic23, lm-sensors, linux-i2c, linux-kernel

On Fri, Oct 22, 2010 at 07:44:48PM -0400, Éric Piel wrote:
> Op 22-10-10 22:08, Guenter Roeck schreef:
> > On Fri, 2010-10-22 at 07:57 -0400, Samu Onkalo wrote:
> >> Changes are tested only with I2C interface using 8bit sensor since I don't
> >> have other possibilities. Some features are not enabled
> >> by default since I can't test them with all possible configurations.
> >> Platform data contains field which controls new features.
> >>
> > [ ... ]
> >>
> >> Samu Onkalo (12):
> >>   hwmon: lis3: pm_runtime support
> >>   hwmon: lis3: regulator control
> >>   hwmon: lis3: Cleanup interrupt handling
> >>   hwmon: lis3: Update coordinates at polled device open
> >>   hwmon: lis3: Power on corrections
> >>   hwmon: lis3: restore axis enabled bits
> >>   hwmon: lis3: New parameters to platform data
> >>   hwmon: lis3: Adjust fuzziness for 8 bit device
> >>   hwmon: lis3: use block read to access data registers
> >>   hwmon: lis3: Enhance lis3 selftest with IRQ line test
> >>   hwmon: lis3: Short explanations of platform data fields
> >>   hwmon: lis3: Release resources is case of failure
> >>
> >>  drivers/hwmon/lis3lv02d.c     |  304 ++++++++++++++++++++++++++++++++++------
> >>  drivers/hwmon/lis3lv02d.h     |   18 +++
> >>  drivers/hwmon/lis3lv02d_i2c.c |  127 +++++++++++++++--
> >>  drivers/hwmon/lis3lv02d_spi.c |    2 +-
> >>  include/linux/lis3lv02d.h     |   50 +++++++-
> >>  5 files changed, 439 insertions(+), 62 deletions(-)
> >>
> > Eric, can you Ack this series ?
> Hi, I'll try to review, test and ack the series this weekend :-)
> 
Thanks!

Guenter

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [PATCHv2] hwmon: lis3: Short explanations of platform data fields
       [not found]     ` <4CC1BAEE.3030708-KWPb1pKIrIJaa/9Udqfwiw@public.gmane.org>
@ 2010-10-23 13:39         ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-23 13:39 UTC (permalink / raw)
  To: eric.piel-VkQ1JFuSMpfAbQlEx87xDw,
	guenter.roeck-IzeFyvvaP7pWk0Htik3J/w,
	jic23-KWPb1pKIrIJaa/9Udqfwiw
  Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA, lm-sensors-GZX6beZjE8VD60Wz+7aTrA

Short documentation at kernel doc format.

Signed-off-by: Samu Onkalo <samu.p.onkalo-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
---
 include/linux/lis3lv02d.h |   46 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 46 insertions(+), 0 deletions(-)

diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
index c949612..d4292c8 100644
--- a/include/linux/lis3lv02d.h
+++ b/include/linux/lis3lv02d.h
@@ -1,6 +1,52 @@
 #ifndef __LIS3LV02D_H_
 #define __LIS3LV02D_H_
 
+/**
+ * struct lis3lv02d_platform_data - lis3 chip family platform data
+ * @click_flags:	Click detection unit configuration
+ * @click_thresh_x:	Click detection unit x axis threshold
+ * @click_thresh_y:	Click detection unit y axis threshold
+ * @click_thresh_z:	Click detection unit z axis threshold
+ * @click_time_limit:	Click detection unit time parameter
+ * @click_latency:	Click detection unit latency parameter
+ * @click_window:	Click detection unit window parameter
+ * @irq_cfg:		On chip irq source and type configuration (click /
+ *			data available / wake up, open drain, polarity)
+ * @irq_flags1:		Additional irq triggering flags for irq channel 0
+ * @irq_flags2:		Additional irq triggering flags for irq channel 1
+ * @duration1:		Wake up unit 1 duration parameter
+ * @duration2:		Wake up unit 2 duration parameter
+ * @wakeup_flags:	Wake up unit 1 flags
+ * @wakeup_thresh:	Wake up unit 1 threshold value
+ * @wakeup_flags2:	Wake up unit 2 flags
+ * @wakeup_thresh2:	Wake up unit 2 threshold value
+ * @hipass_ctrl:	High pass filter control (enable / disable, cut off
+ *			frequency)
+ * @axis_x:		Sensor orientation remapping for x-axis
+ * @axis_y:		Sensor orientation remapping for y-axis
+ * @axis_z:		Sensor orientation remapping for z-axis
+ * @driver_features:	Enable bits for different features. Disabled by default
+ * @default_rate:	Default sampling rate. 0 means reset default
+ * @setup_resources:	Interrupt line setup call back function
+ * @release_resources:	Interrupt line release call back function
+ * @st_min_limits[3]:	Selftest acceptance minimum values
+ * @st_max_limits[3]:	Selftest acceptance maximum values
+ * @irq2:		Irq line 2 number
+ *
+ * Platform data is used to setup the sensor chip. Meaning of the different
+ * chip features can be found from the data sheet. It is publicly available
+ * at www.st.com web pages. Currently the platform data is used
+ * only for the 8 bit device. The 8 bit device has two wake up / free fall
+ * detection units and click detection unit. There are plenty of ways to
+ * configure the chip which makes is quite hard to explain deeper meaning of
+ * the fields here. Behaviour of the detection blocks varies heavily depending
+ * on the configuration. For example, interrupt detection block can use high
+ * pass filtered data which makes it react to the changes in the acceleration.
+ * Irq_flags can be used to enable interrupt detection on the both edges.
+ * With proper chip configuration this produces interrupt when some trigger
+ * starts and when it goes away.
+ */
+
 struct lis3lv02d_platform_data {
 	/* please note: the 'click' feature is only supported for
 	 * LIS[32]02DL variants of the chip and will be ignored for
-- 
1.6.0.4

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [lm-sensors] [PATCHv2] hwmon: lis3: Short explanations of platform
@ 2010-10-23 13:39         ` Samu Onkalo
  0 siblings, 0 replies; 101+ messages in thread
From: Samu Onkalo @ 2010-10-23 13:39 UTC (permalink / raw)
  To: eric.piel-VkQ1JFuSMpfAbQlEx87xDw,
	guenter.roeck-IzeFyvvaP7pWk0Htik3J/w,
	jic23-KWPb1pKIrIJaa/9Udqfwiw
  Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA, lm-sensors-GZX6beZjE8VD60Wz+7aTrA

Short documentation at kernel doc format.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
---
 include/linux/lis3lv02d.h |   46 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 46 insertions(+), 0 deletions(-)

diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
index c949612..d4292c8 100644
--- a/include/linux/lis3lv02d.h
+++ b/include/linux/lis3lv02d.h
@@ -1,6 +1,52 @@
 #ifndef __LIS3LV02D_H_
 #define __LIS3LV02D_H_
 
+/**
+ * struct lis3lv02d_platform_data - lis3 chip family platform data
+ * @click_flags:	Click detection unit configuration
+ * @click_thresh_x:	Click detection unit x axis threshold
+ * @click_thresh_y:	Click detection unit y axis threshold
+ * @click_thresh_z:	Click detection unit z axis threshold
+ * @click_time_limit:	Click detection unit time parameter
+ * @click_latency:	Click detection unit latency parameter
+ * @click_window:	Click detection unit window parameter
+ * @irq_cfg:		On chip irq source and type configuration (click /
+ *			data available / wake up, open drain, polarity)
+ * @irq_flags1:		Additional irq triggering flags for irq channel 0
+ * @irq_flags2:		Additional irq triggering flags for irq channel 1
+ * @duration1:		Wake up unit 1 duration parameter
+ * @duration2:		Wake up unit 2 duration parameter
+ * @wakeup_flags:	Wake up unit 1 flags
+ * @wakeup_thresh:	Wake up unit 1 threshold value
+ * @wakeup_flags2:	Wake up unit 2 flags
+ * @wakeup_thresh2:	Wake up unit 2 threshold value
+ * @hipass_ctrl:	High pass filter control (enable / disable, cut off
+ *			frequency)
+ * @axis_x:		Sensor orientation remapping for x-axis
+ * @axis_y:		Sensor orientation remapping for y-axis
+ * @axis_z:		Sensor orientation remapping for z-axis
+ * @driver_features:	Enable bits for different features. Disabled by default
+ * @default_rate:	Default sampling rate. 0 means reset default
+ * @setup_resources:	Interrupt line setup call back function
+ * @release_resources:	Interrupt line release call back function
+ * @st_min_limits[3]:	Selftest acceptance minimum values
+ * @st_max_limits[3]:	Selftest acceptance maximum values
+ * @irq2:		Irq line 2 number
+ *
+ * Platform data is used to setup the sensor chip. Meaning of the different
+ * chip features can be found from the data sheet. It is publicly available
+ * at www.st.com web pages. Currently the platform data is used
+ * only for the 8 bit device. The 8 bit device has two wake up / free fall
+ * detection units and click detection unit. There are plenty of ways to
+ * configure the chip which makes is quite hard to explain deeper meaning of
+ * the fields here. Behaviour of the detection blocks varies heavily depending
+ * on the configuration. For example, interrupt detection block can use high
+ * pass filtered data which makes it react to the changes in the acceleration.
+ * Irq_flags can be used to enable interrupt detection on the both edges.
+ * With proper chip configuration this produces interrupt when some trigger
+ * starts and when it goes away.
+ */
+
 struct lis3lv02d_platform_data {
 	/* please note: the 'click' feature is only supported for
 	 * LIS[32]02DL variants of the chip and will be ignored for
-- 
1.6.0.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [PATCH 01/12] hwmon: lis3: pm_runtime support
  2010-10-22 11:57   ` Samu Onkalo
  (?)
@ 2010-10-24 14:03     ` Éric Piel
  -1 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:03 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> Add pm_runtime support to lis3 core driver.
> Add pm_runtime support to lis3 i2c driver.
>
> spi and hp_accel drivers are not yet supported. Old always
> on functionality remains for those.
>
> For sysfs there is 5 second delay before turning off the
> chip to avoid long ramp up delay.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>

> ---
>   drivers/hwmon/lis3lv02d.c     |   60 +++++++++++++++++++++++++++++++++++++++++
>   drivers/hwmon/lis3lv02d.h     |    1 +
>   drivers/hwmon/lis3lv02d_i2c.c |   54 ++++++++++++++++++++++++++++---------
>   3 files changed, 102 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index fc591ae..412ddc3 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -34,6 +34,7 @@
>   #include<linux/freezer.h>
>   #include<linux/uaccess.h>
>   #include<linux/miscdevice.h>
> +#include<linux/pm_runtime.h>
>   #include<asm/atomic.h>
>   #include "lis3lv02d.h"
>
> @@ -43,6 +44,9 @@
>   #define MDPS_POLL_INTERVAL 50
>   #define MDPS_POLL_MIN	   0
>   #define MDPS_POLL_MAX	   2000
> +
> +#define LIS3_SYSFS_POWERDOWN_DELAY 5000 /* In milliseconds */
> +
>   /*
>    * The sensor can also generate interrupts (DRDY) but it's pretty pointless
>    * because they are generated even if the data do not change. So it's better
> @@ -262,6 +266,18 @@ static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev)
>   	mutex_unlock(&lis3_dev.mutex);
>   }
>
> +static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
> +{
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_get_sync(lis3_dev.pm_dev);
> +}
> +
> +static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
> +{
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_put(lis3_dev.pm_dev);
> +}
> +
>   static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
>   {
>   	if (!test_bit(0,&lis3_dev.misc_opened))
> @@ -356,6 +372,9 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
>   	if (test_and_set_bit(0,&lis3_dev.misc_opened))
>   		return -EBUSY; /* already open */
>
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_get_sync(lis3_dev.pm_dev);
> +
>   	atomic_set(&lis3_dev.count, 0);
>   	return 0;
>   }
> @@ -364,6 +383,8 @@ static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
>   {
>   	fasync_helper(-1, file, 0,&lis3_dev.async_queue);
>   	clear_bit(0,&lis3_dev.misc_opened); /* release the device */
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_put(lis3_dev.pm_dev);
>   	return 0;
>   }
>
> @@ -460,6 +481,8 @@ int lis3lv02d_joystick_enable(void)
>   		return -ENOMEM;
>
>   	lis3_dev.idev->poll = lis3lv02d_joystick_poll;
> +	lis3_dev.idev->open = lis3lv02d_joystick_open;
> +	lis3_dev.idev->close = lis3lv02d_joystick_close;
>   	lis3_dev.idev->poll_interval = MDPS_POLL_INTERVAL;
>   	lis3_dev.idev->poll_interval_min = MDPS_POLL_MIN;
>   	lis3_dev.idev->poll_interval_max = MDPS_POLL_MAX;
> @@ -512,12 +535,30 @@ void lis3lv02d_joystick_disable(void)
>   EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable);
>
>   /* Sysfs stuff */
> +static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3)
> +{
> +	/*
> +	 * SYSFS functions are fast visitors so put-call
> +	 * immediately after the get-call. However, keep
> +	 * chip running for a while and schedule delayed
> +	 * suspend. This way periodic sysfs calls doesn't
> +	 * suffer from relatively long power up time.
> +	 */
> +
> +	if (lis3->pm_dev) {
> +		pm_runtime_get_sync(lis3->pm_dev);
> +		pm_runtime_put_noidle(lis3->pm_dev);
> +		pm_schedule_suspend(lis3->pm_dev, LIS3_SYSFS_POWERDOWN_DELAY);
> +	}
> +}
> +
>   static ssize_t lis3lv02d_selftest_show(struct device *dev,
>   				struct device_attribute *attr, char *buf)
>   {
>   	int result;
>   	s16 values[3];
>
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>   	result = lis3lv02d_selftest(&lis3_dev, values);
>   	return sprintf(buf, "%s %d %d %d\n", result == 0 ? "OK" : "FAIL",
>   		values[0], values[1], values[2]);
> @@ -528,6 +569,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
>   {
>   	int x, y, z;
>
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>   	mutex_lock(&lis3_dev.mutex);
>   	lis3lv02d_get_xyz(&lis3_dev,&x,&y,&z);
>   	mutex_unlock(&lis3_dev.mutex);
> @@ -537,6 +579,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
>   static ssize_t lis3lv02d_rate_show(struct device *dev,
>   			struct device_attribute *attr, char *buf)
>   {
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>   	return sprintf(buf, "%d\n", lis3lv02d_get_odr());
>   }
>
> @@ -549,6 +592,7 @@ static ssize_t lis3lv02d_rate_set(struct device *dev,
>   	if (strict_strtoul(buf, 0,&rate))
>   		return -EINVAL;
>
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>   	if (lis3lv02d_set_odr(rate))
>   		return -EINVAL;
>
> @@ -585,6 +629,17 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
>   {
>   	sysfs_remove_group(&lis3->pdev->dev.kobj,&lis3lv02d_attribute_group);
>   	platform_device_unregister(lis3->pdev);
> +	if (lis3->pm_dev) {
> +		/* Barrier after the sysfs remove */
> +		pm_runtime_barrier(lis3->pm_dev);
> +
> +		/* SYSFS may have left chip running. Turn off if necessary */
> +		if (!pm_runtime_suspended(lis3->pm_dev))
> +			lis3lv02d_poweroff(&lis3_dev);
> +
> +		pm_runtime_disable(lis3->pm_dev);
> +		pm_runtime_set_suspended(lis3->pm_dev);
> +	}
>   	return 0;
>   }
>   EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
> @@ -685,6 +740,11 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   	lis3lv02d_add_fs(dev);
>   	lis3lv02d_poweron(dev);
>
> +	if (dev->pm_dev) {
> +		pm_runtime_set_active(dev->pm_dev);
> +		pm_runtime_enable(dev->pm_dev);
> +	}
> +
>   	if (lis3lv02d_joystick_enable())
>   		printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
>
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 8540913..3e8a208 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -214,6 +214,7 @@ struct axis_conversion {
>
>   struct lis3lv02d {
>   	void			*bus_priv; /* used by the bus layer only */
> +	struct device		*pm_dev; /* for pm_runtime purposes */
>   	int (*init) (struct lis3lv02d *lis3);
>   	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
>   	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
> diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
> index 8e5933b..6e965d7 100644
> --- a/drivers/hwmon/lis3lv02d_i2c.c
> +++ b/drivers/hwmon/lis3lv02d_i2c.c
> @@ -29,6 +29,7 @@
>   #include<linux/init.h>
>   #include<linux/err.h>
>   #include<linux/i2c.h>
> +#include<linux/pm_runtime.h>
>   #include "lis3lv02d.h"
>
>   #define DRV_NAME 	"lis3lv02d_i2c"
> @@ -95,6 +96,7 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>   	lis3_dev.write	  = lis3_i2c_write;
>   	lis3_dev.irq	  = client->irq;
>   	lis3_dev.ac	  = lis3lv02d_axis_map;
> +	lis3_dev.pm_dev	  =&client->dev;
>
>   	i2c_set_clientdata(client,&lis3_dev);
>   	ret = lis3lv02d_init_device(&lis3_dev);
> @@ -104,21 +106,20 @@ fail:
>
>   static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
>   {
> -	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>   	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
>
>   	if (pdata&&  pdata->release_resources)
>   		pdata->release_resources();
>
>   	lis3lv02d_joystick_disable();
> -	lis3lv02d_poweroff(lis3);
>
>   	return lis3lv02d_remove_fs(&lis3_dev);
>   }
>
>   #ifdef CONFIG_PM
> -static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
> +static int lis3lv02d_i2c_suspend(struct device *dev)
>   {
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
>   	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>
>   	if (!lis3->pdata || !lis3->pdata->wakeup_flags)
> @@ -126,18 +127,21 @@ static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
>   	return 0;
>   }
>
> -static int lis3lv02d_i2c_resume(struct i2c_client *client)
> +static int lis3lv02d_i2c_resume(struct device *dev)
>   {
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
>   	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>
> -	if (!lis3->pdata || !lis3->pdata->wakeup_flags)
> +	/*
> +	 * pm_runtime documentation says that devices should always
> +	 * be powered on at resume. Pm_runtime turns them off after system
> +	 * wide resume is complete.
> +	 */
> +	if (!lis3->pdata || !lis3->pdata->wakeup_flags ||
> +		pm_runtime_suspended(dev))
>   		lis3lv02d_poweron(lis3);
> -	return 0;
> -}
>
> -static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
> -{
> -	lis3lv02d_i2c_suspend(client, PMSG_SUSPEND);
> +	return 0;
>   }
>   #else
>   #define lis3lv02d_i2c_suspend	NULL
> @@ -145,6 +149,24 @@ static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
>   #define lis3lv02d_i2c_shutdown	NULL
>   #endif
>
> +static int lis3_i2c_runtime_suspend(struct device *dev)
> +{
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
> +	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
> +
> +	lis3lv02d_poweroff(lis3);
> +	return 0;
> +}
> +
> +static int lis3_i2c_runtime_resume(struct device *dev)
> +{
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
> +	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
> +
> +	lis3lv02d_poweron(lis3);
> +	return 0;
> +}
> +
>   static const struct i2c_device_id lis3lv02d_id[] = {
>   	{"lis3lv02d", 0 },
>   	{}
> @@ -152,14 +174,20 @@ static const struct i2c_device_id lis3lv02d_id[] = {
>
>   MODULE_DEVICE_TABLE(i2c, lis3lv02d_id);
>
> +static const struct dev_pm_ops lis3_pm_ops = {
> +	SET_SYSTEM_SLEEP_PM_OPS(lis3lv02d_i2c_suspend,
> +				lis3lv02d_i2c_resume)
> +	SET_RUNTIME_PM_OPS(lis3_i2c_runtime_suspend,
> +			   lis3_i2c_runtime_resume,
> +			   NULL)
> +};
> +
>   static struct i2c_driver lis3lv02d_i2c_driver = {
>   	.driver	 = {
>   		.name   = DRV_NAME,
>   		.owner  = THIS_MODULE,
> +		.pm     =&lis3_pm_ops,
>   	},
> -	.suspend = lis3lv02d_i2c_suspend,
> -	.shutdown = lis3lv02d_i2c_shutdown,
> -	.resume = lis3lv02d_i2c_resume,
>   	.probe	= lis3lv02d_i2c_probe,
>   	.remove	= __devexit_p(lis3lv02d_i2c_remove),
>   	.id_table = lis3lv02d_id,


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 01/12] hwmon: lis3: pm_runtime support
@ 2010-10-24 14:03     ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:03 UTC (permalink / raw)
  To: Samu Onkalo; +Cc: linux-kernel, lm-sensors, linux-i2c

Op 22-10-10 13:57, Samu Onkalo schreef:
> Add pm_runtime support to lis3 core driver.
> Add pm_runtime support to lis3 i2c driver.
>
> spi and hp_accel drivers are not yet supported. Old always
> on functionality remains for those.
>
> For sysfs there is 5 second delay before turning off the
> chip to avoid long ramp up delay.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>

> ---
>   drivers/hwmon/lis3lv02d.c     |   60 +++++++++++++++++++++++++++++++++++++++++
>   drivers/hwmon/lis3lv02d.h     |    1 +
>   drivers/hwmon/lis3lv02d_i2c.c |   54 ++++++++++++++++++++++++++++---------
>   3 files changed, 102 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index fc591ae..412ddc3 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -34,6 +34,7 @@
>   #include<linux/freezer.h>
>   #include<linux/uaccess.h>
>   #include<linux/miscdevice.h>
> +#include<linux/pm_runtime.h>
>   #include<asm/atomic.h>
>   #include "lis3lv02d.h"
>
> @@ -43,6 +44,9 @@
>   #define MDPS_POLL_INTERVAL 50
>   #define MDPS_POLL_MIN	   0
>   #define MDPS_POLL_MAX	   2000
> +
> +#define LIS3_SYSFS_POWERDOWN_DELAY 5000 /* In milliseconds */
> +
>   /*
>    * The sensor can also generate interrupts (DRDY) but it's pretty pointless
>    * because they are generated even if the data do not change. So it's better
> @@ -262,6 +266,18 @@ static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev)
>   	mutex_unlock(&lis3_dev.mutex);
>   }
>
> +static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
> +{
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_get_sync(lis3_dev.pm_dev);
> +}
> +
> +static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
> +{
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_put(lis3_dev.pm_dev);
> +}
> +
>   static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
>   {
>   	if (!test_bit(0,&lis3_dev.misc_opened))
> @@ -356,6 +372,9 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
>   	if (test_and_set_bit(0,&lis3_dev.misc_opened))
>   		return -EBUSY; /* already open */
>
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_get_sync(lis3_dev.pm_dev);
> +
>   	atomic_set(&lis3_dev.count, 0);
>   	return 0;
>   }
> @@ -364,6 +383,8 @@ static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
>   {
>   	fasync_helper(-1, file, 0,&lis3_dev.async_queue);
>   	clear_bit(0,&lis3_dev.misc_opened); /* release the device */
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_put(lis3_dev.pm_dev);
>   	return 0;
>   }
>
> @@ -460,6 +481,8 @@ int lis3lv02d_joystick_enable(void)
>   		return -ENOMEM;
>
>   	lis3_dev.idev->poll = lis3lv02d_joystick_poll;
> +	lis3_dev.idev->open = lis3lv02d_joystick_open;
> +	lis3_dev.idev->close = lis3lv02d_joystick_close;
>   	lis3_dev.idev->poll_interval = MDPS_POLL_INTERVAL;
>   	lis3_dev.idev->poll_interval_min = MDPS_POLL_MIN;
>   	lis3_dev.idev->poll_interval_max = MDPS_POLL_MAX;
> @@ -512,12 +535,30 @@ void lis3lv02d_joystick_disable(void)
>   EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable);
>
>   /* Sysfs stuff */
> +static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3)
> +{
> +	/*
> +	 * SYSFS functions are fast visitors so put-call
> +	 * immediately after the get-call. However, keep
> +	 * chip running for a while and schedule delayed
> +	 * suspend. This way periodic sysfs calls doesn't
> +	 * suffer from relatively long power up time.
> +	 */
> +
> +	if (lis3->pm_dev) {
> +		pm_runtime_get_sync(lis3->pm_dev);
> +		pm_runtime_put_noidle(lis3->pm_dev);
> +		pm_schedule_suspend(lis3->pm_dev, LIS3_SYSFS_POWERDOWN_DELAY);
> +	}
> +}
> +
>   static ssize_t lis3lv02d_selftest_show(struct device *dev,
>   				struct device_attribute *attr, char *buf)
>   {
>   	int result;
>   	s16 values[3];
>
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>   	result = lis3lv02d_selftest(&lis3_dev, values);
>   	return sprintf(buf, "%s %d %d %d\n", result == 0 ? "OK" : "FAIL",
>   		values[0], values[1], values[2]);
> @@ -528,6 +569,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
>   {
>   	int x, y, z;
>
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>   	mutex_lock(&lis3_dev.mutex);
>   	lis3lv02d_get_xyz(&lis3_dev,&x,&y,&z);
>   	mutex_unlock(&lis3_dev.mutex);
> @@ -537,6 +579,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
>   static ssize_t lis3lv02d_rate_show(struct device *dev,
>   			struct device_attribute *attr, char *buf)
>   {
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>   	return sprintf(buf, "%d\n", lis3lv02d_get_odr());
>   }
>
> @@ -549,6 +592,7 @@ static ssize_t lis3lv02d_rate_set(struct device *dev,
>   	if (strict_strtoul(buf, 0,&rate))
>   		return -EINVAL;
>
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>   	if (lis3lv02d_set_odr(rate))
>   		return -EINVAL;
>
> @@ -585,6 +629,17 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
>   {
>   	sysfs_remove_group(&lis3->pdev->dev.kobj,&lis3lv02d_attribute_group);
>   	platform_device_unregister(lis3->pdev);
> +	if (lis3->pm_dev) {
> +		/* Barrier after the sysfs remove */
> +		pm_runtime_barrier(lis3->pm_dev);
> +
> +		/* SYSFS may have left chip running. Turn off if necessary */
> +		if (!pm_runtime_suspended(lis3->pm_dev))
> +			lis3lv02d_poweroff(&lis3_dev);
> +
> +		pm_runtime_disable(lis3->pm_dev);
> +		pm_runtime_set_suspended(lis3->pm_dev);
> +	}
>   	return 0;
>   }
>   EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
> @@ -685,6 +740,11 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   	lis3lv02d_add_fs(dev);
>   	lis3lv02d_poweron(dev);
>
> +	if (dev->pm_dev) {
> +		pm_runtime_set_active(dev->pm_dev);
> +		pm_runtime_enable(dev->pm_dev);
> +	}
> +
>   	if (lis3lv02d_joystick_enable())
>   		printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
>
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 8540913..3e8a208 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -214,6 +214,7 @@ struct axis_conversion {
>
>   struct lis3lv02d {
>   	void			*bus_priv; /* used by the bus layer only */
> +	struct device		*pm_dev; /* for pm_runtime purposes */
>   	int (*init) (struct lis3lv02d *lis3);
>   	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
>   	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
> diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
> index 8e5933b..6e965d7 100644
> --- a/drivers/hwmon/lis3lv02d_i2c.c
> +++ b/drivers/hwmon/lis3lv02d_i2c.c
> @@ -29,6 +29,7 @@
>   #include<linux/init.h>
>   #include<linux/err.h>
>   #include<linux/i2c.h>
> +#include<linux/pm_runtime.h>
>   #include "lis3lv02d.h"
>
>   #define DRV_NAME 	"lis3lv02d_i2c"
> @@ -95,6 +96,7 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>   	lis3_dev.write	  = lis3_i2c_write;
>   	lis3_dev.irq	  = client->irq;
>   	lis3_dev.ac	  = lis3lv02d_axis_map;
> +	lis3_dev.pm_dev	  =&client->dev;
>
>   	i2c_set_clientdata(client,&lis3_dev);
>   	ret = lis3lv02d_init_device(&lis3_dev);
> @@ -104,21 +106,20 @@ fail:
>
>   static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
>   {
> -	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>   	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
>
>   	if (pdata&&  pdata->release_resources)
>   		pdata->release_resources();
>
>   	lis3lv02d_joystick_disable();
> -	lis3lv02d_poweroff(lis3);
>
>   	return lis3lv02d_remove_fs(&lis3_dev);
>   }
>
>   #ifdef CONFIG_PM
> -static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
> +static int lis3lv02d_i2c_suspend(struct device *dev)
>   {
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
>   	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>
>   	if (!lis3->pdata || !lis3->pdata->wakeup_flags)
> @@ -126,18 +127,21 @@ static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
>   	return 0;
>   }
>
> -static int lis3lv02d_i2c_resume(struct i2c_client *client)
> +static int lis3lv02d_i2c_resume(struct device *dev)
>   {
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
>   	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>
> -	if (!lis3->pdata || !lis3->pdata->wakeup_flags)
> +	/*
> +	 * pm_runtime documentation says that devices should always
> +	 * be powered on at resume. Pm_runtime turns them off after system
> +	 * wide resume is complete.
> +	 */
> +	if (!lis3->pdata || !lis3->pdata->wakeup_flags ||
> +		pm_runtime_suspended(dev))
>   		lis3lv02d_poweron(lis3);
> -	return 0;
> -}
>
> -static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
> -{
> -	lis3lv02d_i2c_suspend(client, PMSG_SUSPEND);
> +	return 0;
>   }
>   #else
>   #define lis3lv02d_i2c_suspend	NULL
> @@ -145,6 +149,24 @@ static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
>   #define lis3lv02d_i2c_shutdown	NULL
>   #endif
>
> +static int lis3_i2c_runtime_suspend(struct device *dev)
> +{
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
> +	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
> +
> +	lis3lv02d_poweroff(lis3);
> +	return 0;
> +}
> +
> +static int lis3_i2c_runtime_resume(struct device *dev)
> +{
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
> +	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
> +
> +	lis3lv02d_poweron(lis3);
> +	return 0;
> +}
> +
>   static const struct i2c_device_id lis3lv02d_id[] = {
>   	{"lis3lv02d", 0 },
>   	{}
> @@ -152,14 +174,20 @@ static const struct i2c_device_id lis3lv02d_id[] = {
>
>   MODULE_DEVICE_TABLE(i2c, lis3lv02d_id);
>
> +static const struct dev_pm_ops lis3_pm_ops = {
> +	SET_SYSTEM_SLEEP_PM_OPS(lis3lv02d_i2c_suspend,
> +				lis3lv02d_i2c_resume)
> +	SET_RUNTIME_PM_OPS(lis3_i2c_runtime_suspend,
> +			   lis3_i2c_runtime_resume,
> +			   NULL)
> +};
> +
>   static struct i2c_driver lis3lv02d_i2c_driver = {
>   	.driver	 = {
>   		.name   = DRV_NAME,
>   		.owner  = THIS_MODULE,
> +		.pm     =&lis3_pm_ops,
>   	},
> -	.suspend = lis3lv02d_i2c_suspend,
> -	.shutdown = lis3lv02d_i2c_shutdown,
> -	.resume = lis3lv02d_i2c_resume,
>   	.probe	= lis3lv02d_i2c_probe,
>   	.remove	= __devexit_p(lis3lv02d_i2c_remove),
>   	.id_table = lis3lv02d_id,


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 01/12] hwmon: lis3: pm_runtime support
@ 2010-10-24 14:03     ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:03 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> Add pm_runtime support to lis3 core driver.
> Add pm_runtime support to lis3 i2c driver.
>
> spi and hp_accel drivers are not yet supported. Old always
> on functionality remains for those.
>
> For sysfs there is 5 second delay before turning off the
> chip to avoid long ramp up delay.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>

> ---
>   drivers/hwmon/lis3lv02d.c     |   60 +++++++++++++++++++++++++++++++++++++++++
>   drivers/hwmon/lis3lv02d.h     |    1 +
>   drivers/hwmon/lis3lv02d_i2c.c |   54 ++++++++++++++++++++++++++++---------
>   3 files changed, 102 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index fc591ae..412ddc3 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -34,6 +34,7 @@
>   #include<linux/freezer.h>
>   #include<linux/uaccess.h>
>   #include<linux/miscdevice.h>
> +#include<linux/pm_runtime.h>
>   #include<asm/atomic.h>
>   #include "lis3lv02d.h"
>
> @@ -43,6 +44,9 @@
>   #define MDPS_POLL_INTERVAL 50
>   #define MDPS_POLL_MIN	   0
>   #define MDPS_POLL_MAX	   2000
> +
> +#define LIS3_SYSFS_POWERDOWN_DELAY 5000 /* In milliseconds */
> +
>   /*
>    * The sensor can also generate interrupts (DRDY) but it's pretty pointless
>    * because they are generated even if the data do not change. So it's better
> @@ -262,6 +266,18 @@ static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev)
>   	mutex_unlock(&lis3_dev.mutex);
>   }
>
> +static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
> +{
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_get_sync(lis3_dev.pm_dev);
> +}
> +
> +static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
> +{
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_put(lis3_dev.pm_dev);
> +}
> +
>   static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
>   {
>   	if (!test_bit(0,&lis3_dev.misc_opened))
> @@ -356,6 +372,9 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
>   	if (test_and_set_bit(0,&lis3_dev.misc_opened))
>   		return -EBUSY; /* already open */
>
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_get_sync(lis3_dev.pm_dev);
> +
>   	atomic_set(&lis3_dev.count, 0);
>   	return 0;
>   }
> @@ -364,6 +383,8 @@ static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
>   {
>   	fasync_helper(-1, file, 0,&lis3_dev.async_queue);
>   	clear_bit(0,&lis3_dev.misc_opened); /* release the device */
> +	if (lis3_dev.pm_dev)
> +		pm_runtime_put(lis3_dev.pm_dev);
>   	return 0;
>   }
>
> @@ -460,6 +481,8 @@ int lis3lv02d_joystick_enable(void)
>   		return -ENOMEM;
>
>   	lis3_dev.idev->poll = lis3lv02d_joystick_poll;
> +	lis3_dev.idev->open = lis3lv02d_joystick_open;
> +	lis3_dev.idev->close = lis3lv02d_joystick_close;
>   	lis3_dev.idev->poll_interval = MDPS_POLL_INTERVAL;
>   	lis3_dev.idev->poll_interval_min = MDPS_POLL_MIN;
>   	lis3_dev.idev->poll_interval_max = MDPS_POLL_MAX;
> @@ -512,12 +535,30 @@ void lis3lv02d_joystick_disable(void)
>   EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable);
>
>   /* Sysfs stuff */
> +static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3)
> +{
> +	/*
> +	 * SYSFS functions are fast visitors so put-call
> +	 * immediately after the get-call. However, keep
> +	 * chip running for a while and schedule delayed
> +	 * suspend. This way periodic sysfs calls doesn't
> +	 * suffer from relatively long power up time.
> +	 */
> +
> +	if (lis3->pm_dev) {
> +		pm_runtime_get_sync(lis3->pm_dev);
> +		pm_runtime_put_noidle(lis3->pm_dev);
> +		pm_schedule_suspend(lis3->pm_dev, LIS3_SYSFS_POWERDOWN_DELAY);
> +	}
> +}
> +
>   static ssize_t lis3lv02d_selftest_show(struct device *dev,
>   				struct device_attribute *attr, char *buf)
>   {
>   	int result;
>   	s16 values[3];
>
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>   	result = lis3lv02d_selftest(&lis3_dev, values);
>   	return sprintf(buf, "%s %d %d %d\n", result = 0 ? "OK" : "FAIL",
>   		values[0], values[1], values[2]);
> @@ -528,6 +569,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
>   {
>   	int x, y, z;
>
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>   	mutex_lock(&lis3_dev.mutex);
>   	lis3lv02d_get_xyz(&lis3_dev,&x,&y,&z);
>   	mutex_unlock(&lis3_dev.mutex);
> @@ -537,6 +579,7 @@ static ssize_t lis3lv02d_position_show(struct device *dev,
>   static ssize_t lis3lv02d_rate_show(struct device *dev,
>   			struct device_attribute *attr, char *buf)
>   {
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>   	return sprintf(buf, "%d\n", lis3lv02d_get_odr());
>   }
>
> @@ -549,6 +592,7 @@ static ssize_t lis3lv02d_rate_set(struct device *dev,
>   	if (strict_strtoul(buf, 0,&rate))
>   		return -EINVAL;
>
> +	lis3lv02d_sysfs_poweron(&lis3_dev);
>   	if (lis3lv02d_set_odr(rate))
>   		return -EINVAL;
>
> @@ -585,6 +629,17 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
>   {
>   	sysfs_remove_group(&lis3->pdev->dev.kobj,&lis3lv02d_attribute_group);
>   	platform_device_unregister(lis3->pdev);
> +	if (lis3->pm_dev) {
> +		/* Barrier after the sysfs remove */
> +		pm_runtime_barrier(lis3->pm_dev);
> +
> +		/* SYSFS may have left chip running. Turn off if necessary */
> +		if (!pm_runtime_suspended(lis3->pm_dev))
> +			lis3lv02d_poweroff(&lis3_dev);
> +
> +		pm_runtime_disable(lis3->pm_dev);
> +		pm_runtime_set_suspended(lis3->pm_dev);
> +	}
>   	return 0;
>   }
>   EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
> @@ -685,6 +740,11 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   	lis3lv02d_add_fs(dev);
>   	lis3lv02d_poweron(dev);
>
> +	if (dev->pm_dev) {
> +		pm_runtime_set_active(dev->pm_dev);
> +		pm_runtime_enable(dev->pm_dev);
> +	}
> +
>   	if (lis3lv02d_joystick_enable())
>   		printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
>
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 8540913..3e8a208 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -214,6 +214,7 @@ struct axis_conversion {
>
>   struct lis3lv02d {
>   	void			*bus_priv; /* used by the bus layer only */
> +	struct device		*pm_dev; /* for pm_runtime purposes */
>   	int (*init) (struct lis3lv02d *lis3);
>   	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
>   	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
> diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
> index 8e5933b..6e965d7 100644
> --- a/drivers/hwmon/lis3lv02d_i2c.c
> +++ b/drivers/hwmon/lis3lv02d_i2c.c
> @@ -29,6 +29,7 @@
>   #include<linux/init.h>
>   #include<linux/err.h>
>   #include<linux/i2c.h>
> +#include<linux/pm_runtime.h>
>   #include "lis3lv02d.h"
>
>   #define DRV_NAME 	"lis3lv02d_i2c"
> @@ -95,6 +96,7 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>   	lis3_dev.write	  = lis3_i2c_write;
>   	lis3_dev.irq	  = client->irq;
>   	lis3_dev.ac	  = lis3lv02d_axis_map;
> +	lis3_dev.pm_dev	  =&client->dev;
>
>   	i2c_set_clientdata(client,&lis3_dev);
>   	ret = lis3lv02d_init_device(&lis3_dev);
> @@ -104,21 +106,20 @@ fail:
>
>   static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
>   {
> -	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>   	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
>
>   	if (pdata&&  pdata->release_resources)
>   		pdata->release_resources();
>
>   	lis3lv02d_joystick_disable();
> -	lis3lv02d_poweroff(lis3);
>
>   	return lis3lv02d_remove_fs(&lis3_dev);
>   }
>
>   #ifdef CONFIG_PM
> -static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
> +static int lis3lv02d_i2c_suspend(struct device *dev)
>   {
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
>   	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>
>   	if (!lis3->pdata || !lis3->pdata->wakeup_flags)
> @@ -126,18 +127,21 @@ static int lis3lv02d_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
>   	return 0;
>   }
>
> -static int lis3lv02d_i2c_resume(struct i2c_client *client)
> +static int lis3lv02d_i2c_resume(struct device *dev)
>   {
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
>   	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>
> -	if (!lis3->pdata || !lis3->pdata->wakeup_flags)
> +	/*
> +	 * pm_runtime documentation says that devices should always
> +	 * be powered on at resume. Pm_runtime turns them off after system
> +	 * wide resume is complete.
> +	 */
> +	if (!lis3->pdata || !lis3->pdata->wakeup_flags ||
> +		pm_runtime_suspended(dev))
>   		lis3lv02d_poweron(lis3);
> -	return 0;
> -}
>
> -static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
> -{
> -	lis3lv02d_i2c_suspend(client, PMSG_SUSPEND);
> +	return 0;
>   }
>   #else
>   #define lis3lv02d_i2c_suspend	NULL
> @@ -145,6 +149,24 @@ static void lis3lv02d_i2c_shutdown(struct i2c_client *client)
>   #define lis3lv02d_i2c_shutdown	NULL
>   #endif
>
> +static int lis3_i2c_runtime_suspend(struct device *dev)
> +{
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
> +	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
> +
> +	lis3lv02d_poweroff(lis3);
> +	return 0;
> +}
> +
> +static int lis3_i2c_runtime_resume(struct device *dev)
> +{
> +	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
> +	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
> +
> +	lis3lv02d_poweron(lis3);
> +	return 0;
> +}
> +
>   static const struct i2c_device_id lis3lv02d_id[] = {
>   	{"lis3lv02d", 0 },
>   	{}
> @@ -152,14 +174,20 @@ static const struct i2c_device_id lis3lv02d_id[] = {
>
>   MODULE_DEVICE_TABLE(i2c, lis3lv02d_id);
>
> +static const struct dev_pm_ops lis3_pm_ops = {
> +	SET_SYSTEM_SLEEP_PM_OPS(lis3lv02d_i2c_suspend,
> +				lis3lv02d_i2c_resume)
> +	SET_RUNTIME_PM_OPS(lis3_i2c_runtime_suspend,
> +			   lis3_i2c_runtime_resume,
> +			   NULL)
> +};
> +
>   static struct i2c_driver lis3lv02d_i2c_driver = {
>   	.driver	 = {
>   		.name   = DRV_NAME,
>   		.owner  = THIS_MODULE,
> +		.pm     =&lis3_pm_ops,
>   	},
> -	.suspend = lis3lv02d_i2c_suspend,
> -	.shutdown = lis3lv02d_i2c_shutdown,
> -	.resume = lis3lv02d_i2c_resume,
>   	.probe	= lis3lv02d_i2c_probe,
>   	.remove	= __devexit_p(lis3lv02d_i2c_remove),
>   	.id_table = lis3lv02d_id,


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 03/12] hwmon: lis3: Cleanup interrupt handling
  2010-10-22 11:57   ` [lm-sensors] " Samu Onkalo
  (?)
@ 2010-10-24 14:18     ` Éric Piel
  -1 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:18 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> Irqcfg moved to chip data instead of platform data.
> This simplifies access in interrupt handler little bit.
>
> Input device open and close functions set status for
> interrupt threaded handler once.
>
> Unnecessary check for interrupt source removed since
> it is enough that active interrupt line indicates that
> there was an interrupt.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>
> ---
>   drivers/hwmon/lis3lv02d.c |   33 +++++++++++----------------------
>   drivers/hwmon/lis3lv02d.h |    2 ++
>   2 files changed, 13 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index ade6f3a..fe97390 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -309,10 +309,14 @@ static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
>   {
>   	if (lis3_dev.pm_dev)
>   		pm_runtime_get_sync(lis3_dev.pm_dev);
> +
> +	if (lis3_dev.pdata&&  lis3_dev.whoami == WAI_8B&&  lis3_dev.idev)
> +		atomic_set(&lis3_dev.wake_thread, 1);
>   }
>
>   static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
>   {
> +	atomic_set(&lis3_dev.wake_thread, 0);
>   	if (lis3_dev.pm_dev)
>   		pm_runtime_put(lis3_dev.pm_dev);
>   }
> @@ -332,8 +336,7 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
>   	wake_up_interruptible(&lis3_dev.misc_wait);
>   	kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN);
>   out:
> -	if (lis3_dev.pdata&&  lis3_dev.whoami == WAI_8B&&  lis3_dev.idev&&
> -	    lis3_dev.idev->input->users)
> +	if (atomic_read(&lis3_dev.wake_thread))
>   		return IRQ_WAKE_THREAD;
>   	return IRQ_HANDLED;
>   }
> @@ -364,31 +367,15 @@ static void lis302dl_interrupt_handle_click(struct lis3lv02d *lis3)
>   	mutex_unlock(&lis3->mutex);
>   }
>
> -static void lis302dl_interrupt_handle_ff_wu(struct lis3lv02d *lis3)
> -{
> -	u8 wu1_src;
> -	u8 wu2_src;
> -
> -	lis3->read(lis3, FF_WU_SRC_1,&wu1_src);
> -	lis3->read(lis3, FF_WU_SRC_2,&wu2_src);
> -
> -	wu1_src = wu1_src&  FF_WU_SRC_IA ? wu1_src : 0;
> -	wu2_src = wu2_src&  FF_WU_SRC_IA ? wu2_src : 0;
> -
> -	/* joystick poll is internally protected by the lis3->mutex. */
> -	if (wu1_src || wu2_src)
> -		lis3lv02d_joystick_poll(lis3_dev.idev);
> -}
> -
>   static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
>   {
>
>   	struct lis3lv02d *lis3 = data;
>
> -	if ((lis3->pdata->irq_cfg&  LIS3_IRQ1_MASK) == LIS3_IRQ1_CLICK)
> +	if ((lis3->irq_cfg&  LIS3_IRQ1_MASK) == LIS3_IRQ1_CLICK)
>   		lis302dl_interrupt_handle_click(lis3);
>   	else
> -		lis302dl_interrupt_handle_ff_wu(lis3);
> +		lis3lv02d_joystick_poll(lis3->idev);
>
>   	return IRQ_HANDLED;
>   }
> @@ -398,10 +385,10 @@ static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data)
>
>   	struct lis3lv02d *lis3 = data;
>
> -	if ((lis3->pdata->irq_cfg&  LIS3_IRQ2_MASK) == LIS3_IRQ2_CLICK)
> +	if ((lis3->irq_cfg&  LIS3_IRQ2_MASK) == LIS3_IRQ2_CLICK)
>   		lis302dl_interrupt_handle_click(lis3);
>   	else
> -		lis302dl_interrupt_handle_ff_wu(lis3);
> +		lis3lv02d_joystick_poll(lis3->idev);
>
>   	return IRQ_HANDLED;
>   }
> @@ -788,6 +775,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   	}
>
>   	mutex_init(&dev->mutex);
> +	atomic_set(&dev->wake_thread, 0);
>
>   	lis3lv02d_add_fs(dev);
>   	lis3lv02d_poweron(dev);
> @@ -808,6 +796,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   		if (dev->whoami == WAI_8B)
>   			lis3lv02d_8b_configure(dev, p);
>
> +		dev->irq_cfg = p->irq_cfg;
>   		if (p->irq_cfg)
>   			dev->write(dev, CTRL_REG3, p->irq_cfg);
>   	}
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 7661e59..66e37b1 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -252,6 +252,8 @@ struct lis3lv02d {
>   	struct fasync_struct	*async_queue; /* queue for the misc device */
>   	wait_queue_head_t	misc_wait; /* Wait queue for the misc device */
>   	unsigned long		misc_opened; /* bit0: whether the device is open */
> +	atomic_t                wake_thread;
> +	unsigned char           irq_cfg;
>
>   	struct lis3lv02d_platform_data *pdata;	/* for passing board config */
>   	struct mutex		mutex;     /* Serialize poll and selftest */


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 03/12] hwmon: lis3: Cleanup interrupt handling
@ 2010-10-24 14:18     ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:18 UTC (permalink / raw)
  To: Samu Onkalo; +Cc: linux-kernel, lm-sensors, linux-i2c

Op 22-10-10 13:57, Samu Onkalo schreef:
> Irqcfg moved to chip data instead of platform data.
> This simplifies access in interrupt handler little bit.
>
> Input device open and close functions set status for
> interrupt threaded handler once.
>
> Unnecessary check for interrupt source removed since
> it is enough that active interrupt line indicates that
> there was an interrupt.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>
> ---
>   drivers/hwmon/lis3lv02d.c |   33 +++++++++++----------------------
>   drivers/hwmon/lis3lv02d.h |    2 ++
>   2 files changed, 13 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index ade6f3a..fe97390 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -309,10 +309,14 @@ static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
>   {
>   	if (lis3_dev.pm_dev)
>   		pm_runtime_get_sync(lis3_dev.pm_dev);
> +
> +	if (lis3_dev.pdata&&  lis3_dev.whoami == WAI_8B&&  lis3_dev.idev)
> +		atomic_set(&lis3_dev.wake_thread, 1);
>   }
>
>   static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
>   {
> +	atomic_set(&lis3_dev.wake_thread, 0);
>   	if (lis3_dev.pm_dev)
>   		pm_runtime_put(lis3_dev.pm_dev);
>   }
> @@ -332,8 +336,7 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
>   	wake_up_interruptible(&lis3_dev.misc_wait);
>   	kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN);
>   out:
> -	if (lis3_dev.pdata&&  lis3_dev.whoami == WAI_8B&&  lis3_dev.idev&&
> -	    lis3_dev.idev->input->users)
> +	if (atomic_read(&lis3_dev.wake_thread))
>   		return IRQ_WAKE_THREAD;
>   	return IRQ_HANDLED;
>   }
> @@ -364,31 +367,15 @@ static void lis302dl_interrupt_handle_click(struct lis3lv02d *lis3)
>   	mutex_unlock(&lis3->mutex);
>   }
>
> -static void lis302dl_interrupt_handle_ff_wu(struct lis3lv02d *lis3)
> -{
> -	u8 wu1_src;
> -	u8 wu2_src;
> -
> -	lis3->read(lis3, FF_WU_SRC_1,&wu1_src);
> -	lis3->read(lis3, FF_WU_SRC_2,&wu2_src);
> -
> -	wu1_src = wu1_src&  FF_WU_SRC_IA ? wu1_src : 0;
> -	wu2_src = wu2_src&  FF_WU_SRC_IA ? wu2_src : 0;
> -
> -	/* joystick poll is internally protected by the lis3->mutex. */
> -	if (wu1_src || wu2_src)
> -		lis3lv02d_joystick_poll(lis3_dev.idev);
> -}
> -
>   static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
>   {
>
>   	struct lis3lv02d *lis3 = data;
>
> -	if ((lis3->pdata->irq_cfg&  LIS3_IRQ1_MASK) == LIS3_IRQ1_CLICK)
> +	if ((lis3->irq_cfg&  LIS3_IRQ1_MASK) == LIS3_IRQ1_CLICK)
>   		lis302dl_interrupt_handle_click(lis3);
>   	else
> -		lis302dl_interrupt_handle_ff_wu(lis3);
> +		lis3lv02d_joystick_poll(lis3->idev);
>
>   	return IRQ_HANDLED;
>   }
> @@ -398,10 +385,10 @@ static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data)
>
>   	struct lis3lv02d *lis3 = data;
>
> -	if ((lis3->pdata->irq_cfg&  LIS3_IRQ2_MASK) == LIS3_IRQ2_CLICK)
> +	if ((lis3->irq_cfg&  LIS3_IRQ2_MASK) == LIS3_IRQ2_CLICK)
>   		lis302dl_interrupt_handle_click(lis3);
>   	else
> -		lis302dl_interrupt_handle_ff_wu(lis3);
> +		lis3lv02d_joystick_poll(lis3->idev);
>
>   	return IRQ_HANDLED;
>   }
> @@ -788,6 +775,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   	}
>
>   	mutex_init(&dev->mutex);
> +	atomic_set(&dev->wake_thread, 0);
>
>   	lis3lv02d_add_fs(dev);
>   	lis3lv02d_poweron(dev);
> @@ -808,6 +796,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   		if (dev->whoami == WAI_8B)
>   			lis3lv02d_8b_configure(dev, p);
>
> +		dev->irq_cfg = p->irq_cfg;
>   		if (p->irq_cfg)
>   			dev->write(dev, CTRL_REG3, p->irq_cfg);
>   	}
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 7661e59..66e37b1 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -252,6 +252,8 @@ struct lis3lv02d {
>   	struct fasync_struct	*async_queue; /* queue for the misc device */
>   	wait_queue_head_t	misc_wait; /* Wait queue for the misc device */
>   	unsigned long		misc_opened; /* bit0: whether the device is open */
> +	atomic_t                wake_thread;
> +	unsigned char           irq_cfg;
>
>   	struct lis3lv02d_platform_data *pdata;	/* for passing board config */
>   	struct mutex		mutex;     /* Serialize poll and selftest */


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 03/12] hwmon: lis3: Cleanup interrupt
@ 2010-10-24 14:18     ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:18 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> Irqcfg moved to chip data instead of platform data.
> This simplifies access in interrupt handler little bit.
>
> Input device open and close functions set status for
> interrupt threaded handler once.
>
> Unnecessary check for interrupt source removed since
> it is enough that active interrupt line indicates that
> there was an interrupt.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>
> ---
>   drivers/hwmon/lis3lv02d.c |   33 +++++++++++----------------------
>   drivers/hwmon/lis3lv02d.h |    2 ++
>   2 files changed, 13 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index ade6f3a..fe97390 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -309,10 +309,14 @@ static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
>   {
>   	if (lis3_dev.pm_dev)
>   		pm_runtime_get_sync(lis3_dev.pm_dev);
> +
> +	if (lis3_dev.pdata&&  lis3_dev.whoami = WAI_8B&&  lis3_dev.idev)
> +		atomic_set(&lis3_dev.wake_thread, 1);
>   }
>
>   static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)
>   {
> +	atomic_set(&lis3_dev.wake_thread, 0);
>   	if (lis3_dev.pm_dev)
>   		pm_runtime_put(lis3_dev.pm_dev);
>   }
> @@ -332,8 +336,7 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
>   	wake_up_interruptible(&lis3_dev.misc_wait);
>   	kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN);
>   out:
> -	if (lis3_dev.pdata&&  lis3_dev.whoami = WAI_8B&&  lis3_dev.idev&&
> -	    lis3_dev.idev->input->users)
> +	if (atomic_read(&lis3_dev.wake_thread))
>   		return IRQ_WAKE_THREAD;
>   	return IRQ_HANDLED;
>   }
> @@ -364,31 +367,15 @@ static void lis302dl_interrupt_handle_click(struct lis3lv02d *lis3)
>   	mutex_unlock(&lis3->mutex);
>   }
>
> -static void lis302dl_interrupt_handle_ff_wu(struct lis3lv02d *lis3)
> -{
> -	u8 wu1_src;
> -	u8 wu2_src;
> -
> -	lis3->read(lis3, FF_WU_SRC_1,&wu1_src);
> -	lis3->read(lis3, FF_WU_SRC_2,&wu2_src);
> -
> -	wu1_src = wu1_src&  FF_WU_SRC_IA ? wu1_src : 0;
> -	wu2_src = wu2_src&  FF_WU_SRC_IA ? wu2_src : 0;
> -
> -	/* joystick poll is internally protected by the lis3->mutex. */
> -	if (wu1_src || wu2_src)
> -		lis3lv02d_joystick_poll(lis3_dev.idev);
> -}
> -
>   static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
>   {
>
>   	struct lis3lv02d *lis3 = data;
>
> -	if ((lis3->pdata->irq_cfg&  LIS3_IRQ1_MASK) = LIS3_IRQ1_CLICK)
> +	if ((lis3->irq_cfg&  LIS3_IRQ1_MASK) = LIS3_IRQ1_CLICK)
>   		lis302dl_interrupt_handle_click(lis3);
>   	else
> -		lis302dl_interrupt_handle_ff_wu(lis3);
> +		lis3lv02d_joystick_poll(lis3->idev);
>
>   	return IRQ_HANDLED;
>   }
> @@ -398,10 +385,10 @@ static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data)
>
>   	struct lis3lv02d *lis3 = data;
>
> -	if ((lis3->pdata->irq_cfg&  LIS3_IRQ2_MASK) = LIS3_IRQ2_CLICK)
> +	if ((lis3->irq_cfg&  LIS3_IRQ2_MASK) = LIS3_IRQ2_CLICK)
>   		lis302dl_interrupt_handle_click(lis3);
>   	else
> -		lis302dl_interrupt_handle_ff_wu(lis3);
> +		lis3lv02d_joystick_poll(lis3->idev);
>
>   	return IRQ_HANDLED;
>   }
> @@ -788,6 +775,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   	}
>
>   	mutex_init(&dev->mutex);
> +	atomic_set(&dev->wake_thread, 0);
>
>   	lis3lv02d_add_fs(dev);
>   	lis3lv02d_poweron(dev);
> @@ -808,6 +796,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   		if (dev->whoami = WAI_8B)
>   			lis3lv02d_8b_configure(dev, p);
>
> +		dev->irq_cfg = p->irq_cfg;
>   		if (p->irq_cfg)
>   			dev->write(dev, CTRL_REG3, p->irq_cfg);
>   	}
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 7661e59..66e37b1 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -252,6 +252,8 @@ struct lis3lv02d {
>   	struct fasync_struct	*async_queue; /* queue for the misc device */
>   	wait_queue_head_t	misc_wait; /* Wait queue for the misc device */
>   	unsigned long		misc_opened; /* bit0: whether the device is open */
> +	atomic_t                wake_thread;
> +	unsigned char           irq_cfg;
>
>   	struct lis3lv02d_platform_data *pdata;	/* for passing board config */
>   	struct mutex		mutex;     /* Serialize poll and selftest */


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 04/12] hwmon: lis3: Update coordinates at polled device open
  2010-10-22 11:57   ` [lm-sensors] [PATCH 04/12] hwmon: lis3: Update coordinates at Samu Onkalo
@ 2010-10-24 14:19     ` Éric Piel
  -1 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:19 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> Call input device poll function at device open to refresh coordinates
> immediately. This is needed for the case where poll interval is set to
> zero and coordinate updates happens purely under interrupt control.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>
> ---
>   drivers/hwmon/lis3lv02d.c |    5 +++++
>   1 files changed, 5 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index fe97390..e2e0bb4 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -312,6 +312,11 @@ static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
>
>   	if (lis3_dev.pdata&&  lis3_dev.whoami == WAI_8B&&  lis3_dev.idev)
>   		atomic_set(&lis3_dev.wake_thread, 1);
> +	/*
> +	 * Update coordinates for the case where poll interval is 0 and
> +	 * the chip in running purely under interrupt control
> +	 */
> +	lis3lv02d_joystick_poll(pidev);
>   }
>
>   static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 04/12] hwmon: lis3: Update coordinates at
@ 2010-10-24 14:19     ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:19 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> Call input device poll function at device open to refresh coordinates
> immediately. This is needed for the case where poll interval is set to
> zero and coordinate updates happens purely under interrupt control.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>
> ---
>   drivers/hwmon/lis3lv02d.c |    5 +++++
>   1 files changed, 5 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index fe97390..e2e0bb4 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -312,6 +312,11 @@ static void lis3lv02d_joystick_open(struct input_polled_dev *pidev)
>
>   	if (lis3_dev.pdata&&  lis3_dev.whoami = WAI_8B&&  lis3_dev.idev)
>   		atomic_set(&lis3_dev.wake_thread, 1);
> +	/*
> +	 * Update coordinates for the case where poll interval is 0 and
> +	 * the chip in running purely under interrupt control
> +	 */
> +	lis3lv02d_joystick_poll(pidev);
>   }
>
>   static void lis3lv02d_joystick_close(struct input_polled_dev *pidev)


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 05/12] hwmon: lis3: Power on corrections
  2010-10-22 11:57   ` Samu Onkalo
  (?)
@ 2010-10-24 14:22     ` Éric Piel
  -1 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:22 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> Sometimes lis3 chip seems to fail to setup factory tuning at boot up.
> This probably happens if there is some odd power ramp down ramp up sequence
> for example in device restart. Set boot bit in control2 register to
> trig boot sequence manually and wait until it is finished.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
> Acked-by: Jonathan Cameron<jic23@cam.ac.uk>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>
> ---
>   drivers/hwmon/lis3lv02d.c |   19 +++++++++++--------
>   drivers/hwmon/lis3lv02d.h |    1 +
>   2 files changed, 12 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index e2e0bb4..b44d4c5 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -273,19 +273,22 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3)
>
>   	lis3->init(lis3);
>
> -	/* LIS3 power on delay is quite long */
> -	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
> -
>   	/*
>   	 * Common configuration
>   	 * BDU: (12 bits sensors only) LSB and MSB values are not updated until
>   	 *      both have been read. So the value read will always be correct.
> +	 * Set BOOT bit to refresh factory tuning values.
>   	 */
> -	if (lis3->whoami ==  WAI_12B) {
> -		lis3->read(lis3, CTRL_REG2,&reg);
> -		reg |= CTRL2_BDU;
> -		lis3->write(lis3, CTRL_REG2, reg);
> -	}
> +	lis3->read(lis3, CTRL_REG2,&reg);
> +	if (lis3->whoami ==  WAI_12B)
> +		reg |= CTRL2_BDU | CTRL2_BOOT;
> +	else
> +		reg |= CTRL2_BOOT_8B;
> +	lis3->write(lis3, CTRL_REG2, reg);
> +
> +	/* LIS3 power on delay is quite long */
> +	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
> +
>   	if (lis3->reg_ctrl)
>   		lis3_context_restore(lis3);
>   }
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 66e37b1..2ac27b9 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -133,6 +133,7 @@ enum lis3lv02d_ctrl2 {
>   enum lis302d_ctrl2 {
>   	HP_FF_WU2	= 0x08,
>   	HP_FF_WU1	= 0x04,
> +	CTRL2_BOOT_8B   = 0x40,
>   };
>
>   enum lis3lv02d_ctrl3 {


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 05/12] hwmon: lis3: Power on corrections
@ 2010-10-24 14:22     ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:22 UTC (permalink / raw)
  To: Samu Onkalo; +Cc: linux-kernel, lm-sensors, linux-i2c

Op 22-10-10 13:57, Samu Onkalo schreef:
> Sometimes lis3 chip seems to fail to setup factory tuning at boot up.
> This probably happens if there is some odd power ramp down ramp up sequence
> for example in device restart. Set boot bit in control2 register to
> trig boot sequence manually and wait until it is finished.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
> Acked-by: Jonathan Cameron<jic23@cam.ac.uk>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>
> ---
>   drivers/hwmon/lis3lv02d.c |   19 +++++++++++--------
>   drivers/hwmon/lis3lv02d.h |    1 +
>   2 files changed, 12 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index e2e0bb4..b44d4c5 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -273,19 +273,22 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3)
>
>   	lis3->init(lis3);
>
> -	/* LIS3 power on delay is quite long */
> -	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
> -
>   	/*
>   	 * Common configuration
>   	 * BDU: (12 bits sensors only) LSB and MSB values are not updated until
>   	 *      both have been read. So the value read will always be correct.
> +	 * Set BOOT bit to refresh factory tuning values.
>   	 */
> -	if (lis3->whoami ==  WAI_12B) {
> -		lis3->read(lis3, CTRL_REG2,&reg);
> -		reg |= CTRL2_BDU;
> -		lis3->write(lis3, CTRL_REG2, reg);
> -	}
> +	lis3->read(lis3, CTRL_REG2,&reg);
> +	if (lis3->whoami ==  WAI_12B)
> +		reg |= CTRL2_BDU | CTRL2_BOOT;
> +	else
> +		reg |= CTRL2_BOOT_8B;
> +	lis3->write(lis3, CTRL_REG2, reg);
> +
> +	/* LIS3 power on delay is quite long */
> +	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
> +
>   	if (lis3->reg_ctrl)
>   		lis3_context_restore(lis3);
>   }
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 66e37b1..2ac27b9 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -133,6 +133,7 @@ enum lis3lv02d_ctrl2 {
>   enum lis302d_ctrl2 {
>   	HP_FF_WU2	= 0x08,
>   	HP_FF_WU1	= 0x04,
> +	CTRL2_BOOT_8B   = 0x40,
>   };
>
>   enum lis3lv02d_ctrl3 {


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 05/12] hwmon: lis3: Power on corrections
@ 2010-10-24 14:22     ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:22 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> Sometimes lis3 chip seems to fail to setup factory tuning at boot up.
> This probably happens if there is some odd power ramp down ramp up sequence
> for example in device restart. Set boot bit in control2 register to
> trig boot sequence manually and wait until it is finished.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
> Acked-by: Jonathan Cameron<jic23@cam.ac.uk>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>
> ---
>   drivers/hwmon/lis3lv02d.c |   19 +++++++++++--------
>   drivers/hwmon/lis3lv02d.h |    1 +
>   2 files changed, 12 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index e2e0bb4..b44d4c5 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -273,19 +273,22 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3)
>
>   	lis3->init(lis3);
>
> -	/* LIS3 power on delay is quite long */
> -	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
> -
>   	/*
>   	 * Common configuration
>   	 * BDU: (12 bits sensors only) LSB and MSB values are not updated until
>   	 *      both have been read. So the value read will always be correct.
> +	 * Set BOOT bit to refresh factory tuning values.
>   	 */
> -	if (lis3->whoami =  WAI_12B) {
> -		lis3->read(lis3, CTRL_REG2,&reg);
> -		reg |= CTRL2_BDU;
> -		lis3->write(lis3, CTRL_REG2, reg);
> -	}
> +	lis3->read(lis3, CTRL_REG2,&reg);
> +	if (lis3->whoami =  WAI_12B)
> +		reg |= CTRL2_BDU | CTRL2_BOOT;
> +	else
> +		reg |= CTRL2_BOOT_8B;
> +	lis3->write(lis3, CTRL_REG2, reg);
> +
> +	/* LIS3 power on delay is quite long */
> +	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
> +
>   	if (lis3->reg_ctrl)
>   		lis3_context_restore(lis3);
>   }
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 66e37b1..2ac27b9 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -133,6 +133,7 @@ enum lis3lv02d_ctrl2 {
>   enum lis302d_ctrl2 {
>   	HP_FF_WU2	= 0x08,
>   	HP_FF_WU1	= 0x04,
> +	CTRL2_BOOT_8B   = 0x40,
>   };
>
>   enum lis3lv02d_ctrl3 {


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 06/12] hwmon: lis3: restore axis enabled bits
  2010-10-22 11:57   ` Samu Onkalo
@ 2010-10-24 14:24     ` Éric Piel
  -1 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:24 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> All axis enable bits are set to 0 at module remove.
> Restore reset default value at init.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>
> ---
>   drivers/hwmon/lis3lv02d_i2c.c |    2 +-
>   drivers/hwmon/lis3lv02d_spi.c |    2 +-
>   2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
> index 98983cc..36171bf 100644
> --- a/drivers/hwmon/lis3lv02d_i2c.c
> +++ b/drivers/hwmon/lis3lv02d_i2c.c
> @@ -83,7 +83,7 @@ static int lis3_i2c_init(struct lis3lv02d *lis3)
>   	if (ret<  0)
>   		return ret;
>
> -	reg |= CTRL1_PD0;
> +	reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen;
>   	return lis3->write(lis3, CTRL_REG1, reg);
>   }
>
> diff --git a/drivers/hwmon/lis3lv02d_spi.c b/drivers/hwmon/lis3lv02d_spi.c
> index b9be5e3..778885d 100644
> --- a/drivers/hwmon/lis3lv02d_spi.c
> +++ b/drivers/hwmon/lis3lv02d_spi.c
> @@ -50,7 +50,7 @@ static int lis3_spi_init(struct lis3lv02d *lis3)
>   	if (ret<  0)
>   		return ret;
>
> -	reg |= CTRL1_PD0;
> +	reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen;
>   	return lis3->write(lis3, CTRL_REG1, reg);
>   }
>


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 06/12] hwmon: lis3: restore axis enabled
@ 2010-10-24 14:24     ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:24 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> All axis enable bits are set to 0 at module remove.
> Restore reset default value at init.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>
> ---
>   drivers/hwmon/lis3lv02d_i2c.c |    2 +-
>   drivers/hwmon/lis3lv02d_spi.c |    2 +-
>   2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
> index 98983cc..36171bf 100644
> --- a/drivers/hwmon/lis3lv02d_i2c.c
> +++ b/drivers/hwmon/lis3lv02d_i2c.c
> @@ -83,7 +83,7 @@ static int lis3_i2c_init(struct lis3lv02d *lis3)
>   	if (ret<  0)
>   		return ret;
>
> -	reg |= CTRL1_PD0;
> +	reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen;
>   	return lis3->write(lis3, CTRL_REG1, reg);
>   }
>
> diff --git a/drivers/hwmon/lis3lv02d_spi.c b/drivers/hwmon/lis3lv02d_spi.c
> index b9be5e3..778885d 100644
> --- a/drivers/hwmon/lis3lv02d_spi.c
> +++ b/drivers/hwmon/lis3lv02d_spi.c
> @@ -50,7 +50,7 @@ static int lis3_spi_init(struct lis3lv02d *lis3)
>   	if (ret<  0)
>   		return ret;
>
> -	reg |= CTRL1_PD0;
> +	reg |= CTRL1_PD0 | CTRL1_Xen | CTRL1_Yen | CTRL1_Zen;
>   	return lis3->write(lis3, CTRL_REG1, reg);
>   }
>


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 07/12] hwmon: lis3: New parameters to platform data
  2010-10-22 11:57   ` [lm-sensors] [PATCH 07/12] hwmon: lis3: New parameters to platform Samu Onkalo
  (?)
@ 2010-10-24 14:27     ` Éric Piel
  -1 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:27 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> Added default output data rate setting to platform data.
> If default rate is 0, reset default value is used.
> Added control for duration via platform data.
> Added possibility to configure interrupts to trig on
> both rising and falling edge. The lis3 WU unit can be
> configured quite many ways and with some configurations it
> is quite handy to get coordinate refresh when some
> event trigs and when it reason goes away.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>

> ---
>   drivers/hwmon/lis3lv02d.c |   21 ++++++++++++++-------
>   include/linux/lis3lv02d.h |    6 +++++-
>   2 files changed, 19 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index b44d4c5..d66cbe1 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -706,16 +706,16 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
>   	if (p->wakeup_flags) {
>   		dev->write(dev, FF_WU_CFG_1, p->wakeup_flags);
>   		dev->write(dev, FF_WU_THS_1, p->wakeup_thresh&  0x7f);
> -		/* default to 2.5ms for now */
> -		dev->write(dev, FF_WU_DURATION_1, 1);
> +		/* pdata value + 1 to keep this backward compatible*/
> +		dev->write(dev, FF_WU_DURATION_1, p->duration1 + 1);
>   		ctrl2 ^= HP_FF_WU1; /* Xor to keep compatible with old pdata*/
>   	}
>
>   	if (p->wakeup_flags2) {
>   		dev->write(dev, FF_WU_CFG_2, p->wakeup_flags2);
>   		dev->write(dev, FF_WU_THS_2, p->wakeup_thresh2&  0x7f);
> -		/* default to 2.5ms for now */
> -		dev->write(dev, FF_WU_DURATION_2, 1);
> +		/* pdata value + 1 to keep this backward compatible*/
> +		dev->write(dev, FF_WU_DURATION_2, p->duration2 + 1);
>   		ctrl2 ^= HP_FF_WU2; /* Xor to keep compatible with old pdata*/
>   	}
>   	/* Configure hipass filters */
> @@ -725,8 +725,8 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
>   		err = request_threaded_irq(p->irq2,
>   					NULL,
>   					lis302dl_interrupt_thread2_8b,
> -					IRQF_TRIGGER_RISING |
> -					IRQF_ONESHOT,
> +					IRQF_TRIGGER_RISING | IRQF_ONESHOT |
> +					(p->irq_flags2&  IRQF_TRIGGER_MASK),
>   					DRIVER_NAME,&lis3_dev);
>   		if (err<  0)
>   			printk(KERN_ERR DRIVER_NAME
> @@ -742,6 +742,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   {
>   	int err;
>   	irq_handler_t thread_fn;
> +	int irq_flags = 0;
>
>   	dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I);
>
> @@ -804,9 +805,14 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   		if (dev->whoami == WAI_8B)
>   			lis3lv02d_8b_configure(dev, p);
>
> +		irq_flags = p->irq_flags1&  IRQF_TRIGGER_MASK;
> +
>   		dev->irq_cfg = p->irq_cfg;
>   		if (p->irq_cfg)
>   			dev->write(dev, CTRL_REG3, p->irq_cfg);
> +
> +		if (p->default_rate)
> +			lis3lv02d_set_odr(p->default_rate);
>   	}
>
>   	/* bail if we did not get an IRQ from the bus layer */
> @@ -834,7 +840,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>
>   	err = request_threaded_irq(dev->irq, lis302dl_interrupt,
>   				thread_fn,
> -				IRQF_TRIGGER_RISING | IRQF_ONESHOT,
> +				IRQF_TRIGGER_RISING | IRQF_ONESHOT |
> +				irq_flags,
>   				DRIVER_NAME,&lis3_dev);
>
>   	if (err<  0) {
> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
> index c4a4a52..18d578f 100644
> --- a/include/linux/lis3lv02d.h
> +++ b/include/linux/lis3lv02d.h
> @@ -36,7 +36,10 @@ struct lis3lv02d_platform_data {
>   #define LIS3_IRQ_OPEN_DRAIN	(1<<  6)
>   #define LIS3_IRQ_ACTIVE_LOW	(1<<  7)
>   	unsigned char irq_cfg;
> -
> +	unsigned char irq_flags1; /* Additional irq edge / level flags */
> +	unsigned char irq_flags2; /* Additional irq edge / level flags */
> +	unsigned char duration1;
> +	unsigned char duration2;
>   #define LIS3_WAKEUP_X_LO	(1<<  0)
>   #define LIS3_WAKEUP_X_HI	(1<<  1)
>   #define LIS3_WAKEUP_Y_LO	(1<<  2)
> @@ -66,6 +69,7 @@ struct lis3lv02d_platform_data {
>   	s8 axis_z;
>   #define LIS3_USE_REGULATOR_CTRL 0x01
>   	u16 driver_features;
> +	int default_rate;
>   	int (*setup_resources)(void);
>   	int (*release_resources)(void);
>   	/* Limits for selftest are specified in chip data sheet */


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 07/12] hwmon: lis3: New parameters to platform data
@ 2010-10-24 14:27     ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:27 UTC (permalink / raw)
  To: Samu Onkalo; +Cc: linux-kernel, lm-sensors, linux-i2c

Op 22-10-10 13:57, Samu Onkalo schreef:
> Added default output data rate setting to platform data.
> If default rate is 0, reset default value is used.
> Added control for duration via platform data.
> Added possibility to configure interrupts to trig on
> both rising and falling edge. The lis3 WU unit can be
> configured quite many ways and with some configurations it
> is quite handy to get coordinate refresh when some
> event trigs and when it reason goes away.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>

> ---
>   drivers/hwmon/lis3lv02d.c |   21 ++++++++++++++-------
>   include/linux/lis3lv02d.h |    6 +++++-
>   2 files changed, 19 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index b44d4c5..d66cbe1 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -706,16 +706,16 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
>   	if (p->wakeup_flags) {
>   		dev->write(dev, FF_WU_CFG_1, p->wakeup_flags);
>   		dev->write(dev, FF_WU_THS_1, p->wakeup_thresh&  0x7f);
> -		/* default to 2.5ms for now */
> -		dev->write(dev, FF_WU_DURATION_1, 1);
> +		/* pdata value + 1 to keep this backward compatible*/
> +		dev->write(dev, FF_WU_DURATION_1, p->duration1 + 1);
>   		ctrl2 ^= HP_FF_WU1; /* Xor to keep compatible with old pdata*/
>   	}
>
>   	if (p->wakeup_flags2) {
>   		dev->write(dev, FF_WU_CFG_2, p->wakeup_flags2);
>   		dev->write(dev, FF_WU_THS_2, p->wakeup_thresh2&  0x7f);
> -		/* default to 2.5ms for now */
> -		dev->write(dev, FF_WU_DURATION_2, 1);
> +		/* pdata value + 1 to keep this backward compatible*/
> +		dev->write(dev, FF_WU_DURATION_2, p->duration2 + 1);
>   		ctrl2 ^= HP_FF_WU2; /* Xor to keep compatible with old pdata*/
>   	}
>   	/* Configure hipass filters */
> @@ -725,8 +725,8 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
>   		err = request_threaded_irq(p->irq2,
>   					NULL,
>   					lis302dl_interrupt_thread2_8b,
> -					IRQF_TRIGGER_RISING |
> -					IRQF_ONESHOT,
> +					IRQF_TRIGGER_RISING | IRQF_ONESHOT |
> +					(p->irq_flags2&  IRQF_TRIGGER_MASK),
>   					DRIVER_NAME,&lis3_dev);
>   		if (err<  0)
>   			printk(KERN_ERR DRIVER_NAME
> @@ -742,6 +742,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   {
>   	int err;
>   	irq_handler_t thread_fn;
> +	int irq_flags = 0;
>
>   	dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I);
>
> @@ -804,9 +805,14 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   		if (dev->whoami == WAI_8B)
>   			lis3lv02d_8b_configure(dev, p);
>
> +		irq_flags = p->irq_flags1&  IRQF_TRIGGER_MASK;
> +
>   		dev->irq_cfg = p->irq_cfg;
>   		if (p->irq_cfg)
>   			dev->write(dev, CTRL_REG3, p->irq_cfg);
> +
> +		if (p->default_rate)
> +			lis3lv02d_set_odr(p->default_rate);
>   	}
>
>   	/* bail if we did not get an IRQ from the bus layer */
> @@ -834,7 +840,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>
>   	err = request_threaded_irq(dev->irq, lis302dl_interrupt,
>   				thread_fn,
> -				IRQF_TRIGGER_RISING | IRQF_ONESHOT,
> +				IRQF_TRIGGER_RISING | IRQF_ONESHOT |
> +				irq_flags,
>   				DRIVER_NAME,&lis3_dev);
>
>   	if (err<  0) {
> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
> index c4a4a52..18d578f 100644
> --- a/include/linux/lis3lv02d.h
> +++ b/include/linux/lis3lv02d.h
> @@ -36,7 +36,10 @@ struct lis3lv02d_platform_data {
>   #define LIS3_IRQ_OPEN_DRAIN	(1<<  6)
>   #define LIS3_IRQ_ACTIVE_LOW	(1<<  7)
>   	unsigned char irq_cfg;
> -
> +	unsigned char irq_flags1; /* Additional irq edge / level flags */
> +	unsigned char irq_flags2; /* Additional irq edge / level flags */
> +	unsigned char duration1;
> +	unsigned char duration2;
>   #define LIS3_WAKEUP_X_LO	(1<<  0)
>   #define LIS3_WAKEUP_X_HI	(1<<  1)
>   #define LIS3_WAKEUP_Y_LO	(1<<  2)
> @@ -66,6 +69,7 @@ struct lis3lv02d_platform_data {
>   	s8 axis_z;
>   #define LIS3_USE_REGULATOR_CTRL 0x01
>   	u16 driver_features;
> +	int default_rate;
>   	int (*setup_resources)(void);
>   	int (*release_resources)(void);
>   	/* Limits for selftest are specified in chip data sheet */


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 07/12] hwmon: lis3: New parameters to
@ 2010-10-24 14:27     ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:27 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> Added default output data rate setting to platform data.
> If default rate is 0, reset default value is used.
> Added control for duration via platform data.
> Added possibility to configure interrupts to trig on
> both rising and falling edge. The lis3 WU unit can be
> configured quite many ways and with some configurations it
> is quite handy to get coordinate refresh when some
> event trigs and when it reason goes away.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>

> ---
>   drivers/hwmon/lis3lv02d.c |   21 ++++++++++++++-------
>   include/linux/lis3lv02d.h |    6 +++++-
>   2 files changed, 19 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index b44d4c5..d66cbe1 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -706,16 +706,16 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
>   	if (p->wakeup_flags) {
>   		dev->write(dev, FF_WU_CFG_1, p->wakeup_flags);
>   		dev->write(dev, FF_WU_THS_1, p->wakeup_thresh&  0x7f);
> -		/* default to 2.5ms for now */
> -		dev->write(dev, FF_WU_DURATION_1, 1);
> +		/* pdata value + 1 to keep this backward compatible*/
> +		dev->write(dev, FF_WU_DURATION_1, p->duration1 + 1);
>   		ctrl2 ^= HP_FF_WU1; /* Xor to keep compatible with old pdata*/
>   	}
>
>   	if (p->wakeup_flags2) {
>   		dev->write(dev, FF_WU_CFG_2, p->wakeup_flags2);
>   		dev->write(dev, FF_WU_THS_2, p->wakeup_thresh2&  0x7f);
> -		/* default to 2.5ms for now */
> -		dev->write(dev, FF_WU_DURATION_2, 1);
> +		/* pdata value + 1 to keep this backward compatible*/
> +		dev->write(dev, FF_WU_DURATION_2, p->duration2 + 1);
>   		ctrl2 ^= HP_FF_WU2; /* Xor to keep compatible with old pdata*/
>   	}
>   	/* Configure hipass filters */
> @@ -725,8 +725,8 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev,
>   		err = request_threaded_irq(p->irq2,
>   					NULL,
>   					lis302dl_interrupt_thread2_8b,
> -					IRQF_TRIGGER_RISING |
> -					IRQF_ONESHOT,
> +					IRQF_TRIGGER_RISING | IRQF_ONESHOT |
> +					(p->irq_flags2&  IRQF_TRIGGER_MASK),
>   					DRIVER_NAME,&lis3_dev);
>   		if (err<  0)
>   			printk(KERN_ERR DRIVER_NAME
> @@ -742,6 +742,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   {
>   	int err;
>   	irq_handler_t thread_fn;
> +	int irq_flags = 0;
>
>   	dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I);
>
> @@ -804,9 +805,14 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   		if (dev->whoami = WAI_8B)
>   			lis3lv02d_8b_configure(dev, p);
>
> +		irq_flags = p->irq_flags1&  IRQF_TRIGGER_MASK;
> +
>   		dev->irq_cfg = p->irq_cfg;
>   		if (p->irq_cfg)
>   			dev->write(dev, CTRL_REG3, p->irq_cfg);
> +
> +		if (p->default_rate)
> +			lis3lv02d_set_odr(p->default_rate);
>   	}
>
>   	/* bail if we did not get an IRQ from the bus layer */
> @@ -834,7 +840,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>
>   	err = request_threaded_irq(dev->irq, lis302dl_interrupt,
>   				thread_fn,
> -				IRQF_TRIGGER_RISING | IRQF_ONESHOT,
> +				IRQF_TRIGGER_RISING | IRQF_ONESHOT |
> +				irq_flags,
>   				DRIVER_NAME,&lis3_dev);
>
>   	if (err<  0) {
> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
> index c4a4a52..18d578f 100644
> --- a/include/linux/lis3lv02d.h
> +++ b/include/linux/lis3lv02d.h
> @@ -36,7 +36,10 @@ struct lis3lv02d_platform_data {
>   #define LIS3_IRQ_OPEN_DRAIN	(1<<  6)
>   #define LIS3_IRQ_ACTIVE_LOW	(1<<  7)
>   	unsigned char irq_cfg;
> -
> +	unsigned char irq_flags1; /* Additional irq edge / level flags */
> +	unsigned char irq_flags2; /* Additional irq edge / level flags */
> +	unsigned char duration1;
> +	unsigned char duration2;
>   #define LIS3_WAKEUP_X_LO	(1<<  0)
>   #define LIS3_WAKEUP_X_HI	(1<<  1)
>   #define LIS3_WAKEUP_Y_LO	(1<<  2)
> @@ -66,6 +69,7 @@ struct lis3lv02d_platform_data {
>   	s8 axis_z;
>   #define LIS3_USE_REGULATOR_CTRL 0x01
>   	u16 driver_features;
> +	int default_rate;
>   	int (*setup_resources)(void);
>   	int (*release_resources)(void);
>   	/* Limits for selftest are specified in chip data sheet */


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 08/12] hwmon: lis3: Adjust fuzziness for 8 bit device
  2010-10-22 11:57   ` [lm-sensors] [PATCH 08/12] hwmon: lis3: Adjust fuzziness for 8 bit Samu Onkalo
@ 2010-10-24 14:33     ` Éric Piel
  -1 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:33 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> Default fuziness is set smaller for 8 device.
> In 12 bit device LSB is quite close to 1 mg
> (mg = 1 / 1000 of earth gravity).
> In 8bit device LSB is about 18 mg.
> Set fuziness to 1 for 8 bit device.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>
> ---
>   drivers/hwmon/lis3lv02d.c |   18 ++++++++++++++----
>   1 files changed, 14 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index d66cbe1..7555091 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -71,8 +71,10 @@
>   #define LIS3_SENSITIVITY_12B		((LIS3_ACCURACY * 1000) / 1024)
>   #define LIS3_SENSITIVITY_8B		(18 * LIS3_ACCURACY)
>
> -#define LIS3_DEFAULT_FUZZ		3
> -#define LIS3_DEFAULT_FLAT		3
> +#define LIS3_DEFAULT_FUZZ_12B		3
> +#define LIS3_DEFAULT_FLAT_12B		3
> +#define LIS3_DEFAULT_FUZZ_8B		1
> +#define LIS3_DEFAULT_FLAT_8B		1
>
>   struct lis3lv02d lis3_dev = {
>   	.misc_wait   = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait),
> @@ -530,8 +532,16 @@ int lis3lv02d_joystick_enable(void)
>
>   	set_bit(EV_ABS, input_dev->evbit);
>   	max_val = (lis3_dev.mdps_max_val * lis3_dev.scale) / LIS3_ACCURACY;
> -	fuzz = (LIS3_DEFAULT_FUZZ * lis3_dev.scale) / LIS3_ACCURACY;
> -	flat = (LIS3_DEFAULT_FLAT * lis3_dev.scale) / LIS3_ACCURACY;
> +	if (lis3_dev.whoami == WAI_12B) {
> +		fuzz = LIS3_DEFAULT_FUZZ_12B;
> +		flat = LIS3_DEFAULT_FLAT_12B;
> +	} else {
> +		fuzz = LIS3_DEFAULT_FUZZ_8B;
> +		flat = LIS3_DEFAULT_FLAT_8B;
> +	}
> +	fuzz = (fuzz * lis3_dev.scale) / LIS3_ACCURACY;
> +	flat = (flat * lis3_dev.scale) / LIS3_ACCURACY;
> +
>   	input_set_abs_params(input_dev, ABS_X, -max_val, max_val, fuzz, flat);
>   	input_set_abs_params(input_dev, ABS_Y, -max_val, max_val, fuzz, flat);
>   	input_set_abs_params(input_dev, ABS_Z, -max_val, max_val, fuzz, flat);


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 08/12] hwmon: lis3: Adjust fuzziness for 8
@ 2010-10-24 14:33     ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:33 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> Default fuziness is set smaller for 8 device.
> In 12 bit device LSB is quite close to 1 mg
> (mg = 1 / 1000 of earth gravity).
> In 8bit device LSB is about 18 mg.
> Set fuziness to 1 for 8 bit device.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>
> ---
>   drivers/hwmon/lis3lv02d.c |   18 ++++++++++++++----
>   1 files changed, 14 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index d66cbe1..7555091 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -71,8 +71,10 @@
>   #define LIS3_SENSITIVITY_12B		((LIS3_ACCURACY * 1000) / 1024)
>   #define LIS3_SENSITIVITY_8B		(18 * LIS3_ACCURACY)
>
> -#define LIS3_DEFAULT_FUZZ		3
> -#define LIS3_DEFAULT_FLAT		3
> +#define LIS3_DEFAULT_FUZZ_12B		3
> +#define LIS3_DEFAULT_FLAT_12B		3
> +#define LIS3_DEFAULT_FUZZ_8B		1
> +#define LIS3_DEFAULT_FLAT_8B		1
>
>   struct lis3lv02d lis3_dev = {
>   	.misc_wait   = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait),
> @@ -530,8 +532,16 @@ int lis3lv02d_joystick_enable(void)
>
>   	set_bit(EV_ABS, input_dev->evbit);
>   	max_val = (lis3_dev.mdps_max_val * lis3_dev.scale) / LIS3_ACCURACY;
> -	fuzz = (LIS3_DEFAULT_FUZZ * lis3_dev.scale) / LIS3_ACCURACY;
> -	flat = (LIS3_DEFAULT_FLAT * lis3_dev.scale) / LIS3_ACCURACY;
> +	if (lis3_dev.whoami = WAI_12B) {
> +		fuzz = LIS3_DEFAULT_FUZZ_12B;
> +		flat = LIS3_DEFAULT_FLAT_12B;
> +	} else {
> +		fuzz = LIS3_DEFAULT_FUZZ_8B;
> +		flat = LIS3_DEFAULT_FLAT_8B;
> +	}
> +	fuzz = (fuzz * lis3_dev.scale) / LIS3_ACCURACY;
> +	flat = (flat * lis3_dev.scale) / LIS3_ACCURACY;
> +
>   	input_set_abs_params(input_dev, ABS_X, -max_val, max_val, fuzz, flat);
>   	input_set_abs_params(input_dev, ABS_Y, -max_val, max_val, fuzz, flat);
>   	input_set_abs_params(input_dev, ABS_Z, -max_val, max_val, fuzz, flat);


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 09/12] hwmon: lis3: use block read to access data registers
  2010-10-22 11:57   ` [lm-sensors] [PATCH 09/12] hwmon: lis3: use block read to access Samu Onkalo
@ 2010-10-24 14:53     ` Éric Piel
  -1 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:53 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> Add optional blockread function to interface driver. If available
> the chip driver uses it for data register access. For 12 bit device
> it reads 6 bytes to get 3*16bit data. For 8 bit device it reads out
> 5 bytes since every second byte is dummy.
> This optimizes bus usage and reduces number of operations and
> interrupts needed for one data update.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>

> ---
>   drivers/hwmon/lis3lv02d.c     |   21 ++++++++++++++++++---
>   drivers/hwmon/lis3lv02d.h     |    1 +
>   drivers/hwmon/lis3lv02d_i2c.c |   13 +++++++++++++
>   include/linux/lis3lv02d.h     |    1 +
>   4 files changed, 33 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index 7555091..9fd946c 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -130,9 +130,24 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
>   	int position[3];
>   	int i;
>
> -	position[0] = lis3->read_data(lis3, OUTX);
> -	position[1] = lis3->read_data(lis3, OUTY);
> -	position[2] = lis3->read_data(lis3, OUTZ);
> +	if (lis3->blkread) {
> +		if (lis3_dev.whoami == WAI_12B) {
> +			u16 data[3];
> +			lis3->blkread(lis3, OUTX_L, 6, (u8 *)data);
> +			for (i = 0; i<  3; i++)
> +				position[i] = (s16)le16_to_cpu(data[i]);
> +		} else {
> +			u8 data[5];
> +			/* Data: x, dummy, y, dummy, z */
> +			lis3->blkread(lis3, OUTX, 5, data);
> +			for (i = 0; i<  3; i++)
> +				position[i] = (s8)data[i * 2];
> +		}
> +	} else {
> +		position[0] = lis3->read_data(lis3, OUTX);
> +		position[1] = lis3->read_data(lis3, OUTY);
> +		position[2] = lis3->read_data(lis3, OUTZ);
> +	}
>
>   	for (i = 0; i<  3; i++)
>   		position[i] = (position[i] * lis3->scale) / LIS3_ACCURACY;
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 2ac27b9..d3cb662 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -225,6 +225,7 @@ struct lis3lv02d {
>   	int (*init) (struct lis3lv02d *lis3);
>   	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
>   	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
> +	int (*blkread) (struct lis3lv02d *lis3, int reg, int len, u8 *ret);
>   	int (*reg_ctrl) (struct lis3lv02d *lis3, bool state);
>
>   	int                     *odrs;     /* Supported output data rates */
> diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
> index 36171bf..61c109b 100644
> --- a/drivers/hwmon/lis3lv02d_i2c.c
> +++ b/drivers/hwmon/lis3lv02d_i2c.c
> @@ -66,6 +66,14 @@ static inline s32 lis3_i2c_read(struct lis3lv02d *lis3, int reg, u8 *v)
>   	return 0;
>   }
>
> +static inline s32 lis3_i2c_blockread(struct lis3lv02d *lis3, int reg, int len,
> +				u8 *v)
> +{
> +	struct i2c_client *c = lis3->bus_priv;
> +	reg |= (1<<  7); /* 7th bit enables address auto incrementation */
> +	return i2c_smbus_read_i2c_block_data(c, reg, len, v);
> +}
> +
>   static int lis3_i2c_init(struct lis3lv02d *lis3)
>   {
>   	u8 reg;
> @@ -103,6 +111,11 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>   		if (pdata->driver_features&  LIS3_USE_REGULATOR_CTRL)
>   			lis3_dev.reg_ctrl = lis3_reg_ctrl;
>
> +		if ((pdata->driver_features&  LIS3_USE_BLOCK_READ)&&
> +			(i2c_check_functionality(client->adapter,
> +						I2C_FUNC_SMBUS_I2C_BLOCK)))
> +			lis3_dev.blkread  = lis3_i2c_blockread;
> +
>   		if (pdata->axis_x)
>   			lis3lv02d_axis_map.x = pdata->axis_x;
>
> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
> index 18d578f..c949612 100644
> --- a/include/linux/lis3lv02d.h
> +++ b/include/linux/lis3lv02d.h
> @@ -68,6 +68,7 @@ struct lis3lv02d_platform_data {
>   	s8 axis_y;
>   	s8 axis_z;
>   #define LIS3_USE_REGULATOR_CTRL 0x01
> +#define LIS3_USE_BLOCK_READ	0x02
>   	u16 driver_features;
>   	int default_rate;
>   	int (*setup_resources)(void);


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 09/12] hwmon: lis3: use block read to
@ 2010-10-24 14:53     ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:53 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> Add optional blockread function to interface driver. If available
> the chip driver uses it for data register access. For 12 bit device
> it reads 6 bytes to get 3*16bit data. For 8 bit device it reads out
> 5 bytes since every second byte is dummy.
> This optimizes bus usage and reduces number of operations and
> interrupts needed for one data update.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>

> ---
>   drivers/hwmon/lis3lv02d.c     |   21 ++++++++++++++++++---
>   drivers/hwmon/lis3lv02d.h     |    1 +
>   drivers/hwmon/lis3lv02d_i2c.c |   13 +++++++++++++
>   include/linux/lis3lv02d.h     |    1 +
>   4 files changed, 33 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index 7555091..9fd946c 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -130,9 +130,24 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
>   	int position[3];
>   	int i;
>
> -	position[0] = lis3->read_data(lis3, OUTX);
> -	position[1] = lis3->read_data(lis3, OUTY);
> -	position[2] = lis3->read_data(lis3, OUTZ);
> +	if (lis3->blkread) {
> +		if (lis3_dev.whoami = WAI_12B) {
> +			u16 data[3];
> +			lis3->blkread(lis3, OUTX_L, 6, (u8 *)data);
> +			for (i = 0; i<  3; i++)
> +				position[i] = (s16)le16_to_cpu(data[i]);
> +		} else {
> +			u8 data[5];
> +			/* Data: x, dummy, y, dummy, z */
> +			lis3->blkread(lis3, OUTX, 5, data);
> +			for (i = 0; i<  3; i++)
> +				position[i] = (s8)data[i * 2];
> +		}
> +	} else {
> +		position[0] = lis3->read_data(lis3, OUTX);
> +		position[1] = lis3->read_data(lis3, OUTY);
> +		position[2] = lis3->read_data(lis3, OUTZ);
> +	}
>
>   	for (i = 0; i<  3; i++)
>   		position[i] = (position[i] * lis3->scale) / LIS3_ACCURACY;
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 2ac27b9..d3cb662 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -225,6 +225,7 @@ struct lis3lv02d {
>   	int (*init) (struct lis3lv02d *lis3);
>   	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
>   	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
> +	int (*blkread) (struct lis3lv02d *lis3, int reg, int len, u8 *ret);
>   	int (*reg_ctrl) (struct lis3lv02d *lis3, bool state);
>
>   	int                     *odrs;     /* Supported output data rates */
> diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
> index 36171bf..61c109b 100644
> --- a/drivers/hwmon/lis3lv02d_i2c.c
> +++ b/drivers/hwmon/lis3lv02d_i2c.c
> @@ -66,6 +66,14 @@ static inline s32 lis3_i2c_read(struct lis3lv02d *lis3, int reg, u8 *v)
>   	return 0;
>   }
>
> +static inline s32 lis3_i2c_blockread(struct lis3lv02d *lis3, int reg, int len,
> +				u8 *v)
> +{
> +	struct i2c_client *c = lis3->bus_priv;
> +	reg |= (1<<  7); /* 7th bit enables address auto incrementation */
> +	return i2c_smbus_read_i2c_block_data(c, reg, len, v);
> +}
> +
>   static int lis3_i2c_init(struct lis3lv02d *lis3)
>   {
>   	u8 reg;
> @@ -103,6 +111,11 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>   		if (pdata->driver_features&  LIS3_USE_REGULATOR_CTRL)
>   			lis3_dev.reg_ctrl = lis3_reg_ctrl;
>
> +		if ((pdata->driver_features&  LIS3_USE_BLOCK_READ)&&
> +			(i2c_check_functionality(client->adapter,
> +						I2C_FUNC_SMBUS_I2C_BLOCK)))
> +			lis3_dev.blkread  = lis3_i2c_blockread;
> +
>   		if (pdata->axis_x)
>   			lis3lv02d_axis_map.x = pdata->axis_x;
>
> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
> index 18d578f..c949612 100644
> --- a/include/linux/lis3lv02d.h
> +++ b/include/linux/lis3lv02d.h
> @@ -68,6 +68,7 @@ struct lis3lv02d_platform_data {
>   	s8 axis_y;
>   	s8 axis_z;
>   #define LIS3_USE_REGULATOR_CTRL 0x01
> +#define LIS3_USE_BLOCK_READ	0x02
>   	u16 driver_features;
>   	int default_rate;
>   	int (*setup_resources)(void);


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 10/12] hwmon: lis3: Enhance lis3 selftest with IRQ line test
@ 2010-10-24 14:58     ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:58 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> Configure chip to data ready mode in selftest and count received
> interrupts to see that interrupt line(s) are working.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>
> ---
>   drivers/hwmon/lis3lv02d.c |   87 ++++++++++++++++++++++++++++++++++++++++----
>   drivers/hwmon/lis3lv02d.h |    3 +-
>   2 files changed, 81 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index 9fd946c..f0343f3 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -48,6 +48,13 @@
>
>   #define LIS3_SYSFS_POWERDOWN_DELAY 5000 /* In milliseconds */
>
> +#define SELFTEST_OK	       0
> +#define SELFTEST_FAIL	       -1
> +#define SELFTEST_IRQ	       -2
> +
> +#define IRQ_LINE0	       0
> +#define IRQ_LINE1	       1
> +
>   /*
>    * The sensor can also generate interrupts (DRDY) but it's pretty pointless
>    * because they are generated even if the data do not change. So it's better
> @@ -198,6 +205,8 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
>   	s16 x, y, z;
>   	u8 selftest;
>   	int ret;
> +	u8 ctrl_reg_data;
> +	unsigned char irq_cfg;
>
>   	mutex_lock(&lis3->mutex);
>   	if (lis3_dev.whoami == WAI_12B)
> @@ -205,6 +214,20 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
>   	else
>   		selftest = CTRL1_STP;
>
> +	irq_cfg = lis3->irq_cfg;
> +	if (lis3_dev.whoami == WAI_8B) {
> +		lis3->data_ready_count[IRQ_LINE0] = 0;
> +		lis3->data_ready_count[IRQ_LINE1] = 0;
> +
> +		/* Change interrupt cfg to data ready for selftest */
> +		atomic_inc(&lis3_dev.wake_thread);
> +		lis3->irq_cfg = LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY;
> +		lis3->read(lis3, CTRL_REG3,&ctrl_reg_data);
> +		lis3->write(lis3, CTRL_REG3, (ctrl_reg_data&
> +				~(LIS3_IRQ1_MASK | LIS3_IRQ2_MASK)) |
> +				(LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY));
> +	}
> +
>   	lis3->read(lis3, CTRL_REG1,&reg);
>   	lis3->write(lis3, CTRL_REG1, (reg | selftest));
>   	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
> @@ -223,13 +246,33 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
>   	results[2] = z - lis3->read_data(lis3, OUTZ);
>
>   	ret = 0;
> +
> +	if (lis3_dev.whoami == WAI_8B) {
> +		/* Restore original interrupt configuration */
> +		atomic_dec(&lis3_dev.wake_thread);
> +		lis3->write(lis3, CTRL_REG3, ctrl_reg_data);
> +		lis3->irq_cfg = irq_cfg;
> +
> +		if ((irq_cfg&  LIS3_IRQ1_MASK)&&
> +			lis3->data_ready_count[IRQ_LINE0]<  2) {
> +			ret = SELFTEST_IRQ;
> +			goto fail;
> +		}
> +
> +		if ((irq_cfg&  LIS3_IRQ2_MASK)&&
> +			lis3->data_ready_count[IRQ_LINE1]<  2) {
> +			ret = SELFTEST_IRQ;
> +			goto fail;
> +		}
> +	}
> +
>   	if (lis3->pdata) {
>   		int i;
>   		for (i = 0; i<  3; i++) {
>   			/* Check against selftest acceptance limits */
>   			if ((results[i]<  lis3->pdata->st_min_limits[i]) ||
>   			    (results[i]>  lis3->pdata->st_max_limits[i])) {
> -				ret = -EIO;
> +				ret = SELFTEST_FAIL;
>   				goto fail;
>   			}
>   		}
> @@ -392,13 +435,24 @@ static void lis302dl_interrupt_handle_click(struct lis3lv02d *lis3)
>   	mutex_unlock(&lis3->mutex);
>   }
>
> -static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
> +static inline void lis302dl_data_ready(struct lis3lv02d *lis3, int index)
>   {
> +	int dummy;
>
> +	/* Dummy read to ack interrupt */
> +	lis3lv02d_get_xyz(lis3,&dummy,&dummy,&dummy);
> +	lis3->data_ready_count[index]++;
> +}
> +
> +static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
> +{
>   	struct lis3lv02d *lis3 = data;
> +	u8 irq_cfg = lis3->irq_cfg&  LIS3_IRQ1_MASK;
>
> -	if ((lis3->irq_cfg&  LIS3_IRQ1_MASK) == LIS3_IRQ1_CLICK)
> +	if (irq_cfg == LIS3_IRQ1_CLICK)
>   		lis302dl_interrupt_handle_click(lis3);
> +	else if (unlikely(irq_cfg == LIS3_IRQ1_DATA_READY))
> +		lis302dl_data_ready(lis3, IRQ_LINE0);
>   	else
>   		lis3lv02d_joystick_poll(lis3->idev);
>
> @@ -407,11 +461,13 @@ static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
>
>   static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data)
>   {
> -
>   	struct lis3lv02d *lis3 = data;
> +	u8 irq_cfg = lis3->irq_cfg&  LIS3_IRQ2_MASK;
>
> -	if ((lis3->irq_cfg&  LIS3_IRQ2_MASK) == LIS3_IRQ2_CLICK)
> +	if (irq_cfg == LIS3_IRQ2_CLICK)
>   		lis302dl_interrupt_handle_click(lis3);
> +	else if (unlikely(irq_cfg == LIS3_IRQ2_DATA_READY))
> +		lis302dl_data_ready(lis3, IRQ_LINE1);
>   	else
>   		lis3lv02d_joystick_poll(lis3->idev);
>
> @@ -614,12 +670,27 @@ static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3)
>   static ssize_t lis3lv02d_selftest_show(struct device *dev,
>   				struct device_attribute *attr, char *buf)
>   {
> -	int result;
>   	s16 values[3];
>
> +	static const char ok[] = "OK";
> +	static const char fail[] = "FAIL";
> +	static const char irq[] = "FAIL_IRQ";
> +	const char *res;
> +
>   	lis3lv02d_sysfs_poweron(&lis3_dev);
> -	result = lis3lv02d_selftest(&lis3_dev, values);
> -	return sprintf(buf, "%s %d %d %d\n", result == 0 ? "OK" : "FAIL",
> +	switch (lis3lv02d_selftest(&lis3_dev, values)) {
> +	case SELFTEST_FAIL:
> +		res = fail;
> +		break;
> +	case SELFTEST_IRQ:
> +		res = irq;
> +		break;
> +	case SELFTEST_OK:
> +	default:
> +		res = ok;
> +		break;
> +	}
> +	return sprintf(buf, "%s %d %d %d\n", res,
>   		values[0], values[1], values[2]);
>   }
>
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index d3cb662..7b22cd9 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -254,7 +254,8 @@ struct lis3lv02d {
>   	struct fasync_struct	*async_queue; /* queue for the misc device */
>   	wait_queue_head_t	misc_wait; /* Wait queue for the misc device */
>   	unsigned long		misc_opened; /* bit0: whether the device is open */
> -	atomic_t                wake_thread;
> +	int                     data_ready_count[2];
> +	atomic_t		wake_thread;
>   	unsigned char           irq_cfg;
>
>   	struct lis3lv02d_platform_data *pdata;	/* for passing board config */


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 10/12] hwmon: lis3: Enhance lis3 selftest with IRQ line test
@ 2010-10-24 14:58     ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:58 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali-PUYAD+kWke1g9hUCZPvPmw,
	guenter.roeck-IzeFyvvaP7pWk0Htik3J/w,
	jic23-KWPb1pKIrIJaa/9Udqfwiw, lm-sensors-GZX6beZjE8VD60Wz+7aTrA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Op 22-10-10 13:57, Samu Onkalo schreef:
> Configure chip to data ready mode in selftest and count received
> interrupts to see that interrupt line(s) are working.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
Acked-by: Eric Piel <eric.piel-VkQ1JFuSMpfAbQlEx87xDw@public.gmane.org>
> ---
>   drivers/hwmon/lis3lv02d.c |   87 ++++++++++++++++++++++++++++++++++++++++----
>   drivers/hwmon/lis3lv02d.h |    3 +-
>   2 files changed, 81 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index 9fd946c..f0343f3 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -48,6 +48,13 @@
>
>   #define LIS3_SYSFS_POWERDOWN_DELAY 5000 /* In milliseconds */
>
> +#define SELFTEST_OK	       0
> +#define SELFTEST_FAIL	       -1
> +#define SELFTEST_IRQ	       -2
> +
> +#define IRQ_LINE0	       0
> +#define IRQ_LINE1	       1
> +
>   /*
>    * The sensor can also generate interrupts (DRDY) but it's pretty pointless
>    * because they are generated even if the data do not change. So it's better
> @@ -198,6 +205,8 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
>   	s16 x, y, z;
>   	u8 selftest;
>   	int ret;
> +	u8 ctrl_reg_data;
> +	unsigned char irq_cfg;
>
>   	mutex_lock(&lis3->mutex);
>   	if (lis3_dev.whoami == WAI_12B)
> @@ -205,6 +214,20 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
>   	else
>   		selftest = CTRL1_STP;
>
> +	irq_cfg = lis3->irq_cfg;
> +	if (lis3_dev.whoami == WAI_8B) {
> +		lis3->data_ready_count[IRQ_LINE0] = 0;
> +		lis3->data_ready_count[IRQ_LINE1] = 0;
> +
> +		/* Change interrupt cfg to data ready for selftest */
> +		atomic_inc(&lis3_dev.wake_thread);
> +		lis3->irq_cfg = LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY;
> +		lis3->read(lis3, CTRL_REG3,&ctrl_reg_data);
> +		lis3->write(lis3, CTRL_REG3, (ctrl_reg_data&
> +				~(LIS3_IRQ1_MASK | LIS3_IRQ2_MASK)) |
> +				(LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY));
> +	}
> +
>   	lis3->read(lis3, CTRL_REG1,&reg);
>   	lis3->write(lis3, CTRL_REG1, (reg | selftest));
>   	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
> @@ -223,13 +246,33 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
>   	results[2] = z - lis3->read_data(lis3, OUTZ);
>
>   	ret = 0;
> +
> +	if (lis3_dev.whoami == WAI_8B) {
> +		/* Restore original interrupt configuration */
> +		atomic_dec(&lis3_dev.wake_thread);
> +		lis3->write(lis3, CTRL_REG3, ctrl_reg_data);
> +		lis3->irq_cfg = irq_cfg;
> +
> +		if ((irq_cfg&  LIS3_IRQ1_MASK)&&
> +			lis3->data_ready_count[IRQ_LINE0]<  2) {
> +			ret = SELFTEST_IRQ;
> +			goto fail;
> +		}
> +
> +		if ((irq_cfg&  LIS3_IRQ2_MASK)&&
> +			lis3->data_ready_count[IRQ_LINE1]<  2) {
> +			ret = SELFTEST_IRQ;
> +			goto fail;
> +		}
> +	}
> +
>   	if (lis3->pdata) {
>   		int i;
>   		for (i = 0; i<  3; i++) {
>   			/* Check against selftest acceptance limits */
>   			if ((results[i]<  lis3->pdata->st_min_limits[i]) ||
>   			    (results[i]>  lis3->pdata->st_max_limits[i])) {
> -				ret = -EIO;
> +				ret = SELFTEST_FAIL;
>   				goto fail;
>   			}
>   		}
> @@ -392,13 +435,24 @@ static void lis302dl_interrupt_handle_click(struct lis3lv02d *lis3)
>   	mutex_unlock(&lis3->mutex);
>   }
>
> -static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
> +static inline void lis302dl_data_ready(struct lis3lv02d *lis3, int index)
>   {
> +	int dummy;
>
> +	/* Dummy read to ack interrupt */
> +	lis3lv02d_get_xyz(lis3,&dummy,&dummy,&dummy);
> +	lis3->data_ready_count[index]++;
> +}
> +
> +static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
> +{
>   	struct lis3lv02d *lis3 = data;
> +	u8 irq_cfg = lis3->irq_cfg&  LIS3_IRQ1_MASK;
>
> -	if ((lis3->irq_cfg&  LIS3_IRQ1_MASK) == LIS3_IRQ1_CLICK)
> +	if (irq_cfg == LIS3_IRQ1_CLICK)
>   		lis302dl_interrupt_handle_click(lis3);
> +	else if (unlikely(irq_cfg == LIS3_IRQ1_DATA_READY))
> +		lis302dl_data_ready(lis3, IRQ_LINE0);
>   	else
>   		lis3lv02d_joystick_poll(lis3->idev);
>
> @@ -407,11 +461,13 @@ static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
>
>   static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data)
>   {
> -
>   	struct lis3lv02d *lis3 = data;
> +	u8 irq_cfg = lis3->irq_cfg&  LIS3_IRQ2_MASK;
>
> -	if ((lis3->irq_cfg&  LIS3_IRQ2_MASK) == LIS3_IRQ2_CLICK)
> +	if (irq_cfg == LIS3_IRQ2_CLICK)
>   		lis302dl_interrupt_handle_click(lis3);
> +	else if (unlikely(irq_cfg == LIS3_IRQ2_DATA_READY))
> +		lis302dl_data_ready(lis3, IRQ_LINE1);
>   	else
>   		lis3lv02d_joystick_poll(lis3->idev);
>
> @@ -614,12 +670,27 @@ static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3)
>   static ssize_t lis3lv02d_selftest_show(struct device *dev,
>   				struct device_attribute *attr, char *buf)
>   {
> -	int result;
>   	s16 values[3];
>
> +	static const char ok[] = "OK";
> +	static const char fail[] = "FAIL";
> +	static const char irq[] = "FAIL_IRQ";
> +	const char *res;
> +
>   	lis3lv02d_sysfs_poweron(&lis3_dev);
> -	result = lis3lv02d_selftest(&lis3_dev, values);
> -	return sprintf(buf, "%s %d %d %d\n", result == 0 ? "OK" : "FAIL",
> +	switch (lis3lv02d_selftest(&lis3_dev, values)) {
> +	case SELFTEST_FAIL:
> +		res = fail;
> +		break;
> +	case SELFTEST_IRQ:
> +		res = irq;
> +		break;
> +	case SELFTEST_OK:
> +	default:
> +		res = ok;
> +		break;
> +	}
> +	return sprintf(buf, "%s %d %d %d\n", res,
>   		values[0], values[1], values[2]);
>   }
>
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index d3cb662..7b22cd9 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -254,7 +254,8 @@ struct lis3lv02d {
>   	struct fasync_struct	*async_queue; /* queue for the misc device */
>   	wait_queue_head_t	misc_wait; /* Wait queue for the misc device */
>   	unsigned long		misc_opened; /* bit0: whether the device is open */
> -	atomic_t                wake_thread;
> +	int                     data_ready_count[2];
> +	atomic_t		wake_thread;
>   	unsigned char           irq_cfg;
>
>   	struct lis3lv02d_platform_data *pdata;	/* for passing board config */

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 10/12] hwmon: lis3: Enhance lis3 selftest
@ 2010-10-24 14:58     ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:58 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> Configure chip to data ready mode in selftest and count received
> interrupts to see that interrupt line(s) are working.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>
> ---
>   drivers/hwmon/lis3lv02d.c |   87 ++++++++++++++++++++++++++++++++++++++++----
>   drivers/hwmon/lis3lv02d.h |    3 +-
>   2 files changed, 81 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index 9fd946c..f0343f3 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -48,6 +48,13 @@
>
>   #define LIS3_SYSFS_POWERDOWN_DELAY 5000 /* In milliseconds */
>
> +#define SELFTEST_OK	       0
> +#define SELFTEST_FAIL	       -1
> +#define SELFTEST_IRQ	       -2
> +
> +#define IRQ_LINE0	       0
> +#define IRQ_LINE1	       1
> +
>   /*
>    * The sensor can also generate interrupts (DRDY) but it's pretty pointless
>    * because they are generated even if the data do not change. So it's better
> @@ -198,6 +205,8 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
>   	s16 x, y, z;
>   	u8 selftest;
>   	int ret;
> +	u8 ctrl_reg_data;
> +	unsigned char irq_cfg;
>
>   	mutex_lock(&lis3->mutex);
>   	if (lis3_dev.whoami = WAI_12B)
> @@ -205,6 +214,20 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
>   	else
>   		selftest = CTRL1_STP;
>
> +	irq_cfg = lis3->irq_cfg;
> +	if (lis3_dev.whoami = WAI_8B) {
> +		lis3->data_ready_count[IRQ_LINE0] = 0;
> +		lis3->data_ready_count[IRQ_LINE1] = 0;
> +
> +		/* Change interrupt cfg to data ready for selftest */
> +		atomic_inc(&lis3_dev.wake_thread);
> +		lis3->irq_cfg = LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY;
> +		lis3->read(lis3, CTRL_REG3,&ctrl_reg_data);
> +		lis3->write(lis3, CTRL_REG3, (ctrl_reg_data&
> +				~(LIS3_IRQ1_MASK | LIS3_IRQ2_MASK)) |
> +				(LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY));
> +	}
> +
>   	lis3->read(lis3, CTRL_REG1,&reg);
>   	lis3->write(lis3, CTRL_REG1, (reg | selftest));
>   	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
> @@ -223,13 +246,33 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
>   	results[2] = z - lis3->read_data(lis3, OUTZ);
>
>   	ret = 0;
> +
> +	if (lis3_dev.whoami = WAI_8B) {
> +		/* Restore original interrupt configuration */
> +		atomic_dec(&lis3_dev.wake_thread);
> +		lis3->write(lis3, CTRL_REG3, ctrl_reg_data);
> +		lis3->irq_cfg = irq_cfg;
> +
> +		if ((irq_cfg&  LIS3_IRQ1_MASK)&&
> +			lis3->data_ready_count[IRQ_LINE0]<  2) {
> +			ret = SELFTEST_IRQ;
> +			goto fail;
> +		}
> +
> +		if ((irq_cfg&  LIS3_IRQ2_MASK)&&
> +			lis3->data_ready_count[IRQ_LINE1]<  2) {
> +			ret = SELFTEST_IRQ;
> +			goto fail;
> +		}
> +	}
> +
>   	if (lis3->pdata) {
>   		int i;
>   		for (i = 0; i<  3; i++) {
>   			/* Check against selftest acceptance limits */
>   			if ((results[i]<  lis3->pdata->st_min_limits[i]) ||
>   			    (results[i]>  lis3->pdata->st_max_limits[i])) {
> -				ret = -EIO;
> +				ret = SELFTEST_FAIL;
>   				goto fail;
>   			}
>   		}
> @@ -392,13 +435,24 @@ static void lis302dl_interrupt_handle_click(struct lis3lv02d *lis3)
>   	mutex_unlock(&lis3->mutex);
>   }
>
> -static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
> +static inline void lis302dl_data_ready(struct lis3lv02d *lis3, int index)
>   {
> +	int dummy;
>
> +	/* Dummy read to ack interrupt */
> +	lis3lv02d_get_xyz(lis3,&dummy,&dummy,&dummy);
> +	lis3->data_ready_count[index]++;
> +}
> +
> +static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
> +{
>   	struct lis3lv02d *lis3 = data;
> +	u8 irq_cfg = lis3->irq_cfg&  LIS3_IRQ1_MASK;
>
> -	if ((lis3->irq_cfg&  LIS3_IRQ1_MASK) = LIS3_IRQ1_CLICK)
> +	if (irq_cfg = LIS3_IRQ1_CLICK)
>   		lis302dl_interrupt_handle_click(lis3);
> +	else if (unlikely(irq_cfg = LIS3_IRQ1_DATA_READY))
> +		lis302dl_data_ready(lis3, IRQ_LINE0);
>   	else
>   		lis3lv02d_joystick_poll(lis3->idev);
>
> @@ -407,11 +461,13 @@ static irqreturn_t lis302dl_interrupt_thread1_8b(int irq, void *data)
>
>   static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data)
>   {
> -
>   	struct lis3lv02d *lis3 = data;
> +	u8 irq_cfg = lis3->irq_cfg&  LIS3_IRQ2_MASK;
>
> -	if ((lis3->irq_cfg&  LIS3_IRQ2_MASK) = LIS3_IRQ2_CLICK)
> +	if (irq_cfg = LIS3_IRQ2_CLICK)
>   		lis302dl_interrupt_handle_click(lis3);
> +	else if (unlikely(irq_cfg = LIS3_IRQ2_DATA_READY))
> +		lis302dl_data_ready(lis3, IRQ_LINE1);
>   	else
>   		lis3lv02d_joystick_poll(lis3->idev);
>
> @@ -614,12 +670,27 @@ static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3)
>   static ssize_t lis3lv02d_selftest_show(struct device *dev,
>   				struct device_attribute *attr, char *buf)
>   {
> -	int result;
>   	s16 values[3];
>
> +	static const char ok[] = "OK";
> +	static const char fail[] = "FAIL";
> +	static const char irq[] = "FAIL_IRQ";
> +	const char *res;
> +
>   	lis3lv02d_sysfs_poweron(&lis3_dev);
> -	result = lis3lv02d_selftest(&lis3_dev, values);
> -	return sprintf(buf, "%s %d %d %d\n", result = 0 ? "OK" : "FAIL",
> +	switch (lis3lv02d_selftest(&lis3_dev, values)) {
> +	case SELFTEST_FAIL:
> +		res = fail;
> +		break;
> +	case SELFTEST_IRQ:
> +		res = irq;
> +		break;
> +	case SELFTEST_OK:
> +	default:
> +		res = ok;
> +		break;
> +	}
> +	return sprintf(buf, "%s %d %d %d\n", res,
>   		values[0], values[1], values[2]);
>   }
>
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index d3cb662..7b22cd9 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -254,7 +254,8 @@ struct lis3lv02d {
>   	struct fasync_struct	*async_queue; /* queue for the misc device */
>   	wait_queue_head_t	misc_wait; /* Wait queue for the misc device */
>   	unsigned long		misc_opened; /* bit0: whether the device is open */
> -	atomic_t                wake_thread;
> +	int                     data_ready_count[2];
> +	atomic_t		wake_thread;
>   	unsigned char           irq_cfg;
>
>   	struct lis3lv02d_platform_data *pdata;	/* for passing board config */


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCHv2] hwmon: lis3: Short explanations of platform data fields
       [not found]         ` <1287841184-4871-1-git-send-email-samu.p.onkalo-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
@ 2010-10-24 14:59             ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:59 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: guenter.roeck-IzeFyvvaP7pWk0Htik3J/w,
	jic23-KWPb1pKIrIJaa/9Udqfwiw, linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	lm-sensors-GZX6beZjE8VD60Wz+7aTrA

Op 23-10-10 15:39, Samu Onkalo schreef:
> Short documentation at kernel doc format.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
Acked-by: Eric Piel <eric.piel-VkQ1JFuSMpfAbQlEx87xDw@public.gmane.org>
> ---
>   include/linux/lis3lv02d.h |   46 +++++++++++++++++++++++++++++++++++++++++++++
>   1 files changed, 46 insertions(+), 0 deletions(-)
>
> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
> index c949612..d4292c8 100644
> --- a/include/linux/lis3lv02d.h
> +++ b/include/linux/lis3lv02d.h
> @@ -1,6 +1,52 @@
>   #ifndef __LIS3LV02D_H_
>   #define __LIS3LV02D_H_
>
> +/**
> + * struct lis3lv02d_platform_data - lis3 chip family platform data
> + * @click_flags:	Click detection unit configuration
> + * @click_thresh_x:	Click detection unit x axis threshold
> + * @click_thresh_y:	Click detection unit y axis threshold
> + * @click_thresh_z:	Click detection unit z axis threshold
> + * @click_time_limit:	Click detection unit time parameter
> + * @click_latency:	Click detection unit latency parameter
> + * @click_window:	Click detection unit window parameter
> + * @irq_cfg:		On chip irq source and type configuration (click /
> + *			data available / wake up, open drain, polarity)
> + * @irq_flags1:		Additional irq triggering flags for irq channel 0
> + * @irq_flags2:		Additional irq triggering flags for irq channel 1
> + * @duration1:		Wake up unit 1 duration parameter
> + * @duration2:		Wake up unit 2 duration parameter
> + * @wakeup_flags:	Wake up unit 1 flags
> + * @wakeup_thresh:	Wake up unit 1 threshold value
> + * @wakeup_flags2:	Wake up unit 2 flags
> + * @wakeup_thresh2:	Wake up unit 2 threshold value
> + * @hipass_ctrl:	High pass filter control (enable / disable, cut off
> + *			frequency)
> + * @axis_x:		Sensor orientation remapping for x-axis
> + * @axis_y:		Sensor orientation remapping for y-axis
> + * @axis_z:		Sensor orientation remapping for z-axis
> + * @driver_features:	Enable bits for different features. Disabled by default
> + * @default_rate:	Default sampling rate. 0 means reset default
> + * @setup_resources:	Interrupt line setup call back function
> + * @release_resources:	Interrupt line release call back function
> + * @st_min_limits[3]:	Selftest acceptance minimum values
> + * @st_max_limits[3]:	Selftest acceptance maximum values
> + * @irq2:		Irq line 2 number
> + *
> + * Platform data is used to setup the sensor chip. Meaning of the different
> + * chip features can be found from the data sheet. It is publicly available
> + * at www.st.com web pages. Currently the platform data is used
> + * only for the 8 bit device. The 8 bit device has two wake up / free fall
> + * detection units and click detection unit. There are plenty of ways to
> + * configure the chip which makes is quite hard to explain deeper meaning of
> + * the fields here. Behaviour of the detection blocks varies heavily depending
> + * on the configuration. For example, interrupt detection block can use high
> + * pass filtered data which makes it react to the changes in the acceleration.
> + * Irq_flags can be used to enable interrupt detection on the both edges.
> + * With proper chip configuration this produces interrupt when some trigger
> + * starts and when it goes away.
> + */
> +
>   struct lis3lv02d_platform_data {
>   	/* please note: the 'click' feature is only supported for
>   	 * LIS[32]02DL variants of the chip and will be ignored for

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCHv2] hwmon: lis3: Short explanations of
@ 2010-10-24 14:59             ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:59 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: guenter.roeck-IzeFyvvaP7pWk0Htik3J/w,
	jic23-KWPb1pKIrIJaa/9Udqfwiw, linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	lm-sensors-GZX6beZjE8VD60Wz+7aTrA

Op 23-10-10 15:39, Samu Onkalo schreef:
> Short documentation at kernel doc format.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>
> ---
>   include/linux/lis3lv02d.h |   46 +++++++++++++++++++++++++++++++++++++++++++++
>   1 files changed, 46 insertions(+), 0 deletions(-)
>
> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
> index c949612..d4292c8 100644
> --- a/include/linux/lis3lv02d.h
> +++ b/include/linux/lis3lv02d.h
> @@ -1,6 +1,52 @@
>   #ifndef __LIS3LV02D_H_
>   #define __LIS3LV02D_H_
>
> +/**
> + * struct lis3lv02d_platform_data - lis3 chip family platform data
> + * @click_flags:	Click detection unit configuration
> + * @click_thresh_x:	Click detection unit x axis threshold
> + * @click_thresh_y:	Click detection unit y axis threshold
> + * @click_thresh_z:	Click detection unit z axis threshold
> + * @click_time_limit:	Click detection unit time parameter
> + * @click_latency:	Click detection unit latency parameter
> + * @click_window:	Click detection unit window parameter
> + * @irq_cfg:		On chip irq source and type configuration (click /
> + *			data available / wake up, open drain, polarity)
> + * @irq_flags1:		Additional irq triggering flags for irq channel 0
> + * @irq_flags2:		Additional irq triggering flags for irq channel 1
> + * @duration1:		Wake up unit 1 duration parameter
> + * @duration2:		Wake up unit 2 duration parameter
> + * @wakeup_flags:	Wake up unit 1 flags
> + * @wakeup_thresh:	Wake up unit 1 threshold value
> + * @wakeup_flags2:	Wake up unit 2 flags
> + * @wakeup_thresh2:	Wake up unit 2 threshold value
> + * @hipass_ctrl:	High pass filter control (enable / disable, cut off
> + *			frequency)
> + * @axis_x:		Sensor orientation remapping for x-axis
> + * @axis_y:		Sensor orientation remapping for y-axis
> + * @axis_z:		Sensor orientation remapping for z-axis
> + * @driver_features:	Enable bits for different features. Disabled by default
> + * @default_rate:	Default sampling rate. 0 means reset default
> + * @setup_resources:	Interrupt line setup call back function
> + * @release_resources:	Interrupt line release call back function
> + * @st_min_limits[3]:	Selftest acceptance minimum values
> + * @st_max_limits[3]:	Selftest acceptance maximum values
> + * @irq2:		Irq line 2 number
> + *
> + * Platform data is used to setup the sensor chip. Meaning of the different
> + * chip features can be found from the data sheet. It is publicly available
> + * at www.st.com web pages. Currently the platform data is used
> + * only for the 8 bit device. The 8 bit device has two wake up / free fall
> + * detection units and click detection unit. There are plenty of ways to
> + * configure the chip which makes is quite hard to explain deeper meaning of
> + * the fields here. Behaviour of the detection blocks varies heavily depending
> + * on the configuration. For example, interrupt detection block can use high
> + * pass filtered data which makes it react to the changes in the acceleration.
> + * Irq_flags can be used to enable interrupt detection on the both edges.
> + * With proper chip configuration this produces interrupt when some trigger
> + * starts and when it goes away.
> + */
> +
>   struct lis3lv02d_platform_data {
>   	/* please note: the 'click' feature is only supported for
>   	 * LIS[32]02DL variants of the chip and will be ignored for


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 12/12] hwmon: lis3: Release resources is case of failure
@ 2010-10-24 14:59     ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:59 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> If lis3lv02d_init_device fails, HW resources were not released
> properly. In case of failure call release_resources if available.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>
> ---
>   drivers/hwmon/lis3lv02d_i2c.c |    5 +++++
>   1 files changed, 5 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
> index 61c109b..94d5bde 100644
> --- a/drivers/hwmon/lis3lv02d_i2c.c
> +++ b/drivers/hwmon/lis3lv02d_i2c.c
> @@ -161,7 +161,12 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>
>   	if (lis3_dev.reg_ctrl)
>   		lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF);
> +
> +	if (ret == 0)
> +		return 0;
>   fail:
> +	if (pdata&&  pdata->release_resources)
> +		pdata->release_resources();
>   	return ret;
>   }
>


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 12/12] hwmon: lis3: Release resources is case of failure
@ 2010-10-24 14:59     ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:59 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali-PUYAD+kWke1g9hUCZPvPmw,
	guenter.roeck-IzeFyvvaP7pWk0Htik3J/w,
	jic23-KWPb1pKIrIJaa/9Udqfwiw, lm-sensors-GZX6beZjE8VD60Wz+7aTrA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Op 22-10-10 13:57, Samu Onkalo schreef:
> If lis3lv02d_init_device fails, HW resources were not released
> properly. In case of failure call release_resources if available.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
Acked-by: Eric Piel <eric.piel-VkQ1JFuSMpfAbQlEx87xDw@public.gmane.org>
> ---
>   drivers/hwmon/lis3lv02d_i2c.c |    5 +++++
>   1 files changed, 5 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
> index 61c109b..94d5bde 100644
> --- a/drivers/hwmon/lis3lv02d_i2c.c
> +++ b/drivers/hwmon/lis3lv02d_i2c.c
> @@ -161,7 +161,12 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>
>   	if (lis3_dev.reg_ctrl)
>   		lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF);
> +
> +	if (ret == 0)
> +		return 0;
>   fail:
> +	if (pdata&&  pdata->release_resources)
> +		pdata->release_resources();
>   	return ret;
>   }
>

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 12/12] hwmon: lis3: Release resources is
@ 2010-10-24 14:59     ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:59 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> If lis3lv02d_init_device fails, HW resources were not released
> properly. In case of failure call release_resources if available.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
Acked-by: Eric Piel <eric.piel@tremplin-utc.net>
> ---
>   drivers/hwmon/lis3lv02d_i2c.c |    5 +++++
>   1 files changed, 5 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
> index 61c109b..94d5bde 100644
> --- a/drivers/hwmon/lis3lv02d_i2c.c
> +++ b/drivers/hwmon/lis3lv02d_i2c.c
> @@ -161,7 +161,12 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>
>   	if (lis3_dev.reg_ctrl)
>   		lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF);
> +
> +	if (ret = 0)
> +		return 0;
>   fail:
> +	if (pdata&&  pdata->release_resources)
> +		pdata->release_resources();
>   	return ret;
>   }
>


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 02/12] hwmon: lis3: regulator control
  2010-10-22 11:57   ` Samu Onkalo
@ 2010-10-24 14:59     ` Éric Piel
  -1 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:59 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> Based on pm_runtime control, turn lis3 regulators on and off.
> Perform context save and restore on transitions.
>
> Feature is optional and must be enabled in platform data.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
I have very little knowledge about regulators, but for what I could 
understand it looks fine...

Acked-by: Eric Piel <eric.piel@tremplin-utc.net>

> ---
>   drivers/hwmon/lis3lv02d.c     |   52 ++++++++++++++++++++++++++++++++++++++
>   drivers/hwmon/lis3lv02d.h     |   12 +++++++++
>   drivers/hwmon/lis3lv02d_i2c.c |   55 ++++++++++++++++++++++++++++++++++++++++-
>   include/linux/lis3lv02d.h     |    2 +
>   4 files changed, 120 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index 412ddc3..ade6f3a 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -31,6 +31,7 @@
>   #include<linux/delay.h>
>   #include<linux/wait.h>
>   #include<linux/poll.h>
> +#include<linux/slab.h>
>   #include<linux/freezer.h>
>   #include<linux/uaccess.h>
>   #include<linux/miscdevice.h>
> @@ -223,10 +224,46 @@ fail:
>   	return ret;
>   }
>
> +/*
> + * Order of registers in the list affects to order of the restore process.
> + * Perhaps it is a good idea to set interrupt enable register as a last one
> + * after all other configurations
> + */
> +static u8 lis3_wai8_regs[] = { FF_WU_CFG_1, FF_WU_THS_1, FF_WU_DURATION_1,
> +			       FF_WU_CFG_2, FF_WU_THS_2, FF_WU_DURATION_2,
> +			       CLICK_CFG, CLICK_SRC, CLICK_THSY_X, CLICK_THSZ,
> +			       CLICK_TIMELIMIT, CLICK_LATENCY, CLICK_WINDOW,
> +			       CTRL_REG1, CTRL_REG2, CTRL_REG3};
> +
> +static u8 lis3_wai12_regs[] = {FF_WU_CFG, FF_WU_THS_L, FF_WU_THS_H,
> +			       FF_WU_DURATION, DD_CFG, DD_THSI_L, DD_THSI_H,
> +			       DD_THSE_L, DD_THSE_H,
> +			       CTRL_REG1, CTRL_REG3, CTRL_REG2};
> +
> +static inline void lis3_context_save(struct lis3lv02d *lis3)
> +{
> +	int i;
> +	for (i = 0; i<  lis3->regs_size; i++)
> +		lis3->read(lis3, lis3->regs[i],&lis3->reg_cache[i]);
> +	lis3->regs_stored = true;
> +}
> +
> +static inline void lis3_context_restore(struct lis3lv02d *lis3)
> +{
> +	int i;
> +	if (lis3->regs_stored)
> +		for (i = 0; i<  lis3->regs_size; i++)
> +			lis3->write(lis3, lis3->regs[i], lis3->reg_cache[i]);
> +}
> +
>   void lis3lv02d_poweroff(struct lis3lv02d *lis3)
>   {
> +	if (lis3->reg_ctrl)
> +		lis3_context_save(lis3);
>   	/* disable X,Y,Z axis and power down */
>   	lis3->write(lis3, CTRL_REG1, 0x00);
> +	if (lis3->reg_ctrl)
> +		lis3->reg_ctrl(lis3, LIS3_REG_OFF);
>   }
>   EXPORT_SYMBOL_GPL(lis3lv02d_poweroff);
>
> @@ -249,6 +286,8 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3)
>   		reg |= CTRL2_BDU;
>   		lis3->write(lis3, CTRL_REG2, reg);
>   	}
> +	if (lis3->reg_ctrl)
> +		lis3_context_restore(lis3);
>   }
>   EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
>
> @@ -640,6 +679,7 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
>   		pm_runtime_disable(lis3->pm_dev);
>   		pm_runtime_set_suspended(lis3->pm_dev);
>   	}
> +	kfree(lis3->reg_cache);
>   	return 0;
>   }
>   EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
> @@ -719,6 +759,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   		dev->odrs = lis3_12_rates;
>   		dev->odr_mask = CTRL1_DF0 | CTRL1_DF1;
>   		dev->scale = LIS3_SENSITIVITY_12B;
> +		dev->regs = lis3_wai12_regs;
> +		dev->regs_size = ARRAY_SIZE(lis3_wai12_regs);
>   		break;
>   	case WAI_8B:
>   		printk(KERN_INFO DRIVER_NAME ": 8 bits sensor found\n");
> @@ -728,6 +770,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   		dev->odrs = lis3_8_rates;
>   		dev->odr_mask = CTRL1_DR;
>   		dev->scale = LIS3_SENSITIVITY_8B;
> +		dev->regs = lis3_wai8_regs;
> +		dev->regs_size = ARRAY_SIZE(lis3_wai8_regs);
>   		break;
>   	default:
>   		printk(KERN_ERR DRIVER_NAME
> @@ -735,6 +779,14 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   		return -EINVAL;
>   	}
>
> +	dev->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs),
> +				     sizeof(lis3_wai12_regs)), GFP_KERNEL);
> +
> +	if (dev->reg_cache == NULL) {
> +		printk(KERN_ERR DRIVER_NAME "out of memory\n");
> +		return -ENOMEM;
> +	}
> +
>   	mutex_init(&dev->mutex);
>
>   	lis3lv02d_add_fs(dev);
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 3e8a208..7661e59 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -20,6 +20,7 @@
>    */
>   #include<linux/platform_device.h>
>   #include<linux/input-polldev.h>
> +#include<linux/regulator/consumer.h>
>
>   /*
>    * This driver tries to support the "digital" accelerometer chips from
> @@ -206,6 +207,11 @@ enum lis3lv02d_click_src_8b {
>   	CLICK_IA	= 0x40,
>   };
>
> +enum lis3lv02d_reg_state {
> +	LIS3_REG_OFF	= 0x00,
> +	LIS3_REG_ON	= 0x01,
> +};
> +
>   struct axis_conversion {
>   	s8	x;
>   	s8	y;
> @@ -218,8 +224,13 @@ struct lis3lv02d {
>   	int (*init) (struct lis3lv02d *lis3);
>   	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
>   	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
> +	int (*reg_ctrl) (struct lis3lv02d *lis3, bool state);
>
>   	int                     *odrs;     /* Supported output data rates */
> +	u8			*regs;	   /* Regs to store / restore */
> +	int			regs_size;
> +	u8                      *reg_cache;
> +	bool			regs_stored;
>   	u8                      odr_mask;  /* ODR bit mask */
>   	u8			whoami;    /* indicates measurement precision */
>   	s16 (*read_data) (struct lis3lv02d *lis3, int reg);
> @@ -232,6 +243,7 @@ struct lis3lv02d {
>
>   	struct input_polled_dev	*idev;     /* input device */
>   	struct platform_device	*pdev;     /* platform device */
> +	struct regulator_bulk_data regulators[2];
>   	atomic_t		count;     /* interrupt count after last read */
>   	struct axis_conversion	ac;        /* hw ->  logical axis */
>   	int			mapped_btns[3];
> diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
> index 6e965d7..98983cc 100644
> --- a/drivers/hwmon/lis3lv02d_i2c.c
> +++ b/drivers/hwmon/lis3lv02d_i2c.c
> @@ -30,10 +30,29 @@
>   #include<linux/err.h>
>   #include<linux/i2c.h>
>   #include<linux/pm_runtime.h>
> +#include<linux/delay.h>
>   #include "lis3lv02d.h"
>
>   #define DRV_NAME 	"lis3lv02d_i2c"
>
> +static const char reg_vdd[]    = "Vdd";
> +static const char reg_vdd_io[] = "Vdd_IO";
> +
> +static int lis3_reg_ctrl(struct lis3lv02d *lis3, bool state)
> +{
> +	int ret;
> +	if (state == LIS3_REG_OFF) {
> +		ret = regulator_bulk_disable(ARRAY_SIZE(lis3->regulators),
> +					lis3->regulators);
> +	} else {
> +		ret = regulator_bulk_enable(ARRAY_SIZE(lis3->regulators),
> +					lis3->regulators);
> +		/* Chip needs time to wakeup. Not mentioned in datasheet */
> +		usleep_range(10000, 20000);
> +	}
> +	return ret;
> +}
> +
>   static inline s32 lis3_i2c_write(struct lis3lv02d *lis3, int reg, u8 value)
>   {
>   	struct i2c_client *c = lis3->bus_priv;
> @@ -52,6 +71,13 @@ static int lis3_i2c_init(struct lis3lv02d *lis3)
>   	u8 reg;
>   	int ret;
>
> +	if (lis3->reg_ctrl)
> +		lis3_reg_ctrl(lis3, LIS3_REG_ON);
> +
> +	lis3->read(lis3, WHO_AM_I,&reg);
> +	if (reg != lis3->whoami)
> +		printk(KERN_ERR "lis3: power on failure\n");
> +
>   	/* power up the device */
>   	ret = lis3->read(lis3, CTRL_REG1,&reg);
>   	if (ret<  0)
> @@ -73,6 +99,10 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>   	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
>
>   	if (pdata) {
> +		/* Regulator control is optional */
> +		if (pdata->driver_features&  LIS3_USE_REGULATOR_CTRL)
> +			lis3_dev.reg_ctrl = lis3_reg_ctrl;
> +
>   		if (pdata->axis_x)
>   			lis3lv02d_axis_map.x = pdata->axis_x;
>
> @@ -89,6 +119,16 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>   			goto fail;
>   	}
>
> +	if (lis3_dev.reg_ctrl) {
> +		lis3_dev.regulators[0].supply = reg_vdd;
> +		lis3_dev.regulators[1].supply = reg_vdd_io;
> +		ret = regulator_bulk_get(&client->dev,
> +					ARRAY_SIZE(lis3_dev.regulators),
> +					lis3_dev.regulators);
> +		if (ret<  0)
> +			goto fail;
> +	}
> +
>   	lis3_dev.pdata	  = pdata;
>   	lis3_dev.bus_priv = client;
>   	lis3_dev.init	  = lis3_i2c_init;
> @@ -99,21 +139,34 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>   	lis3_dev.pm_dev	  =&client->dev;
>
>   	i2c_set_clientdata(client,&lis3_dev);
> +
> +	/* Provide power over the init call */
> +	if (lis3_dev.reg_ctrl)
> +		lis3_reg_ctrl(&lis3_dev, LIS3_REG_ON);
> +
>   	ret = lis3lv02d_init_device(&lis3_dev);
> +
> +	if (lis3_dev.reg_ctrl)
> +		lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF);
>   fail:
>   	return ret;
>   }
>
>   static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
>   {
> +	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>   	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
>
>   	if (pdata&&  pdata->release_resources)
>   		pdata->release_resources();
>
>   	lis3lv02d_joystick_disable();
> +	lis3lv02d_remove_fs(&lis3_dev);
>
> -	return lis3lv02d_remove_fs(&lis3_dev);
> +	if (lis3_dev.reg_ctrl)
> +		regulator_bulk_free(ARRAY_SIZE(lis3->regulators),
> +				lis3_dev.regulators);
> +	return 0;
>   }
>
>   #ifdef CONFIG_PM
> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
> index 0e8a346..c4a4a52 100644
> --- a/include/linux/lis3lv02d.h
> +++ b/include/linux/lis3lv02d.h
> @@ -64,6 +64,8 @@ struct lis3lv02d_platform_data {
>   	s8 axis_x;
>   	s8 axis_y;
>   	s8 axis_z;
> +#define LIS3_USE_REGULATOR_CTRL 0x01
> +	u16 driver_features;
>   	int (*setup_resources)(void);
>   	int (*release_resources)(void);
>   	/* Limits for selftest are specified in chip data sheet */


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 02/12] hwmon: lis3: regulator control
@ 2010-10-24 14:59     ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 14:59 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> Based on pm_runtime control, turn lis3 regulators on and off.
> Perform context save and restore on transitions.
>
> Feature is optional and must be enabled in platform data.
>
> Signed-off-by: Samu Onkalo<samu.p.onkalo@nokia.com>
I have very little knowledge about regulators, but for what I could 
understand it looks fine...

Acked-by: Eric Piel <eric.piel@tremplin-utc.net>

> ---
>   drivers/hwmon/lis3lv02d.c     |   52 ++++++++++++++++++++++++++++++++++++++
>   drivers/hwmon/lis3lv02d.h     |   12 +++++++++
>   drivers/hwmon/lis3lv02d_i2c.c |   55 ++++++++++++++++++++++++++++++++++++++++-
>   include/linux/lis3lv02d.h     |    2 +
>   4 files changed, 120 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
> index 412ddc3..ade6f3a 100644
> --- a/drivers/hwmon/lis3lv02d.c
> +++ b/drivers/hwmon/lis3lv02d.c
> @@ -31,6 +31,7 @@
>   #include<linux/delay.h>
>   #include<linux/wait.h>
>   #include<linux/poll.h>
> +#include<linux/slab.h>
>   #include<linux/freezer.h>
>   #include<linux/uaccess.h>
>   #include<linux/miscdevice.h>
> @@ -223,10 +224,46 @@ fail:
>   	return ret;
>   }
>
> +/*
> + * Order of registers in the list affects to order of the restore process.
> + * Perhaps it is a good idea to set interrupt enable register as a last one
> + * after all other configurations
> + */
> +static u8 lis3_wai8_regs[] = { FF_WU_CFG_1, FF_WU_THS_1, FF_WU_DURATION_1,
> +			       FF_WU_CFG_2, FF_WU_THS_2, FF_WU_DURATION_2,
> +			       CLICK_CFG, CLICK_SRC, CLICK_THSY_X, CLICK_THSZ,
> +			       CLICK_TIMELIMIT, CLICK_LATENCY, CLICK_WINDOW,
> +			       CTRL_REG1, CTRL_REG2, CTRL_REG3};
> +
> +static u8 lis3_wai12_regs[] = {FF_WU_CFG, FF_WU_THS_L, FF_WU_THS_H,
> +			       FF_WU_DURATION, DD_CFG, DD_THSI_L, DD_THSI_H,
> +			       DD_THSE_L, DD_THSE_H,
> +			       CTRL_REG1, CTRL_REG3, CTRL_REG2};
> +
> +static inline void lis3_context_save(struct lis3lv02d *lis3)
> +{
> +	int i;
> +	for (i = 0; i<  lis3->regs_size; i++)
> +		lis3->read(lis3, lis3->regs[i],&lis3->reg_cache[i]);
> +	lis3->regs_stored = true;
> +}
> +
> +static inline void lis3_context_restore(struct lis3lv02d *lis3)
> +{
> +	int i;
> +	if (lis3->regs_stored)
> +		for (i = 0; i<  lis3->regs_size; i++)
> +			lis3->write(lis3, lis3->regs[i], lis3->reg_cache[i]);
> +}
> +
>   void lis3lv02d_poweroff(struct lis3lv02d *lis3)
>   {
> +	if (lis3->reg_ctrl)
> +		lis3_context_save(lis3);
>   	/* disable X,Y,Z axis and power down */
>   	lis3->write(lis3, CTRL_REG1, 0x00);
> +	if (lis3->reg_ctrl)
> +		lis3->reg_ctrl(lis3, LIS3_REG_OFF);
>   }
>   EXPORT_SYMBOL_GPL(lis3lv02d_poweroff);
>
> @@ -249,6 +286,8 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3)
>   		reg |= CTRL2_BDU;
>   		lis3->write(lis3, CTRL_REG2, reg);
>   	}
> +	if (lis3->reg_ctrl)
> +		lis3_context_restore(lis3);
>   }
>   EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
>
> @@ -640,6 +679,7 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3)
>   		pm_runtime_disable(lis3->pm_dev);
>   		pm_runtime_set_suspended(lis3->pm_dev);
>   	}
> +	kfree(lis3->reg_cache);
>   	return 0;
>   }
>   EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
> @@ -719,6 +759,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   		dev->odrs = lis3_12_rates;
>   		dev->odr_mask = CTRL1_DF0 | CTRL1_DF1;
>   		dev->scale = LIS3_SENSITIVITY_12B;
> +		dev->regs = lis3_wai12_regs;
> +		dev->regs_size = ARRAY_SIZE(lis3_wai12_regs);
>   		break;
>   	case WAI_8B:
>   		printk(KERN_INFO DRIVER_NAME ": 8 bits sensor found\n");
> @@ -728,6 +770,8 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   		dev->odrs = lis3_8_rates;
>   		dev->odr_mask = CTRL1_DR;
>   		dev->scale = LIS3_SENSITIVITY_8B;
> +		dev->regs = lis3_wai8_regs;
> +		dev->regs_size = ARRAY_SIZE(lis3_wai8_regs);
>   		break;
>   	default:
>   		printk(KERN_ERR DRIVER_NAME
> @@ -735,6 +779,14 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
>   		return -EINVAL;
>   	}
>
> +	dev->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs),
> +				     sizeof(lis3_wai12_regs)), GFP_KERNEL);
> +
> +	if (dev->reg_cache = NULL) {
> +		printk(KERN_ERR DRIVER_NAME "out of memory\n");
> +		return -ENOMEM;
> +	}
> +
>   	mutex_init(&dev->mutex);
>
>   	lis3lv02d_add_fs(dev);
> diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
> index 3e8a208..7661e59 100644
> --- a/drivers/hwmon/lis3lv02d.h
> +++ b/drivers/hwmon/lis3lv02d.h
> @@ -20,6 +20,7 @@
>    */
>   #include<linux/platform_device.h>
>   #include<linux/input-polldev.h>
> +#include<linux/regulator/consumer.h>
>
>   /*
>    * This driver tries to support the "digital" accelerometer chips from
> @@ -206,6 +207,11 @@ enum lis3lv02d_click_src_8b {
>   	CLICK_IA	= 0x40,
>   };
>
> +enum lis3lv02d_reg_state {
> +	LIS3_REG_OFF	= 0x00,
> +	LIS3_REG_ON	= 0x01,
> +};
> +
>   struct axis_conversion {
>   	s8	x;
>   	s8	y;
> @@ -218,8 +224,13 @@ struct lis3lv02d {
>   	int (*init) (struct lis3lv02d *lis3);
>   	int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
>   	int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
> +	int (*reg_ctrl) (struct lis3lv02d *lis3, bool state);
>
>   	int                     *odrs;     /* Supported output data rates */
> +	u8			*regs;	   /* Regs to store / restore */
> +	int			regs_size;
> +	u8                      *reg_cache;
> +	bool			regs_stored;
>   	u8                      odr_mask;  /* ODR bit mask */
>   	u8			whoami;    /* indicates measurement precision */
>   	s16 (*read_data) (struct lis3lv02d *lis3, int reg);
> @@ -232,6 +243,7 @@ struct lis3lv02d {
>
>   	struct input_polled_dev	*idev;     /* input device */
>   	struct platform_device	*pdev;     /* platform device */
> +	struct regulator_bulk_data regulators[2];
>   	atomic_t		count;     /* interrupt count after last read */
>   	struct axis_conversion	ac;        /* hw ->  logical axis */
>   	int			mapped_btns[3];
> diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
> index 6e965d7..98983cc 100644
> --- a/drivers/hwmon/lis3lv02d_i2c.c
> +++ b/drivers/hwmon/lis3lv02d_i2c.c
> @@ -30,10 +30,29 @@
>   #include<linux/err.h>
>   #include<linux/i2c.h>
>   #include<linux/pm_runtime.h>
> +#include<linux/delay.h>
>   #include "lis3lv02d.h"
>
>   #define DRV_NAME 	"lis3lv02d_i2c"
>
> +static const char reg_vdd[]    = "Vdd";
> +static const char reg_vdd_io[] = "Vdd_IO";
> +
> +static int lis3_reg_ctrl(struct lis3lv02d *lis3, bool state)
> +{
> +	int ret;
> +	if (state = LIS3_REG_OFF) {
> +		ret = regulator_bulk_disable(ARRAY_SIZE(lis3->regulators),
> +					lis3->regulators);
> +	} else {
> +		ret = regulator_bulk_enable(ARRAY_SIZE(lis3->regulators),
> +					lis3->regulators);
> +		/* Chip needs time to wakeup. Not mentioned in datasheet */
> +		usleep_range(10000, 20000);
> +	}
> +	return ret;
> +}
> +
>   static inline s32 lis3_i2c_write(struct lis3lv02d *lis3, int reg, u8 value)
>   {
>   	struct i2c_client *c = lis3->bus_priv;
> @@ -52,6 +71,13 @@ static int lis3_i2c_init(struct lis3lv02d *lis3)
>   	u8 reg;
>   	int ret;
>
> +	if (lis3->reg_ctrl)
> +		lis3_reg_ctrl(lis3, LIS3_REG_ON);
> +
> +	lis3->read(lis3, WHO_AM_I,&reg);
> +	if (reg != lis3->whoami)
> +		printk(KERN_ERR "lis3: power on failure\n");
> +
>   	/* power up the device */
>   	ret = lis3->read(lis3, CTRL_REG1,&reg);
>   	if (ret<  0)
> @@ -73,6 +99,10 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>   	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
>
>   	if (pdata) {
> +		/* Regulator control is optional */
> +		if (pdata->driver_features&  LIS3_USE_REGULATOR_CTRL)
> +			lis3_dev.reg_ctrl = lis3_reg_ctrl;
> +
>   		if (pdata->axis_x)
>   			lis3lv02d_axis_map.x = pdata->axis_x;
>
> @@ -89,6 +119,16 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>   			goto fail;
>   	}
>
> +	if (lis3_dev.reg_ctrl) {
> +		lis3_dev.regulators[0].supply = reg_vdd;
> +		lis3_dev.regulators[1].supply = reg_vdd_io;
> +		ret = regulator_bulk_get(&client->dev,
> +					ARRAY_SIZE(lis3_dev.regulators),
> +					lis3_dev.regulators);
> +		if (ret<  0)
> +			goto fail;
> +	}
> +
>   	lis3_dev.pdata	  = pdata;
>   	lis3_dev.bus_priv = client;
>   	lis3_dev.init	  = lis3_i2c_init;
> @@ -99,21 +139,34 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
>   	lis3_dev.pm_dev	  =&client->dev;
>
>   	i2c_set_clientdata(client,&lis3_dev);
> +
> +	/* Provide power over the init call */
> +	if (lis3_dev.reg_ctrl)
> +		lis3_reg_ctrl(&lis3_dev, LIS3_REG_ON);
> +
>   	ret = lis3lv02d_init_device(&lis3_dev);
> +
> +	if (lis3_dev.reg_ctrl)
> +		lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF);
>   fail:
>   	return ret;
>   }
>
>   static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client)
>   {
> +	struct lis3lv02d *lis3 = i2c_get_clientdata(client);
>   	struct lis3lv02d_platform_data *pdata = client->dev.platform_data;
>
>   	if (pdata&&  pdata->release_resources)
>   		pdata->release_resources();
>
>   	lis3lv02d_joystick_disable();
> +	lis3lv02d_remove_fs(&lis3_dev);
>
> -	return lis3lv02d_remove_fs(&lis3_dev);
> +	if (lis3_dev.reg_ctrl)
> +		regulator_bulk_free(ARRAY_SIZE(lis3->regulators),
> +				lis3_dev.regulators);
> +	return 0;
>   }
>
>   #ifdef CONFIG_PM
> diff --git a/include/linux/lis3lv02d.h b/include/linux/lis3lv02d.h
> index 0e8a346..c4a4a52 100644
> --- a/include/linux/lis3lv02d.h
> +++ b/include/linux/lis3lv02d.h
> @@ -64,6 +64,8 @@ struct lis3lv02d_platform_data {
>   	s8 axis_x;
>   	s8 axis_y;
>   	s8 axis_z;
> +#define LIS3_USE_REGULATOR_CTRL 0x01
> +	u16 driver_features;
>   	int (*setup_resources)(void);
>   	int (*release_resources)(void);
>   	/* Limits for selftest are specified in chip data sheet */


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-24 15:05   ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 15:05 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> Changes are tested only with I2C interface using 8bit sensor since I don't
> have other possibilities. Some features are not enabled
> by default since I can't test them with all possible configurations.
> Platform data contains field which controls new features.
Thanks Samu for persevering with the automatic power down feature. 
Hopefully I'll find also some time to activate it on the hp_accel side.

For now, I've reviewed the changes and everything looked fine, as well 
as tested them on my HP laptop (with a 12 bits sensor). Although most of 
the changes are not visible on this platform, at least there shouldn't 
be any regression.

Thanks,
Eric

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-24 15:05   ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 15:05 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali-PUYAD+kWke1g9hUCZPvPmw,
	guenter.roeck-IzeFyvvaP7pWk0Htik3J/w,
	jic23-KWPb1pKIrIJaa/9Udqfwiw, lm-sensors-GZX6beZjE8VD60Wz+7aTrA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Op 22-10-10 13:57, Samu Onkalo schreef:
> Changes are tested only with I2C interface using 8bit sensor since I don't
> have other possibilities. Some features are not enabled
> by default since I can't test them with all possible configurations.
> Platform data contains field which controls new features.
Thanks Samu for persevering with the automatic power down feature. 
Hopefully I'll find also some time to activate it on the hp_accel side.

For now, I've reviewed the changes and everything looked fine, as well 
as tested them on my HP laptop (with a 12 bits sensor). Although most of 
the changes are not visible on this platform, at least there shouldn't 
be any regression.

Thanks,
Eric

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-24 15:05   ` Éric Piel
  0 siblings, 0 replies; 101+ messages in thread
From: Éric Piel @ 2010-10-24 15:05 UTC (permalink / raw)
  To: Samu Onkalo
  Cc: khali, guenter.roeck, jic23, lm-sensors, linux-i2c, linux-kernel

Op 22-10-10 13:57, Samu Onkalo schreef:
> Changes are tested only with I2C interface using 8bit sensor since I don't
> have other possibilities. Some features are not enabled
> by default since I can't test them with all possible configurations.
> Platform data contains field which controls new features.
Thanks Samu for persevering with the automatic power down feature. 
Hopefully I'll find also some time to activate it on the hp_accel side.

For now, I've reviewed the changes and everything looked fine, as well 
as tested them on my HP laptop (with a 12 bits sensor). Although most of 
the changes are not visible on this platform, at least there shouldn't 
be any regression.

Thanks,
Eric

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-24 15:35     ` Guenter Roeck
  0 siblings, 0 replies; 101+ messages in thread
From: Guenter Roeck @ 2010-10-24 15:35 UTC (permalink / raw)
  To: Éric Piel
  Cc: Samu Onkalo, khali, jic23, lm-sensors, linux-i2c, linux-kernel

On Sun, Oct 24, 2010 at 11:05:33AM -0400, Éric Piel wrote:
> Op 22-10-10 13:57, Samu Onkalo schreef:
> > Changes are tested only with I2C interface using 8bit sensor since I don't
> > have other possibilities. Some features are not enabled
> > by default since I can't test them with all possible configurations.
> > Platform data contains field which controls new features.
> Thanks Samu for persevering with the automatic power down feature. 
> Hopefully I'll find also some time to activate it on the hp_accel side.
> 
> For now, I've reviewed the changes and everything looked fine, as well 
> as tested them on my HP laptop (with a 12 bits sensor). Although most of 
> the changes are not visible on this platform, at least there shouldn't 
> be any regression.
> 
Great, thanks.

Unfortunately, the patches don't apply to my staging branch, probably
because of the other pending lis3 changes.

Samu, please rebase your patches to 
	git://git.kernel.org/pub/scm/linux/kernel/git/groeck/staging.git hwmon-next
and resubmit.

Thanks,
Guenter

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-24 15:35     ` Guenter Roeck
  0 siblings, 0 replies; 101+ messages in thread
From: Guenter Roeck @ 2010-10-24 15:35 UTC (permalink / raw)
  To: Éric Piel
  Cc: Samu Onkalo, khali-PUYAD+kWke1g9hUCZPvPmw,
	jic23-KWPb1pKIrIJaa/9Udqfwiw, lm-sensors-GZX6beZjE8VD60Wz+7aTrA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Sun, Oct 24, 2010 at 11:05:33AM -0400, Éric Piel wrote:
> Op 22-10-10 13:57, Samu Onkalo schreef:
> > Changes are tested only with I2C interface using 8bit sensor since I don't
> > have other possibilities. Some features are not enabled
> > by default since I can't test them with all possible configurations.
> > Platform data contains field which controls new features.
> Thanks Samu for persevering with the automatic power down feature. 
> Hopefully I'll find also some time to activate it on the hp_accel side.
> 
> For now, I've reviewed the changes and everything looked fine, as well 
> as tested them on my HP laptop (with a 12 bits sensor). Although most of 
> the changes are not visible on this platform, at least there shouldn't 
> be any regression.
> 
Great, thanks.

Unfortunately, the patches don't apply to my staging branch, probably
because of the other pending lis3 changes.

Samu, please rebase your patches to 
	git://git.kernel.org/pub/scm/linux/kernel/git/groeck/staging.git hwmon-next
and resubmit.

Thanks,
Guenter

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-24 15:35     ` Guenter Roeck
  0 siblings, 0 replies; 101+ messages in thread
From: Guenter Roeck @ 2010-10-24 15:35 UTC (permalink / raw)
  To: Éric Piel
  Cc: Samu Onkalo, khali, jic23, lm-sensors, linux-i2c, linux-kernel

On Sun, Oct 24, 2010 at 11:05:33AM -0400, Éric Piel wrote:
> Op 22-10-10 13:57, Samu Onkalo schreef:
> > Changes are tested only with I2C interface using 8bit sensor since I don't
> > have other possibilities. Some features are not enabled
> > by default since I can't test them with all possible configurations.
> > Platform data contains field which controls new features.
> Thanks Samu for persevering with the automatic power down feature. 
> Hopefully I'll find also some time to activate it on the hp_accel side.
> 
> For now, I've reviewed the changes and everything looked fine, as well 
> as tested them on my HP laptop (with a 12 bits sensor). Although most of 
> the changes are not visible on this platform, at least there shouldn't 
> be any regression.
> 
Great, thanks.

Unfortunately, the patches don't apply to my staging branch, probably
because of the other pending lis3 changes.

Samu, please rebase your patches to 
	git://git.kernel.org/pub/scm/linux/kernel/git/groeck/staging.git hwmon-next
and resubmit.

Thanks,
Guenter

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-24 16:35       ` Guenter Roeck
  0 siblings, 0 replies; 101+ messages in thread
From: Guenter Roeck @ 2010-10-24 16:35 UTC (permalink / raw)
  To: Éric Piel; +Cc: linux-kernel, lm-sensors, linux-i2c

On Sun, Oct 24, 2010 at 11:35:48AM -0400, Guenter Roeck wrote:
> On Sun, Oct 24, 2010 at 11:05:33AM -0400, Éric Piel wrote:
> > Op 22-10-10 13:57, Samu Onkalo schreef:
> > > Changes are tested only with I2C interface using 8bit sensor since I don't
> > > have other possibilities. Some features are not enabled
> > > by default since I can't test them with all possible configurations.
> > > Platform data contains field which controls new features.
> > Thanks Samu for persevering with the automatic power down feature. 
> > Hopefully I'll find also some time to activate it on the hp_accel side.
> > 
> > For now, I've reviewed the changes and everything looked fine, as well 
> > as tested them on my HP laptop (with a 12 bits sensor). Although most of 
> > the changes are not visible on this platform, at least there shouldn't 
> > be any regression.
> > 
> Great, thanks.
> 
> Unfortunately, the patches don't apply to my staging branch, probably
> because of the other pending lis3 changes.
> 
> Samu, please rebase your patches to 
> 	git://git.kernel.org/pub/scm/linux/kernel/git/groeck/staging.git hwmon-next
> and resubmit.
> 
Never mind. Played a bit with git, learned something new, and got it all merged.
Now compiling.

Eric, once I pushed the changes into above branch (hopefully by tonight),
would be great if you could give it another test run.

Thanks,
Guenter

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-24 16:35       ` Guenter Roeck
  0 siblings, 0 replies; 101+ messages in thread
From: Guenter Roeck @ 2010-10-24 16:35 UTC (permalink / raw)
  To: Éric Piel
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	lm-sensors-GZX6beZjE8VD60Wz+7aTrA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA

On Sun, Oct 24, 2010 at 11:35:48AM -0400, Guenter Roeck wrote:
> On Sun, Oct 24, 2010 at 11:05:33AM -0400, Éric Piel wrote:
> > Op 22-10-10 13:57, Samu Onkalo schreef:
> > > Changes are tested only with I2C interface using 8bit sensor since I don't
> > > have other possibilities. Some features are not enabled
> > > by default since I can't test them with all possible configurations.
> > > Platform data contains field which controls new features.
> > Thanks Samu for persevering with the automatic power down feature. 
> > Hopefully I'll find also some time to activate it on the hp_accel side.
> > 
> > For now, I've reviewed the changes and everything looked fine, as well 
> > as tested them on my HP laptop (with a 12 bits sensor). Although most of 
> > the changes are not visible on this platform, at least there shouldn't 
> > be any regression.
> > 
> Great, thanks.
> 
> Unfortunately, the patches don't apply to my staging branch, probably
> because of the other pending lis3 changes.
> 
> Samu, please rebase your patches to 
> 	git://git.kernel.org/pub/scm/linux/kernel/git/groeck/staging.git hwmon-next
> and resubmit.
> 
Never mind. Played a bit with git, learned something new, and got it all merged.
Now compiling.

Eric, once I pushed the changes into above branch (hopefully by tonight),
would be great if you could give it another test run.

Thanks,
Guenter

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-24 16:35       ` Guenter Roeck
  0 siblings, 0 replies; 101+ messages in thread
From: Guenter Roeck @ 2010-10-24 16:35 UTC (permalink / raw)
  To: Éric Piel; +Cc: linux-kernel, lm-sensors, linux-i2c

On Sun, Oct 24, 2010 at 11:35:48AM -0400, Guenter Roeck wrote:
> On Sun, Oct 24, 2010 at 11:05:33AM -0400, Éric Piel wrote:
> > Op 22-10-10 13:57, Samu Onkalo schreef:
> > > Changes are tested only with I2C interface using 8bit sensor since I don't
> > > have other possibilities. Some features are not enabled
> > > by default since I can't test them with all possible configurations.
> > > Platform data contains field which controls new features.
> > Thanks Samu for persevering with the automatic power down feature. 
> > Hopefully I'll find also some time to activate it on the hp_accel side.
> > 
> > For now, I've reviewed the changes and everything looked fine, as well 
> > as tested them on my HP laptop (with a 12 bits sensor). Although most of 
> > the changes are not visible on this platform, at least there shouldn't 
> > be any regression.
> > 
> Great, thanks.
> 
> Unfortunately, the patches don't apply to my staging branch, probably
> because of the other pending lis3 changes.
> 
> Samu, please rebase your patches to 
> 	git://git.kernel.org/pub/scm/linux/kernel/git/groeck/staging.git hwmon-next
> and resubmit.
> 
Never mind. Played a bit with git, learned something new, and got it all merged.
Now compiling.

Eric, once I pushed the changes into above branch (hopefully by tonight),
would be great if you could give it another test run.

Thanks,
Guenter

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-24 17:01         ` Guenter Roeck
  0 siblings, 0 replies; 101+ messages in thread
From: Guenter Roeck @ 2010-10-24 17:01 UTC (permalink / raw)
  To: Éric Piel; +Cc: linux-i2c, linux-kernel, lm-sensors

On Sun, Oct 24, 2010 at 12:35:29PM -0400, Guenter Roeck wrote:
> On Sun, Oct 24, 2010 at 11:35:48AM -0400, Guenter Roeck wrote:
> > On Sun, Oct 24, 2010 at 11:05:33AM -0400, Éric Piel wrote:
> > > Op 22-10-10 13:57, Samu Onkalo schreef:
> > > > Changes are tested only with I2C interface using 8bit sensor since I don't
> > > > have other possibilities. Some features are not enabled
> > > > by default since I can't test them with all possible configurations.
> > > > Platform data contains field which controls new features.
> > > Thanks Samu for persevering with the automatic power down feature. 
> > > Hopefully I'll find also some time to activate it on the hp_accel side.
> > > 
> > > For now, I've reviewed the changes and everything looked fine, as well 
> > > as tested them on my HP laptop (with a 12 bits sensor). Although most of 
> > > the changes are not visible on this platform, at least there shouldn't 
> > > be any regression.
> > > 
> > Great, thanks.
> > 
> > Unfortunately, the patches don't apply to my staging branch, probably
> > because of the other pending lis3 changes.
> > 
> > Samu, please rebase your patches to 
> > 	git://git.kernel.org/pub/scm/linux/kernel/git/groeck/staging.git hwmon-next
> > and resubmit.
> > 
> Never mind. Played a bit with git, learned something new, and got it all merged.
> Now compiling.
> 
> Eric, once I pushed the changes into above branch (hopefully by tonight),
> would be great if you could give it another test run.
> 
Compiled and applied to hwmon-next. I'll let it rest there for a couple of days
before sending it off to Linus. Eric, would be great if you can sanity test
the merged version.

Thanks,
Guenter

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-24 17:01         ` Guenter Roeck
  0 siblings, 0 replies; 101+ messages in thread
From: Guenter Roeck @ 2010-10-24 17:01 UTC (permalink / raw)
  To: Éric Piel
  Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	lm-sensors-GZX6beZjE8VD60Wz+7aTrA

On Sun, Oct 24, 2010 at 12:35:29PM -0400, Guenter Roeck wrote:
> On Sun, Oct 24, 2010 at 11:35:48AM -0400, Guenter Roeck wrote:
> > On Sun, Oct 24, 2010 at 11:05:33AM -0400, Éric Piel wrote:
> > > Op 22-10-10 13:57, Samu Onkalo schreef:
> > > > Changes are tested only with I2C interface using 8bit sensor since I don't
> > > > have other possibilities. Some features are not enabled
> > > > by default since I can't test them with all possible configurations.
> > > > Platform data contains field which controls new features.
> > > Thanks Samu for persevering with the automatic power down feature. 
> > > Hopefully I'll find also some time to activate it on the hp_accel side.
> > > 
> > > For now, I've reviewed the changes and everything looked fine, as well 
> > > as tested them on my HP laptop (with a 12 bits sensor). Although most of 
> > > the changes are not visible on this platform, at least there shouldn't 
> > > be any regression.
> > > 
> > Great, thanks.
> > 
> > Unfortunately, the patches don't apply to my staging branch, probably
> > because of the other pending lis3 changes.
> > 
> > Samu, please rebase your patches to 
> > 	git://git.kernel.org/pub/scm/linux/kernel/git/groeck/staging.git hwmon-next
> > and resubmit.
> > 
> Never mind. Played a bit with git, learned something new, and got it all merged.
> Now compiling.
> 
> Eric, once I pushed the changes into above branch (hopefully by tonight),
> would be great if you could give it another test run.
> 
Compiled and applied to hwmon-next. I'll let it rest there for a couple of days
before sending it off to Linus. Eric, would be great if you can sanity test
the merged version.

Thanks,
Guenter

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-24 17:01         ` Guenter Roeck
  0 siblings, 0 replies; 101+ messages in thread
From: Guenter Roeck @ 2010-10-24 17:01 UTC (permalink / raw)
  To: Éric Piel; +Cc: linux-i2c, linux-kernel, lm-sensors

On Sun, Oct 24, 2010 at 12:35:29PM -0400, Guenter Roeck wrote:
> On Sun, Oct 24, 2010 at 11:35:48AM -0400, Guenter Roeck wrote:
> > On Sun, Oct 24, 2010 at 11:05:33AM -0400, Éric Piel wrote:
> > > Op 22-10-10 13:57, Samu Onkalo schreef:
> > > > Changes are tested only with I2C interface using 8bit sensor since I don't
> > > > have other possibilities. Some features are not enabled
> > > > by default since I can't test them with all possible configurations.
> > > > Platform data contains field which controls new features.
> > > Thanks Samu for persevering with the automatic power down feature. 
> > > Hopefully I'll find also some time to activate it on the hp_accel side.
> > > 
> > > For now, I've reviewed the changes and everything looked fine, as well 
> > > as tested them on my HP laptop (with a 12 bits sensor). Although most of 
> > > the changes are not visible on this platform, at least there shouldn't 
> > > be any regression.
> > > 
> > Great, thanks.
> > 
> > Unfortunately, the patches don't apply to my staging branch, probably
> > because of the other pending lis3 changes.
> > 
> > Samu, please rebase your patches to 
> > 	git://git.kernel.org/pub/scm/linux/kernel/git/groeck/staging.git hwmon-next
> > and resubmit.
> > 
> Never mind. Played a bit with git, learned something new, and got it all merged.
> Now compiling.
> 
> Eric, once I pushed the changes into above branch (hopefully by tonight),
> would be great if you could give it another test run.
> 
Compiled and applied to hwmon-next. I'll let it rest there for a couple of days
before sending it off to Linus. Eric, would be great if you can sanity test
the merged version.

Thanks,
Guenter

_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

* RE: [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-25  6:10     ` samu.p.onkalo-xNZwKgViW5gAvxtiuMwx3w
  0 siblings, 0 replies; 101+ messages in thread
From: samu.p.onkalo @ 2010-10-25  6:10 UTC (permalink / raw)
  To: eric.piel, jic23
  Cc: khali, guenter.roeck, lm-sensors, linux-i2c, linux-kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 1028 bytes --]

>-----Original Message-----
>From: linux-i2c-owner@vger.kernel.org [mailto:linux-i2c-
>owner@vger.kernel.org] On Behalf Of ext Éric Piel
>
>Op 22-10-10 13:57, Samu Onkalo schreef:
>> Changes are tested only with I2C interface using 8bit sensor since I
>don't
>> have other possibilities. Some features are not enabled
>> by default since I can't test them with all possible configurations.
>> Platform data contains field which controls new features.
>Thanks Samu for persevering with the automatic power down feature.
>Hopefully I'll find also some time to activate it on the hp_accel side.
>
>For now, I've reviewed the changes and everything looked fine, as well
>as tested them on my HP laptop (with a 12 bits sensor). Although most of
>the changes are not visible on this platform, at least there shouldn't
>be any regression.
>

Thanks for the review.

-Samu
 
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 101+ messages in thread

* RE: [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-25  6:10     ` samu.p.onkalo-xNZwKgViW5gAvxtiuMwx3w
  0 siblings, 0 replies; 101+ messages in thread
From: samu.p.onkalo-xNZwKgViW5gAvxtiuMwx3w @ 2010-10-25  6:10 UTC (permalink / raw)
  To: eric.piel-VkQ1JFuSMpfAbQlEx87xDw, jic23-KWPb1pKIrIJaa/9Udqfwiw
  Cc: khali-PUYAD+kWke1g9hUCZPvPmw,
	guenter.roeck-IzeFyvvaP7pWk0Htik3J/w,
	lm-sensors-GZX6beZjE8VD60Wz+7aTrA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

>-----Original Message-----
>From: linux-i2c-owner@vger.kernel.org [mailto:linux-i2c-
>owner@vger.kernel.org] On Behalf Of ext Éric Piel
>
>Op 22-10-10 13:57, Samu Onkalo schreef:
>> Changes are tested only with I2C interface using 8bit sensor since I
>don't
>> have other possibilities. Some features are not enabled
>> by default since I can't test them with all possible configurations.
>> Platform data contains field which controls new features.
>Thanks Samu for persevering with the automatic power down feature.
>Hopefully I'll find also some time to activate it on the hp_accel side.
>
>For now, I've reviewed the changes and everything looked fine, as well
>as tested them on my HP laptop (with a 12 bits sensor). Although most of
>the changes are not visible on this platform, at least there shouldn't
>be any regression.
>

Thanks for the review.

-Samu
 

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [lm-sensors] [PATCH 00/12] lis3 accelerator feature update
@ 2010-10-25  6:10     ` samu.p.onkalo-xNZwKgViW5gAvxtiuMwx3w
  0 siblings, 0 replies; 101+ messages in thread
From: samu.p.onkalo @ 2010-10-25  6:10 UTC (permalink / raw)
  To: eric.piel, jic23
  Cc: khali, guenter.roeck, lm-sensors, linux-i2c, linux-kernel

>-----Original Message-----
>From: linux-i2c-owner@vger.kernel.org [mailto:linux-i2c-
>owner@vger.kernel.org] On Behalf Of ext Éric Piel
>
>Op 22-10-10 13:57, Samu Onkalo schreef:
>> Changes are tested only with I2C interface using 8bit sensor since I
>don't
>> have other possibilities. Some features are not enabled
>> by default since I can't test them with all possible configurations.
>> Platform data contains field which controls new features.
>Thanks Samu for persevering with the automatic power down feature.
>Hopefully I'll find also some time to activate it on the hp_accel side.
>
>For now, I've reviewed the changes and everything looked fine, as well
>as tested them on my HP laptop (with a 12 bits sensor). Although most of
>the changes are not visible on this platform, at least there shouldn't
>be any regression.
>

Thanks for the review.

-Samu
 
_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply	[flat|nested] 101+ messages in thread

end of thread, other threads:[~2010-10-25  6:10 UTC | newest]

Thread overview: 101+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-10-22 11:57 [PATCH 00/12] lis3 accelerator feature update Samu Onkalo
2010-10-22 11:57 ` [lm-sensors] " Samu Onkalo
2010-10-22 11:57 ` [PATCH 01/12] hwmon: lis3: pm_runtime support Samu Onkalo
2010-10-22 11:57   ` [lm-sensors] " Samu Onkalo
2010-10-22 11:57   ` Samu Onkalo
2010-10-22 16:13   ` Jonathan Cameron
2010-10-22 16:13     ` [lm-sensors] " Jonathan Cameron
2010-10-22 16:13     ` Jonathan Cameron
2010-10-24 14:03   ` Éric Piel
2010-10-24 14:03     ` [lm-sensors] " Éric Piel
2010-10-24 14:03     ` Éric Piel
2010-10-22 11:57 ` [PATCH 02/12] hwmon: lis3: regulator control Samu Onkalo
2010-10-22 11:57   ` [lm-sensors] " Samu Onkalo
2010-10-22 11:57   ` Samu Onkalo
2010-10-22 16:11   ` Jonathan Cameron
2010-10-22 16:11     ` [lm-sensors] " Jonathan Cameron
2010-10-22 16:11     ` Jonathan Cameron
2010-10-24 14:59   ` Éric Piel
2010-10-24 14:59     ` [lm-sensors] " Éric Piel
2010-10-22 11:57 ` [PATCH 03/12] hwmon: lis3: Cleanup interrupt handling Samu Onkalo
2010-10-22 11:57   ` [lm-sensors] " Samu Onkalo
2010-10-24 14:18   ` Éric Piel
2010-10-24 14:18     ` [lm-sensors] [PATCH 03/12] hwmon: lis3: Cleanup interrupt Éric Piel
2010-10-24 14:18     ` [PATCH 03/12] hwmon: lis3: Cleanup interrupt handling Éric Piel
2010-10-22 11:57 ` [PATCH 04/12] hwmon: lis3: Update coordinates at polled device open Samu Onkalo
2010-10-22 11:57   ` [lm-sensors] [PATCH 04/12] hwmon: lis3: Update coordinates at Samu Onkalo
2010-10-24 14:19   ` [PATCH 04/12] hwmon: lis3: Update coordinates at polled device open Éric Piel
2010-10-24 14:19     ` [lm-sensors] [PATCH 04/12] hwmon: lis3: Update coordinates at Éric Piel
2010-10-22 11:57 ` [PATCH 05/12] hwmon: lis3: Power on corrections Samu Onkalo
2010-10-22 11:57   ` [lm-sensors] " Samu Onkalo
2010-10-22 11:57   ` Samu Onkalo
2010-10-24 14:22   ` Éric Piel
2010-10-24 14:22     ` [lm-sensors] " Éric Piel
2010-10-24 14:22     ` Éric Piel
2010-10-22 11:57 ` [PATCH 06/12] hwmon: lis3: restore axis enabled bits Samu Onkalo
2010-10-22 11:57   ` [lm-sensors] " Samu Onkalo
2010-10-22 11:57   ` Samu Onkalo
2010-10-24 14:24   ` Éric Piel
2010-10-24 14:24     ` [lm-sensors] [PATCH 06/12] hwmon: lis3: restore axis enabled Éric Piel
2010-10-22 11:57 ` [PATCH 07/12] hwmon: lis3: New parameters to platform data Samu Onkalo
2010-10-22 11:57   ` [lm-sensors] [PATCH 07/12] hwmon: lis3: New parameters to platform Samu Onkalo
2010-10-22 16:17   ` [PATCH 07/12] hwmon: lis3: New parameters to platform data Jonathan Cameron
2010-10-22 16:17     ` [lm-sensors] [PATCH 07/12] hwmon: lis3: New parameters to Jonathan Cameron
2010-10-22 16:17     ` [PATCH 07/12] hwmon: lis3: New parameters to platform data Jonathan Cameron
2010-10-24 14:27   ` Éric Piel
2010-10-24 14:27     ` [lm-sensors] [PATCH 07/12] hwmon: lis3: New parameters to Éric Piel
2010-10-24 14:27     ` [PATCH 07/12] hwmon: lis3: New parameters to platform data Éric Piel
2010-10-22 11:57 ` [PATCH 08/12] hwmon: lis3: Adjust fuzziness for 8 bit device Samu Onkalo
2010-10-22 11:57   ` [lm-sensors] [PATCH 08/12] hwmon: lis3: Adjust fuzziness for 8 bit Samu Onkalo
2010-10-24 14:33   ` [PATCH 08/12] hwmon: lis3: Adjust fuzziness for 8 bit device Éric Piel
2010-10-24 14:33     ` [lm-sensors] [PATCH 08/12] hwmon: lis3: Adjust fuzziness for 8 Éric Piel
2010-10-22 11:57 ` [PATCH 09/12] hwmon: lis3: use block read to access data registers Samu Onkalo
2010-10-22 11:57   ` [lm-sensors] [PATCH 09/12] hwmon: lis3: use block read to access Samu Onkalo
2010-10-22 16:20   ` [PATCH 09/12] hwmon: lis3: use block read to access data registers Jonathan Cameron
2010-10-22 16:20     ` [lm-sensors] [PATCH 09/12] hwmon: lis3: use block read to Jonathan Cameron
2010-10-24 14:53   ` [PATCH 09/12] hwmon: lis3: use block read to access data registers Éric Piel
2010-10-24 14:53     ` [lm-sensors] [PATCH 09/12] hwmon: lis3: use block read to Éric Piel
2010-10-22 11:57 ` [PATCH 10/12] hwmon: lis3: Enhance lis3 selftest with IRQ line test Samu Onkalo
2010-10-22 11:57   ` [lm-sensors] [PATCH 10/12] hwmon: lis3: Enhance lis3 selftest with Samu Onkalo
2010-10-24 14:58   ` [PATCH 10/12] hwmon: lis3: Enhance lis3 selftest with IRQ line test Éric Piel
2010-10-24 14:58     ` [lm-sensors] [PATCH 10/12] hwmon: lis3: Enhance lis3 selftest Éric Piel
2010-10-24 14:58     ` [PATCH 10/12] hwmon: lis3: Enhance lis3 selftest with IRQ line test Éric Piel
2010-10-22 11:57 ` [PATCH 11/12] hwmon: lis3: Short explanations of platform data fields Samu Onkalo
2010-10-22 11:57   ` [lm-sensors] [PATCH 11/12] hwmon: lis3: Short explanations of Samu Onkalo
2010-10-22 11:57   ` [PATCH 11/12] hwmon: lis3: Short explanations of platform data fields Samu Onkalo
2010-10-22 16:25   ` Jonathan Cameron
2010-10-22 16:25     ` [lm-sensors] [PATCH 11/12] hwmon: lis3: Short explanations of Jonathan Cameron
2010-10-22 16:25     ` [PATCH 11/12] hwmon: lis3: Short explanations of platform data fields Jonathan Cameron
     [not found]     ` <4CC1BAEE.3030708-KWPb1pKIrIJaa/9Udqfwiw@public.gmane.org>
2010-10-23 13:39       ` [PATCHv2] " Samu Onkalo
2010-10-23 13:39         ` [lm-sensors] [PATCHv2] hwmon: lis3: Short explanations of platform Samu Onkalo
     [not found]         ` <1287841184-4871-1-git-send-email-samu.p.onkalo-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
2010-10-24 14:59           ` [PATCHv2] hwmon: lis3: Short explanations of platform data fields Éric Piel
2010-10-24 14:59             ` [lm-sensors] [PATCHv2] hwmon: lis3: Short explanations of Éric Piel
2010-10-22 11:57 ` [PATCH 12/12] hwmon: lis3: Release resources is case of failure Samu Onkalo
2010-10-22 11:57   ` [lm-sensors] [PATCH 12/12] hwmon: lis3: Release resources is case Samu Onkalo
2010-10-22 11:57   ` [PATCH 12/12] hwmon: lis3: Release resources is case of failure Samu Onkalo
2010-10-24 14:59   ` Éric Piel
2010-10-24 14:59     ` [lm-sensors] [PATCH 12/12] hwmon: lis3: Release resources is Éric Piel
2010-10-24 14:59     ` [PATCH 12/12] hwmon: lis3: Release resources is case of failure Éric Piel
2010-10-22 20:08 ` [PATCH 00/12] lis3 accelerator feature update Guenter Roeck
2010-10-22 20:08   ` [lm-sensors] " Guenter Roeck
2010-10-22 20:08   ` Guenter Roeck
2010-10-22 23:44   ` Éric Piel
2010-10-22 23:44     ` [lm-sensors] " Éric Piel
2010-10-23  1:05     ` Guenter Roeck
2010-10-23  1:05       ` [lm-sensors] " Guenter Roeck
2010-10-23  1:05       ` Guenter Roeck
2010-10-24 15:05 ` Éric Piel
2010-10-24 15:05   ` [lm-sensors] " Éric Piel
2010-10-24 15:05   ` Éric Piel
2010-10-24 15:35   ` Guenter Roeck
2010-10-24 15:35     ` [lm-sensors] " Guenter Roeck
2010-10-24 15:35     ` Guenter Roeck
2010-10-24 16:35     ` [lm-sensors] " Guenter Roeck
2010-10-24 16:35       ` Guenter Roeck
2010-10-24 16:35       ` Guenter Roeck
2010-10-24 17:01       ` Guenter Roeck
2010-10-24 17:01         ` Guenter Roeck
2010-10-24 17:01         ` Guenter Roeck
2010-10-25  6:10   ` samu.p.onkalo
2010-10-25  6:10     ` [lm-sensors] " samu.p.onkalo
2010-10-25  6:10     ` samu.p.onkalo-xNZwKgViW5gAvxtiuMwx3w

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.