Re: [PATCH 02/12] hwmon: lis3: regulator control

2010-10-24 Thread Éric Piel

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
I have very little knowledge about regulators, but for what I could 
understand it looks fine...


Acked-by: Eric Piel 


---
  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
  #include
  #include
+#include
  #include
  #include
  #include
@@ -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
  #include
+#include

  /*
   * 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_conver

Re: [PATCH 02/12] hwmon: lis3: regulator control

2010-10-22 Thread Jonathan Cameron
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 
Acked-by: Jonathan Cameron 
> ---
>  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 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -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 
>  #include 
> +#include 
>  
>  /*
>   * This driver tries to support the "digital" accelerometer chips from
> @@ -206,6 +207,11 @@ enum lis3lv02d_click_src_8b {
>   CLICK_IA= 0x40,
>  };
>  
> +enum lis3lv0