aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
authorDaniel Baluta <daniel.baluta@intel.com>2014-12-03 08:31:50 -0500
committerJonathan Cameron <jic23@kernel.org>2014-12-12 08:44:30 -0500
commitaff8609addd00efa3d907f3523823693f95686fd (patch)
treec059d724d8a32a8b35113cd1a497e31e6c35750c /drivers/iio
parentb25862c577979659020f3575838d366f480ec3bf (diff)
iio: imu: kmx61: Add PM runtime support
By default both sensors are ACTIVE, in this way the driver will work even if CONFIG_PM_RUNTIME is not selected. Signed-off-by: Daniel Baluta <daniel.baluta@intel.com> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/imu/kmx61.c114
1 files changed, 112 insertions, 2 deletions
diff --git a/drivers/iio/imu/kmx61.c b/drivers/iio/imu/kmx61.c
index efb2f8b450c1..f3007dd664fc 100644
--- a/drivers/iio/imu/kmx61.c
+++ b/drivers/iio/imu/kmx61.c
@@ -15,6 +15,8 @@
15#include <linux/i2c.h> 15#include <linux/i2c.h>
16#include <linux/acpi.h> 16#include <linux/acpi.h>
17#include <linux/gpio/consumer.h> 17#include <linux/gpio/consumer.h>
18#include <linux/interrupt.h>
19#include <linux/pm_runtime.h>
18#include <linux/iio/iio.h> 20#include <linux/iio/iio.h>
19#include <linux/iio/sysfs.h> 21#include <linux/iio/sysfs.h>
20 22
@@ -69,6 +71,8 @@
69#define KMX61_ACC_ODR_MASK 0x0F 71#define KMX61_ACC_ODR_MASK 0x0F
70#define KMX61_MAG_ODR_MASK 0xF0 72#define KMX61_MAG_ODR_MASK 0xF0
71 73
74#define KMX61_SLEEP_DELAY_MS 2000
75
72#define KMX61_CHIP_ID 0x12 76#define KMX61_CHIP_ID 0x12
73 77
74/* KMX61 devices */ 78/* KMX61 devices */
@@ -85,6 +89,10 @@ struct kmx61_data {
85 bool acc_stby; 89 bool acc_stby;
86 bool mag_stby; 90 bool mag_stby;
87 91
92 /* power state */
93 bool acc_ps;
94 bool mag_ps;
95
88 /* config bits */ 96 /* config bits */
89 u8 range; 97 u8 range;
90 u8 odr_bits; 98 u8 odr_bits;
@@ -457,6 +465,58 @@ static int kmx61_chip_init(struct kmx61_data *data)
457 return 0; 465 return 0;
458} 466}
459 467
468/**
469 * kmx61_set_power_state() - set power state for kmx61 @device
470 * @data - kmx61 device private pointer
471 * @on - power state to be set for @device
472 * @device - bitmask indicating device for which @on state needs to be set
473 *
474 * Notice that when ACC power state needs to be set to ON and MAG is in
475 * OPERATION then we know that kmx61_runtime_resume was already called
476 * so we must set ACC OPERATION mode here. The same happens when MAG power
477 * state needs to be set to ON and ACC is in OPERATION.
478 */
479static int kmx61_set_power_state(struct kmx61_data *data, bool on, u8 device)
480{
481#ifdef CONFIG_PM_RUNTIME
482 int ret;
483
484 if (device & KMX61_ACC) {
485 if (on && !data->acc_ps && !data->mag_stby) {
486 ret = kmx61_set_mode(data, 0, KMX61_ACC, true);
487 if (ret < 0)
488 return ret;
489 }
490 data->acc_ps = on;
491 }
492 if (device & KMX61_MAG) {
493 if (on && !data->mag_ps && !data->acc_stby) {
494 ret = kmx61_set_mode(data, 0, KMX61_MAG, true);
495 if (ret < 0)
496 return ret;
497 }
498 data->mag_ps = on;
499 }
500
501 if (on) {
502 ret = pm_runtime_get_sync(&data->client->dev);
503 } else {
504 pm_runtime_mark_last_busy(&data->client->dev);
505 ret = pm_runtime_put_autosuspend(&data->client->dev);
506 }
507 if (ret < 0) {
508 dev_err(&data->client->dev,
509 "Failed: kmx61_set_power_state for %d, ret %d\n",
510 on, ret);
511 if (on)
512 pm_runtime_put_noidle(&data->client->dev);
513
514 return ret;
515 }
516#endif
517 return 0;
518}
519
460static int kmx61_read_measurement(struct kmx61_data *data, u8 base, u8 offset) 520static int kmx61_read_measurement(struct kmx61_data *data, u8 base, u8 offset)
461{ 521{
462 int ret; 522 int ret;
@@ -491,13 +551,16 @@ static int kmx61_read_raw(struct iio_dev *indio_dev,
491 } 551 }
492 mutex_lock(&data->lock); 552 mutex_lock(&data->lock);
493 553
554 kmx61_set_power_state(data, true, chan->address);
494 ret = kmx61_read_measurement(data, base_reg, chan->scan_index); 555 ret = kmx61_read_measurement(data, base_reg, chan->scan_index);
495 if (ret < 0) { 556 if (ret < 0) {
557 kmx61_set_power_state(data, false, chan->address);
496 mutex_unlock(&data->lock); 558 mutex_unlock(&data->lock);
497 return ret; 559 return ret;
498 } 560 }
499 *val = sign_extend32(ret >> chan->scan_type.shift, 561 *val = sign_extend32(ret >> chan->scan_type.shift,
500 chan->scan_type.realbits - 1); 562 chan->scan_type.realbits - 1);
563 kmx61_set_power_state(data, false, chan->address);
501 564
502 mutex_unlock(&data->lock); 565 mutex_unlock(&data->lock);
503 return IIO_VAL_INT; 566 return IIO_VAL_INT;
@@ -693,12 +756,22 @@ static int kmx61_probe(struct i2c_client *client,
693 ret = iio_device_register(data->mag_indio_dev); 756 ret = iio_device_register(data->mag_indio_dev);
694 if (ret < 0) { 757 if (ret < 0) {
695 dev_err(&client->dev, "Failed to register mag iio device\n"); 758 dev_err(&client->dev, "Failed to register mag iio device\n");
696 goto err_iio_unregister; 759 goto err_iio_unregister_acc;
697 } 760 }
698 761
762 ret = pm_runtime_set_active(&client->dev);
763 if (ret < 0)
764 goto err_iio_unregister_mag;
765
766 pm_runtime_enable(&client->dev);
767 pm_runtime_set_autosuspend_delay(&client->dev, KMX61_SLEEP_DELAY_MS);
768 pm_runtime_use_autosuspend(&client->dev);
769
699 return 0; 770 return 0;
700 771
701err_iio_unregister: 772err_iio_unregister_mag:
773 iio_device_unregister(data->mag_indio_dev);
774err_iio_unregister_acc:
702 iio_device_unregister(data->acc_indio_dev); 775 iio_device_unregister(data->acc_indio_dev);
703err_chip_uninit: 776err_chip_uninit:
704 kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true); 777 kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
@@ -709,6 +782,10 @@ static int kmx61_remove(struct i2c_client *client)
709{ 782{
710 struct kmx61_data *data = i2c_get_clientdata(client); 783 struct kmx61_data *data = i2c_get_clientdata(client);
711 784
785 pm_runtime_disable(&client->dev);
786 pm_runtime_set_suspended(&client->dev);
787 pm_runtime_put_noidle(&client->dev);
788
712 iio_device_unregister(data->acc_indio_dev); 789 iio_device_unregister(data->acc_indio_dev);
713 iio_device_unregister(data->mag_indio_dev); 790 iio_device_unregister(data->mag_indio_dev);
714 791
@@ -719,6 +796,38 @@ static int kmx61_remove(struct i2c_client *client)
719 return 0; 796 return 0;
720} 797}
721 798
799
800#ifdef CONFIG_PM_RUNTIME
801static int kmx61_runtime_suspend(struct device *dev)
802{
803 struct kmx61_data *data = i2c_get_clientdata(to_i2c_client(dev));
804 int ret;
805
806 mutex_lock(&data->lock);
807 ret = kmx61_set_mode(data, KMX61_ALL_STBY, KMX61_ACC | KMX61_MAG, true);
808 mutex_unlock(&data->lock);
809
810 return ret;
811}
812
813static int kmx61_runtime_resume(struct device *dev)
814{
815 struct kmx61_data *data = i2c_get_clientdata(to_i2c_client(dev));
816 u8 stby = 0;
817
818 if (!data->acc_ps)
819 stby |= KMX61_ACC_STBY_BIT;
820 if (!data->mag_ps)
821 stby |= KMX61_MAG_STBY_BIT;
822
823 return kmx61_set_mode(data, stby, KMX61_ACC | KMX61_MAG, true);
824}
825#endif
826
827static const struct dev_pm_ops kmx61_pm_ops = {
828 SET_RUNTIME_PM_OPS(kmx61_runtime_suspend, kmx61_runtime_resume, NULL)
829};
830
722static const struct acpi_device_id kmx61_acpi_match[] = { 831static const struct acpi_device_id kmx61_acpi_match[] = {
723 {"KMX61021", 0}, 832 {"KMX61021", 0},
724 {} 833 {}
@@ -737,6 +846,7 @@ static struct i2c_driver kmx61_driver = {
737 .driver = { 846 .driver = {
738 .name = KMX61_DRV_NAME, 847 .name = KMX61_DRV_NAME,
739 .acpi_match_table = ACPI_PTR(kmx61_acpi_match), 848 .acpi_match_table = ACPI_PTR(kmx61_acpi_match),
849 .pm = &kmx61_pm_ops,
740 }, 850 },
741 .probe = kmx61_probe, 851 .probe = kmx61_probe,
742 .remove = kmx61_remove, 852 .remove = kmx61_remove,