aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio/accel/kxcjk-1013.c
diff options
context:
space:
mode:
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>2014-05-08 17:58:00 -0400
committerJonathan Cameron <jic23@kernel.org>2014-08-07 06:22:42 -0400
commit124e1b1d0924ca51ded8bb6f52844b2bc9e485f7 (patch)
tree734d5437f2a893dd3408ae1edb65dafbceb2c58a /drivers/iio/accel/kxcjk-1013.c
parentce9d475607e7bf48b066603700afdb4811cec9b6 (diff)
iio: accel: kxcjk-1013: support runtime pm
In an effort to improve raw read performance and at the same time enter low power state at every possible chance. For raw reads, it will keep the system powered on for a default or user specified time, via autosuspend_delay attribute of device power. This will help read multiple samples without power on/off sequence. For triggers it will keep the system on till, requested to be turned off by trigger state by utilizing run time PM usage counters. When runtime pm is not enabled, then it keeps the chip in operation mode always. Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio/accel/kxcjk-1013.c')
-rw-r--r--drivers/iio/accel/kxcjk-1013.c206
1 files changed, 156 insertions, 50 deletions
diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c
index 7941cf2d31ee..b32bdd10e0c4 100644
--- a/drivers/iio/accel/kxcjk-1013.c
+++ b/drivers/iio/accel/kxcjk-1013.c
@@ -21,6 +21,8 @@
21#include <linux/string.h> 21#include <linux/string.h>
22#include <linux/acpi.h> 22#include <linux/acpi.h>
23#include <linux/gpio/consumer.h> 23#include <linux/gpio/consumer.h>
24#include <linux/pm.h>
25#include <linux/pm_runtime.h>
24#include <linux/iio/iio.h> 26#include <linux/iio/iio.h>
25#include <linux/iio/sysfs.h> 27#include <linux/iio/sysfs.h>
26#include <linux/iio/buffer.h> 28#include <linux/iio/buffer.h>
@@ -71,15 +73,17 @@
71#define KXCJK1013_DATA_MASK_12_BIT 0x0FFF 73#define KXCJK1013_DATA_MASK_12_BIT 0x0FFF
72#define KXCJK1013_MAX_STARTUP_TIME_US 100000 74#define KXCJK1013_MAX_STARTUP_TIME_US 100000
73 75
76#define KXCJK1013_SLEEP_DELAY_MS 2000
77
74struct kxcjk1013_data { 78struct kxcjk1013_data {
75 struct i2c_client *client; 79 struct i2c_client *client;
76 struct iio_trigger *trig; 80 struct iio_trigger *trig;
77 bool trig_mode; 81 bool trig_mode;
78 struct mutex mutex; 82 struct mutex mutex;
79 s16 buffer[8]; 83 s16 buffer[8];
80 int power_state;
81 u8 odr_bits; 84 u8 odr_bits;
82 bool active_high_intr; 85 bool active_high_intr;
86 bool trigger_on;
83}; 87};
84 88
85enum kxcjk1013_axis { 89enum kxcjk1013_axis {
@@ -138,6 +142,25 @@ static int kxcjk1013_set_mode(struct kxcjk1013_data *data,
138 return 0; 142 return 0;
139} 143}
140 144
145static int kxcjk1013_get_mode(struct kxcjk1013_data *data,
146 enum kxcjk1013_mode *mode)
147{
148 int ret;
149
150 ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1);
151 if (ret < 0) {
152 dev_err(&data->client->dev, "Error reading reg_ctrl1\n");
153 return ret;
154 }
155
156 if (ret & KXCJK1013_REG_CTRL1_BIT_PC1)
157 *mode = OPERATION;
158 else
159 *mode = STANDBY;
160
161 return 0;
162}
163
141static int kxcjk1013_chip_init(struct kxcjk1013_data *data) 164static int kxcjk1013_chip_init(struct kxcjk1013_data *data)
142{ 165{
143 int ret; 166 int ret;
@@ -201,6 +224,41 @@ static int kxcjk1013_chip_init(struct kxcjk1013_data *data)
201 return ret; 224 return ret;
202 } 225 }
203 226
227 ret = kxcjk1013_set_mode(data, OPERATION);
228 if (ret < 0)
229 return ret;
230
231 return 0;
232}
233
234static int kxcjk1013_get_startup_times(struct kxcjk1013_data *data)
235{
236 int i;
237
238 for (i = 0; i < ARRAY_SIZE(odr_start_up_times); ++i) {
239 if (odr_start_up_times[i].odr_bits == data->odr_bits)
240 return odr_start_up_times[i].usec;
241 }
242
243 return KXCJK1013_MAX_STARTUP_TIME_US;
244}
245
246static int kxcjk1013_set_power_state(struct kxcjk1013_data *data, bool on)
247{
248 int ret;
249
250 if (on)
251 ret = pm_runtime_get_sync(&data->client->dev);
252 else {
253 pm_runtime_mark_last_busy(&data->client->dev);
254 ret = pm_runtime_put_autosuspend(&data->client->dev);
255 }
256 if (ret < 0) {
257 dev_err(&data->client->dev,
258 "Failed: kxcjk1013_set_power_state for %d\n", on);
259 return ret;
260 }
261
204 return 0; 262 return 0;
205} 263}
206 264
@@ -208,6 +266,11 @@ static int kxcjk1013_chip_setup_interrupt(struct kxcjk1013_data *data,
208 bool status) 266 bool status)
209{ 267{
210 int ret; 268 int ret;
269 enum kxcjk1013_mode store_mode;
270
271 ret = kxcjk1013_get_mode(data, &store_mode);
272 if (ret < 0)
273 return ret;
211 274
212 /* This is requirement by spec to change state to STANDBY */ 275 /* This is requirement by spec to change state to STANDBY */
213 ret = kxcjk1013_set_mode(data, STANDBY); 276 ret = kxcjk1013_set_mode(data, STANDBY);
@@ -250,7 +313,13 @@ static int kxcjk1013_chip_setup_interrupt(struct kxcjk1013_data *data,
250 return ret; 313 return ret;
251 } 314 }
252 315
253 return ret; 316 if (store_mode == OPERATION) {
317 ret = kxcjk1013_set_mode(data, OPERATION);
318 if (ret < 0)
319 return ret;
320 }
321
322 return 0;
254} 323}
255 324
256static int kxcjk1013_convert_freq_to_bit(int val, int val2) 325static int kxcjk1013_convert_freq_to_bit(int val, int val2)
@@ -271,6 +340,11 @@ static int kxcjk1013_set_odr(struct kxcjk1013_data *data, int val, int val2)
271{ 340{
272 int ret; 341 int ret;
273 int odr_bits; 342 int odr_bits;
343 enum kxcjk1013_mode store_mode;
344
345 ret = kxcjk1013_get_mode(data, &store_mode);
346 if (ret < 0)
347 return ret;
274 348
275 odr_bits = kxcjk1013_convert_freq_to_bit(val, val2); 349 odr_bits = kxcjk1013_convert_freq_to_bit(val, val2);
276 if (odr_bits < 0) 350 if (odr_bits < 0)
@@ -290,9 +364,7 @@ static int kxcjk1013_set_odr(struct kxcjk1013_data *data, int val, int val2)
290 364
291 data->odr_bits = odr_bits; 365 data->odr_bits = odr_bits;
292 366
293 /* Check, if the ODR is changed after data enable */ 367 if (store_mode == OPERATION) {
294 if (data->power_state) {
295 /* Set the state back to operation */
296 ret = kxcjk1013_set_mode(data, OPERATION); 368 ret = kxcjk1013_set_mode(data, OPERATION);
297 if (ret < 0) 369 if (ret < 0)
298 return ret; 370 return ret;
@@ -331,18 +403,6 @@ static int kxcjk1013_get_acc_reg(struct kxcjk1013_data *data, int axis)
331 return ret; 403 return ret;
332} 404}
333 405
334static int kxcjk1013_get_startup_times(struct kxcjk1013_data *data)
335{
336 int i;
337
338 for (i = 0; i < ARRAY_SIZE(odr_start_up_times); ++i) {
339 if (odr_start_up_times[i].odr_bits == data->odr_bits)
340 return odr_start_up_times[i].usec;
341 }
342
343 return KXCJK1013_MAX_STARTUP_TIME_US;
344}
345
346static int kxcjk1013_read_raw(struct iio_dev *indio_dev, 406static int kxcjk1013_read_raw(struct iio_dev *indio_dev,
347 struct iio_chan_spec const *chan, int *val, 407 struct iio_chan_spec const *chan, int *val,
348 int *val2, long mask) 408 int *val2, long mask)
@@ -356,29 +416,25 @@ static int kxcjk1013_read_raw(struct iio_dev *indio_dev,
356 if (iio_buffer_enabled(indio_dev)) 416 if (iio_buffer_enabled(indio_dev))
357 ret = -EBUSY; 417 ret = -EBUSY;
358 else { 418 else {
359 int sleep_val; 419 ret = kxcjk1013_set_power_state(data, true);
360
361 ret = kxcjk1013_set_mode(data, OPERATION);
362 if (ret < 0) { 420 if (ret < 0) {
363 mutex_unlock(&data->mutex); 421 mutex_unlock(&data->mutex);
364 return ret; 422 return ret;
365 } 423 }
366 ++data->power_state;
367 sleep_val = kxcjk1013_get_startup_times(data);
368 if (sleep_val < 20000)
369 usleep_range(sleep_val, 20000);
370 else
371 msleep_interruptible(sleep_val/1000);
372 ret = kxcjk1013_get_acc_reg(data, chan->scan_index); 424 ret = kxcjk1013_get_acc_reg(data, chan->scan_index);
373 if (--data->power_state == 0) 425 if (ret < 0) {
374 kxcjk1013_set_mode(data, STANDBY); 426 kxcjk1013_set_power_state(data, false);
427 mutex_unlock(&data->mutex);
428 return ret;
429 }
430 *val = sign_extend32(ret >> 4, 11);
431 ret = kxcjk1013_set_power_state(data, false);
375 } 432 }
376 mutex_unlock(&data->mutex); 433 mutex_unlock(&data->mutex);
377 434
378 if (ret < 0) 435 if (ret < 0)
379 return ret; 436 return ret;
380 437
381 *val = sign_extend32(ret >> 4, 11);
382 return IIO_VAL_INT; 438 return IIO_VAL_INT;
383 439
384 case IIO_CHAN_INFO_SCALE: 440 case IIO_CHAN_INFO_SCALE:
@@ -520,20 +576,21 @@ static int kxcjk1013_data_rdy_trigger_set_state(struct iio_trigger *trig,
520{ 576{
521 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 577 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
522 struct kxcjk1013_data *data = iio_priv(indio_dev); 578 struct kxcjk1013_data *data = iio_priv(indio_dev);
579 int ret;
580
581 if (state && data->trigger_on)
582 return 0;
523 583
524 mutex_lock(&data->mutex); 584 mutex_lock(&data->mutex);
525 if (state) { 585 ret = kxcjk1013_chip_setup_interrupt(data, state);
526 kxcjk1013_chip_setup_interrupt(data, true); 586 if (!ret) {
527 kxcjk1013_set_mode(data, OPERATION); 587 ret = kxcjk1013_set_power_state(data, state);
528 ++data->power_state; 588 if (ret < 0) {
529 } else {
530 if (--data->power_state) {
531 mutex_unlock(&data->mutex); 589 mutex_unlock(&data->mutex);
532 return 0; 590 return ret;
533 } 591 }
534 kxcjk1013_chip_setup_interrupt(data, false);
535 kxcjk1013_set_mode(data, STANDBY);
536 } 592 }
593 data->trigger_on = state;
537 mutex_unlock(&data->mutex); 594 mutex_unlock(&data->mutex);
538 595
539 return 0; 596 return 0;
@@ -661,14 +718,25 @@ static int kxcjk1013_probe(struct i2c_client *client,
661 } 718 }
662 } 719 }
663 720
664 ret = devm_iio_device_register(&client->dev, indio_dev); 721 ret = iio_device_register(indio_dev);
665 if (ret < 0) { 722 if (ret < 0) {
666 dev_err(&client->dev, "unable to register iio device\n"); 723 dev_err(&client->dev, "unable to register iio device\n");
667 goto err_buffer_cleanup; 724 goto err_buffer_cleanup;
668 } 725 }
669 726
727 ret = pm_runtime_set_active(&client->dev);
728 if (ret)
729 goto err_iio_unregister;
730
731 pm_runtime_enable(&client->dev);
732 pm_runtime_set_autosuspend_delay(&client->dev,
733 KXCJK1013_SLEEP_DELAY_MS);
734 pm_runtime_use_autosuspend(&client->dev);
735
670 return 0; 736 return 0;
671 737
738err_iio_unregister:
739 iio_device_unregister(indio_dev);
672err_buffer_cleanup: 740err_buffer_cleanup:
673 if (data->trig_mode) 741 if (data->trig_mode)
674 iio_triggered_buffer_cleanup(indio_dev); 742 iio_triggered_buffer_cleanup(indio_dev);
@@ -687,6 +755,12 @@ static int kxcjk1013_remove(struct i2c_client *client)
687 struct iio_dev *indio_dev = i2c_get_clientdata(client); 755 struct iio_dev *indio_dev = i2c_get_clientdata(client);
688 struct kxcjk1013_data *data = iio_priv(indio_dev); 756 struct kxcjk1013_data *data = iio_priv(indio_dev);
689 757
758 pm_runtime_disable(&client->dev);
759 pm_runtime_set_suspended(&client->dev);
760 pm_runtime_put_noidle(&client->dev);
761
762 iio_device_unregister(indio_dev);
763
690 if (data->trig_mode) { 764 if (data->trig_mode) {
691 iio_triggered_buffer_cleanup(indio_dev); 765 iio_triggered_buffer_cleanup(indio_dev);
692 iio_trigger_unregister(data->trig); 766 iio_trigger_unregister(data->trig);
@@ -705,35 +779,67 @@ static int kxcjk1013_suspend(struct device *dev)
705{ 779{
706 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); 780 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
707 struct kxcjk1013_data *data = iio_priv(indio_dev); 781 struct kxcjk1013_data *data = iio_priv(indio_dev);
782 int ret;
708 783
709 mutex_lock(&data->mutex); 784 mutex_lock(&data->mutex);
710 kxcjk1013_set_mode(data, STANDBY); 785 ret = kxcjk1013_set_mode(data, STANDBY);
711 mutex_unlock(&data->mutex); 786 mutex_unlock(&data->mutex);
712 787
713 return 0; 788 return ret;
714} 789}
715 790
716static int kxcjk1013_resume(struct device *dev) 791static int kxcjk1013_resume(struct device *dev)
717{ 792{
718 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); 793 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
719 struct kxcjk1013_data *data = iio_priv(indio_dev); 794 struct kxcjk1013_data *data = iio_priv(indio_dev);
795 int ret = 0;
720 796
721 mutex_lock(&data->mutex); 797 mutex_lock(&data->mutex);
798 /* Check, if the suspend occured while active */
799 if (data->trigger_on)
800 ret = kxcjk1013_set_mode(data, OPERATION);
801 mutex_unlock(&data->mutex);
722 802
723 if (data->power_state) 803 return ret;
724 kxcjk1013_set_mode(data, OPERATION); 804}
805#endif
725 806
726 mutex_unlock(&data->mutex); 807#ifdef CONFIG_PM_RUNTIME
808static int kxcjk1013_runtime_suspend(struct device *dev)
809{
810 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
811 struct kxcjk1013_data *data = iio_priv(indio_dev);
727 812
728 return 0; 813 return kxcjk1013_set_mode(data, STANDBY);
729} 814}
730 815
731static SIMPLE_DEV_PM_OPS(kxcjk1013_pm_ops, kxcjk1013_suspend, kxcjk1013_resume); 816static int kxcjk1013_runtime_resume(struct device *dev)
732#define KXCJK1013_PM_OPS (&kxcjk1013_pm_ops) 817{
733#else 818 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
734#define KXCJK1013_PM_OPS NULL 819 struct kxcjk1013_data *data = iio_priv(indio_dev);
820 int ret;
821 int sleep_val;
822
823 ret = kxcjk1013_set_mode(data, OPERATION);
824 if (ret < 0)
825 return ret;
826
827 sleep_val = kxcjk1013_get_startup_times(data);
828 if (sleep_val < 20000)
829 usleep_range(sleep_val, 20000);
830 else
831 msleep_interruptible(sleep_val/1000);
832
833 return 0;
834}
735#endif 835#endif
736 836
837static const struct dev_pm_ops kxcjk1013_pm_ops = {
838 SET_SYSTEM_SLEEP_PM_OPS(kxcjk1013_suspend, kxcjk1013_resume)
839 SET_RUNTIME_PM_OPS(kxcjk1013_runtime_suspend,
840 kxcjk1013_runtime_resume, NULL)
841};
842
737static const struct acpi_device_id kx_acpi_match[] = { 843static const struct acpi_device_id kx_acpi_match[] = {
738 {"KXCJ1013", 0}, 844 {"KXCJ1013", 0},
739 { }, 845 { },
@@ -751,7 +857,7 @@ static struct i2c_driver kxcjk1013_driver = {
751 .driver = { 857 .driver = {
752 .name = KXCJK1013_DRV_NAME, 858 .name = KXCJK1013_DRV_NAME,
753 .acpi_match_table = ACPI_PTR(kx_acpi_match), 859 .acpi_match_table = ACPI_PTR(kx_acpi_match),
754 .pm = KXCJK1013_PM_OPS, 860 .pm = &kxcjk1013_pm_ops,
755 }, 861 },
756 .probe = kxcjk1013_probe, 862 .probe = kxcjk1013_probe,
757 .remove = kxcjk1013_remove, 863 .remove = kxcjk1013_remove,