aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2016-09-01 05:44:46 -0400
committerJonathan Cameron <jic23@kernel.org>2016-09-18 06:33:28 -0400
commit2bb4a02aad0257148be4f51e3b4c9c0077787e17 (patch)
treeb970d5c272ea3b3957cd87393feffb56e891a87d
parent11adc2b218028934540be4f235a486d575d74b54 (diff)
iio: accel: kxsd9: Fetch and handle regulators
This adds supply regulator handling for the VDD and IOVDD inputs on the KXSD9 component, makes sure to bring the regulators online during probe and disable them on remove or the errorpath. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r--drivers/iio/accel/kxsd9.c88
1 files changed, 85 insertions, 3 deletions
diff --git a/drivers/iio/accel/kxsd9.c b/drivers/iio/accel/kxsd9.c
index 8c6a4559256e..dc53f70e616e 100644
--- a/drivers/iio/accel/kxsd9.c
+++ b/drivers/iio/accel/kxsd9.c
@@ -21,6 +21,8 @@
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/regmap.h> 22#include <linux/regmap.h>
23#include <linux/bitops.h> 23#include <linux/bitops.h>
24#include <linux/delay.h>
25#include <linux/regulator/consumer.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>
@@ -65,10 +67,12 @@
65 * struct kxsd9_state - device related storage 67 * struct kxsd9_state - device related storage
66 * @dev: pointer to the parent device 68 * @dev: pointer to the parent device
67 * @map: regmap to the device 69 * @map: regmap to the device
70 * @regs: regulators for this device, VDD and IOVDD
68 */ 71 */
69struct kxsd9_state { 72struct kxsd9_state {
70 struct device *dev; 73 struct device *dev;
71 struct regmap *map; 74 struct regmap *map;
75 struct regulator_bulk_data regs[2];
72}; 76};
73 77
74#define KXSD9_SCALE_2G "0.011978" 78#define KXSD9_SCALE_2G "0.011978"
@@ -81,6 +85,12 @@ static const int kxsd9_micro_scales[4] = { 47853, 35934, 23927, 11978 };
81 85
82#define KXSD9_ZERO_G_OFFSET -2048 86#define KXSD9_ZERO_G_OFFSET -2048
83 87
88/*
89 * Regulator names
90 */
91static const char kxsd9_reg_vdd[] = "vdd";
92static const char kxsd9_reg_iovdd[] = "iovdd";
93
84static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro) 94static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro)
85{ 95{
86 int ret, i; 96 int ret, i;
@@ -252,12 +262,69 @@ static int kxsd9_power_up(struct kxsd9_state *st)
252{ 262{
253 int ret; 263 int ret;
254 264
255 ret = regmap_write(st->map, KXSD9_REG_CTRL_B, 0x40); 265 /* Enable the regulators */
266 ret = regulator_bulk_enable(ARRAY_SIZE(st->regs), st->regs);
267 if (ret) {
268 dev_err(st->dev, "Cannot enable regulators\n");
269 return ret;
270 }
271
272 /* Power up */
273 ret = regmap_write(st->map,
274 KXSD9_REG_CTRL_B,
275 KXSD9_CTRL_B_ENABLE);
256 if (ret) 276 if (ret)
257 return ret; 277 return ret;
258 return regmap_write(st->map, KXSD9_REG_CTRL_C, 0x9b); 278
279 /*
280 * Set 1000Hz LPF, 2g fullscale, motion wakeup threshold 1g,
281 * latched wakeup
282 */
283 ret = regmap_write(st->map,
284 KXSD9_REG_CTRL_C,
285 KXSD9_CTRL_C_LP_1000HZ |
286 KXSD9_CTRL_C_MOT_LEV |
287 KXSD9_CTRL_C_MOT_LAT |
288 KXSD9_CTRL_C_FS_2G);
289 if (ret)
290 return ret;
291
292 /*
293 * Power-up time depends on the LPF setting, but typ 15.9 ms, let's
294 * set 20 ms to allow for some slack.
295 */
296 msleep(20);
297
298 return 0;
259}; 299};
260 300
301static int kxsd9_power_down(struct kxsd9_state *st)
302{
303 int ret;
304
305 /*
306 * Set into low power mode - since there may be more users of the
307 * regulators this is the first step of the power saving: it will
308 * make sure we conserve power even if there are others users on the
309 * regulators.
310 */
311 ret = regmap_update_bits(st->map,
312 KXSD9_REG_CTRL_B,
313 KXSD9_CTRL_B_ENABLE,
314 0);
315 if (ret)
316 return ret;
317
318 /* Disable the regulators */
319 ret = regulator_bulk_disable(ARRAY_SIZE(st->regs), st->regs);
320 if (ret) {
321 dev_err(st->dev, "Cannot disable regulators\n");
322 return ret;
323 }
324
325 return 0;
326}
327
261static const struct iio_info kxsd9_info = { 328static const struct iio_info kxsd9_info = {
262 .read_raw = &kxsd9_read_raw, 329 .read_raw = &kxsd9_read_raw,
263 .write_raw = &kxsd9_write_raw, 330 .write_raw = &kxsd9_write_raw,
@@ -292,6 +359,17 @@ int kxsd9_common_probe(struct device *parent,
292 indio_dev->modes = INDIO_DIRECT_MODE; 359 indio_dev->modes = INDIO_DIRECT_MODE;
293 indio_dev->available_scan_masks = kxsd9_scan_masks; 360 indio_dev->available_scan_masks = kxsd9_scan_masks;
294 361
362 /* Fetch and turn on regulators */
363 st->regs[0].supply = kxsd9_reg_vdd;
364 st->regs[1].supply = kxsd9_reg_iovdd;
365 ret = devm_regulator_bulk_get(parent,
366 ARRAY_SIZE(st->regs),
367 st->regs);
368 if (ret) {
369 dev_err(parent, "Cannot get regulators\n");
370 return ret;
371 }
372
295 kxsd9_power_up(st); 373 kxsd9_power_up(st);
296 374
297 ret = iio_triggered_buffer_setup(indio_dev, 375 ret = iio_triggered_buffer_setup(indio_dev,
@@ -300,7 +378,7 @@ int kxsd9_common_probe(struct device *parent,
300 NULL); 378 NULL);
301 if (ret) { 379 if (ret) {
302 dev_err(parent, "triggered buffer setup failed\n"); 380 dev_err(parent, "triggered buffer setup failed\n");
303 return ret; 381 goto err_power_down;
304 } 382 }
305 383
306 ret = iio_device_register(indio_dev); 384 ret = iio_device_register(indio_dev);
@@ -313,6 +391,8 @@ int kxsd9_common_probe(struct device *parent,
313 391
314err_cleanup_buffer: 392err_cleanup_buffer:
315 iio_triggered_buffer_cleanup(indio_dev); 393 iio_triggered_buffer_cleanup(indio_dev);
394err_power_down:
395 kxsd9_power_down(st);
316 396
317 return ret; 397 return ret;
318} 398}
@@ -321,9 +401,11 @@ EXPORT_SYMBOL(kxsd9_common_probe);
321int kxsd9_common_remove(struct device *parent) 401int kxsd9_common_remove(struct device *parent)
322{ 402{
323 struct iio_dev *indio_dev = dev_get_drvdata(parent); 403 struct iio_dev *indio_dev = dev_get_drvdata(parent);
404 struct kxsd9_state *st = iio_priv(indio_dev);
324 405
325 iio_triggered_buffer_cleanup(indio_dev); 406 iio_triggered_buffer_cleanup(indio_dev);
326 iio_device_unregister(indio_dev); 407 iio_device_unregister(indio_dev);
408 kxsd9_power_down(st);
327 409
328 return 0; 410 return 0;
329} 411}