514 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * kxsd9.c simple support for the Kionix KXSD9 3D4 * accelerometer.5 *6 * Copyright (c) 2008-2009 Jonathan Cameron <jic23@kernel.org>7 *8 * The i2c interface is very similar, so shouldn't be a problem once9 * I have a suitable wire made up.10 *11 * TODO: Support the motion detector12 */13 14#include <linux/device.h>15#include <linux/kernel.h>16#include <linux/sysfs.h>17#include <linux/slab.h>18#include <linux/module.h>19#include <linux/regmap.h>20#include <linux/bitops.h>21#include <linux/delay.h>22#include <linux/regulator/consumer.h>23#include <linux/pm_runtime.h>24#include <linux/iio/iio.h>25#include <linux/iio/sysfs.h>26#include <linux/iio/buffer.h>27#include <linux/iio/triggered_buffer.h>28#include <linux/iio/trigger_consumer.h>29 30#include "kxsd9.h"31 32#define KXSD9_REG_X 0x0033#define KXSD9_REG_Y 0x0234#define KXSD9_REG_Z 0x0435#define KXSD9_REG_AUX 0x0636#define KXSD9_REG_RESET 0x0a37#define KXSD9_REG_CTRL_C 0x0c38 39#define KXSD9_CTRL_C_FS_MASK 0x0340#define KXSD9_CTRL_C_FS_8G 0x0041#define KXSD9_CTRL_C_FS_6G 0x0142#define KXSD9_CTRL_C_FS_4G 0x0243#define KXSD9_CTRL_C_FS_2G 0x0344#define KXSD9_CTRL_C_MOT_LAT BIT(3)45#define KXSD9_CTRL_C_MOT_LEV BIT(4)46#define KXSD9_CTRL_C_LP_MASK 0xe047#define KXSD9_CTRL_C_LP_NONE 0x0048#define KXSD9_CTRL_C_LP_2000HZC BIT(5)49#define KXSD9_CTRL_C_LP_2000HZB BIT(6)50#define KXSD9_CTRL_C_LP_2000HZA (BIT(5)|BIT(6))51#define KXSD9_CTRL_C_LP_1000HZ BIT(7)52#define KXSD9_CTRL_C_LP_500HZ (BIT(7)|BIT(5))53#define KXSD9_CTRL_C_LP_100HZ (BIT(7)|BIT(6))54#define KXSD9_CTRL_C_LP_50HZ (BIT(7)|BIT(6)|BIT(5))55 56#define KXSD9_REG_CTRL_B 0x0d57 58#define KXSD9_CTRL_B_CLK_HLD BIT(7)59#define KXSD9_CTRL_B_ENABLE BIT(6)60#define KXSD9_CTRL_B_ST BIT(5) /* Self-test */61 62#define KXSD9_REG_CTRL_A 0x0e63 64/**65 * struct kxsd9_state - device related storage66 * @dev: pointer to the parent device67 * @map: regmap to the device68 * @orientation: mounting matrix, flipped axis etc69 * @regs: regulators for this device, VDD and IOVDD70 * @scale: the current scaling setting71 */72struct kxsd9_state {73 struct device *dev;74 struct regmap *map;75 struct iio_mount_matrix orientation;76 struct regulator_bulk_data regs[2];77 u8 scale;78};79 80#define KXSD9_SCALE_2G "0.011978"81#define KXSD9_SCALE_4G "0.023927"82#define KXSD9_SCALE_6G "0.035934"83#define KXSD9_SCALE_8G "0.047853"84 85/* reverse order */86static const int kxsd9_micro_scales[4] = { 47853, 35934, 23927, 11978 };87 88#define KXSD9_ZERO_G_OFFSET -204889 90/*91 * Regulator names92 */93static const char kxsd9_reg_vdd[] = "vdd";94static const char kxsd9_reg_iovdd[] = "iovdd";95 96static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro)97{98 int ret, i;99 struct kxsd9_state *st = iio_priv(indio_dev);100 bool foundit = false;101 102 for (i = 0; i < 4; i++)103 if (micro == kxsd9_micro_scales[i]) {104 foundit = true;105 break;106 }107 if (!foundit)108 return -EINVAL;109 110 ret = regmap_update_bits(st->map,111 KXSD9_REG_CTRL_C,112 KXSD9_CTRL_C_FS_MASK,113 i);114 if (ret < 0)115 goto error_ret;116 117 /* Cached scale when the sensor is powered down */118 st->scale = i;119 120error_ret:121 return ret;122}123 124static IIO_CONST_ATTR(accel_scale_available,125 KXSD9_SCALE_2G " "126 KXSD9_SCALE_4G " "127 KXSD9_SCALE_6G " "128 KXSD9_SCALE_8G);129 130static struct attribute *kxsd9_attributes[] = {131 &iio_const_attr_accel_scale_available.dev_attr.attr,132 NULL,133};134 135static int kxsd9_write_raw(struct iio_dev *indio_dev,136 struct iio_chan_spec const *chan,137 int val,138 int val2,139 long mask)140{141 int ret = -EINVAL;142 struct kxsd9_state *st = iio_priv(indio_dev);143 144 pm_runtime_get_sync(st->dev);145 146 if (mask == IIO_CHAN_INFO_SCALE) {147 /* Check no integer component */148 if (val)149 return -EINVAL;150 ret = kxsd9_write_scale(indio_dev, val2);151 }152 153 pm_runtime_mark_last_busy(st->dev);154 pm_runtime_put_autosuspend(st->dev);155 156 return ret;157}158 159static int kxsd9_read_raw(struct iio_dev *indio_dev,160 struct iio_chan_spec const *chan,161 int *val, int *val2, long mask)162{163 int ret = -EINVAL;164 struct kxsd9_state *st = iio_priv(indio_dev);165 unsigned int regval;166 __be16 raw_val;167 u16 nval;168 169 pm_runtime_get_sync(st->dev);170 171 switch (mask) {172 case IIO_CHAN_INFO_RAW:173 ret = regmap_bulk_read(st->map, chan->address, &raw_val,174 sizeof(raw_val));175 if (ret)176 goto error_ret;177 nval = be16_to_cpu(raw_val);178 /* Only 12 bits are valid */179 nval >>= 4;180 *val = nval;181 ret = IIO_VAL_INT;182 break;183 case IIO_CHAN_INFO_OFFSET:184 /* This has a bias of -2048 */185 *val = KXSD9_ZERO_G_OFFSET;186 ret = IIO_VAL_INT;187 break;188 case IIO_CHAN_INFO_SCALE:189 ret = regmap_read(st->map,190 KXSD9_REG_CTRL_C,191 ®val);192 if (ret < 0)193 goto error_ret;194 *val = 0;195 *val2 = kxsd9_micro_scales[regval & KXSD9_CTRL_C_FS_MASK];196 ret = IIO_VAL_INT_PLUS_MICRO;197 break;198 }199 200error_ret:201 pm_runtime_mark_last_busy(st->dev);202 pm_runtime_put_autosuspend(st->dev);203 204 return ret;205};206 207static irqreturn_t kxsd9_trigger_handler(int irq, void *p)208{209 const struct iio_poll_func *pf = p;210 struct iio_dev *indio_dev = pf->indio_dev;211 struct kxsd9_state *st = iio_priv(indio_dev);212 /*213 * Ensure correct positioning and alignment of timestamp.214 * No need to zero initialize as all elements written.215 */216 struct {217 __be16 chan[4];218 s64 ts __aligned(8);219 } hw_values;220 int ret;221 222 ret = regmap_bulk_read(st->map,223 KXSD9_REG_X,224 hw_values.chan,225 sizeof(hw_values.chan));226 if (ret) {227 dev_err(st->dev, "error reading data: %d\n", ret);228 goto out;229 }230 231 iio_push_to_buffers_with_timestamp(indio_dev,232 &hw_values,233 iio_get_time_ns(indio_dev));234out:235 iio_trigger_notify_done(indio_dev->trig);236 237 return IRQ_HANDLED;238}239 240static int kxsd9_buffer_preenable(struct iio_dev *indio_dev)241{242 struct kxsd9_state *st = iio_priv(indio_dev);243 244 pm_runtime_get_sync(st->dev);245 246 return 0;247}248 249static int kxsd9_buffer_postdisable(struct iio_dev *indio_dev)250{251 struct kxsd9_state *st = iio_priv(indio_dev);252 253 pm_runtime_mark_last_busy(st->dev);254 pm_runtime_put_autosuspend(st->dev);255 256 return 0;257}258 259static const struct iio_buffer_setup_ops kxsd9_buffer_setup_ops = {260 .preenable = kxsd9_buffer_preenable,261 .postdisable = kxsd9_buffer_postdisable,262};263 264static const struct iio_mount_matrix *265kxsd9_get_mount_matrix(const struct iio_dev *indio_dev,266 const struct iio_chan_spec *chan)267{268 struct kxsd9_state *st = iio_priv(indio_dev);269 270 return &st->orientation;271}272 273static const struct iio_chan_spec_ext_info kxsd9_ext_info[] = {274 IIO_MOUNT_MATRIX(IIO_SHARED_BY_TYPE, kxsd9_get_mount_matrix),275 { },276};277 278#define KXSD9_ACCEL_CHAN(axis, index) \279 { \280 .type = IIO_ACCEL, \281 .modified = 1, \282 .channel2 = IIO_MOD_##axis, \283 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \284 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \285 BIT(IIO_CHAN_INFO_OFFSET), \286 .ext_info = kxsd9_ext_info, \287 .address = KXSD9_REG_##axis, \288 .scan_index = index, \289 .scan_type = { \290 .sign = 'u', \291 .realbits = 12, \292 .storagebits = 16, \293 .shift = 4, \294 .endianness = IIO_BE, \295 }, \296 }297 298static const struct iio_chan_spec kxsd9_channels[] = {299 KXSD9_ACCEL_CHAN(X, 0),300 KXSD9_ACCEL_CHAN(Y, 1),301 KXSD9_ACCEL_CHAN(Z, 2),302 {303 .type = IIO_VOLTAGE,304 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),305 .indexed = 1,306 .address = KXSD9_REG_AUX,307 .scan_index = 3,308 .scan_type = {309 .sign = 'u',310 .realbits = 12,311 .storagebits = 16,312 .shift = 4,313 .endianness = IIO_BE,314 },315 },316 IIO_CHAN_SOFT_TIMESTAMP(4),317};318 319static const struct attribute_group kxsd9_attribute_group = {320 .attrs = kxsd9_attributes,321};322 323static int kxsd9_power_up(struct kxsd9_state *st)324{325 int ret;326 327 /* Enable the regulators */328 ret = regulator_bulk_enable(ARRAY_SIZE(st->regs), st->regs);329 if (ret) {330 dev_err(st->dev, "Cannot enable regulators\n");331 return ret;332 }333 334 /* Power up */335 ret = regmap_write(st->map,336 KXSD9_REG_CTRL_B,337 KXSD9_CTRL_B_ENABLE);338 if (ret)339 return ret;340 341 /*342 * Set 1000Hz LPF, 2g fullscale, motion wakeup threshold 1g,343 * latched wakeup344 */345 ret = regmap_write(st->map,346 KXSD9_REG_CTRL_C,347 KXSD9_CTRL_C_LP_1000HZ |348 KXSD9_CTRL_C_MOT_LEV |349 KXSD9_CTRL_C_MOT_LAT |350 st->scale);351 if (ret)352 return ret;353 354 /*355 * Power-up time depends on the LPF setting, but typ 15.9 ms, let's356 * set 20 ms to allow for some slack.357 */358 msleep(20);359 360 return 0;361};362 363static int kxsd9_power_down(struct kxsd9_state *st)364{365 int ret;366 367 /*368 * Set into low power mode - since there may be more users of the369 * regulators this is the first step of the power saving: it will370 * make sure we conserve power even if there are others users on the371 * regulators.372 */373 ret = regmap_clear_bits(st->map, KXSD9_REG_CTRL_B, KXSD9_CTRL_B_ENABLE);374 if (ret)375 return ret;376 377 /* Disable the regulators */378 ret = regulator_bulk_disable(ARRAY_SIZE(st->regs), st->regs);379 if (ret) {380 dev_err(st->dev, "Cannot disable regulators\n");381 return ret;382 }383 384 return 0;385}386 387static const struct iio_info kxsd9_info = {388 .read_raw = &kxsd9_read_raw,389 .write_raw = &kxsd9_write_raw,390 .attrs = &kxsd9_attribute_group,391};392 393/* Four channels apart from timestamp, scan mask = 0x0f */394static const unsigned long kxsd9_scan_masks[] = { 0xf, 0 };395 396int kxsd9_common_probe(struct device *dev,397 struct regmap *map,398 const char *name)399{400 struct iio_dev *indio_dev;401 struct kxsd9_state *st;402 int ret;403 404 indio_dev = devm_iio_device_alloc(dev, sizeof(*st));405 if (!indio_dev)406 return -ENOMEM;407 408 st = iio_priv(indio_dev);409 st->dev = dev;410 st->map = map;411 412 indio_dev->channels = kxsd9_channels;413 indio_dev->num_channels = ARRAY_SIZE(kxsd9_channels);414 indio_dev->name = name;415 indio_dev->info = &kxsd9_info;416 indio_dev->modes = INDIO_DIRECT_MODE;417 indio_dev->available_scan_masks = kxsd9_scan_masks;418 419 /* Read the mounting matrix, if present */420 ret = iio_read_mount_matrix(dev, &st->orientation);421 if (ret)422 return ret;423 424 /* Fetch and turn on regulators */425 st->regs[0].supply = kxsd9_reg_vdd;426 st->regs[1].supply = kxsd9_reg_iovdd;427 ret = devm_regulator_bulk_get(dev,428 ARRAY_SIZE(st->regs),429 st->regs);430 if (ret) {431 dev_err(dev, "Cannot get regulators\n");432 return ret;433 }434 /* Default scaling */435 st->scale = KXSD9_CTRL_C_FS_2G;436 437 kxsd9_power_up(st);438 439 ret = iio_triggered_buffer_setup(indio_dev,440 iio_pollfunc_store_time,441 kxsd9_trigger_handler,442 &kxsd9_buffer_setup_ops);443 if (ret) {444 dev_err(dev, "triggered buffer setup failed\n");445 goto err_power_down;446 }447 448 ret = iio_device_register(indio_dev);449 if (ret)450 goto err_cleanup_buffer;451 452 dev_set_drvdata(dev, indio_dev);453 454 /* Enable runtime PM */455 pm_runtime_get_noresume(dev);456 pm_runtime_set_active(dev);457 pm_runtime_enable(dev);458 /*459 * Set autosuspend to two orders of magnitude larger than the460 * start-up time. 20ms start-up time means 2000ms autosuspend,461 * i.e. 2 seconds.462 */463 pm_runtime_set_autosuspend_delay(dev, 2000);464 pm_runtime_use_autosuspend(dev);465 pm_runtime_put(dev);466 467 return 0;468 469err_cleanup_buffer:470 iio_triggered_buffer_cleanup(indio_dev);471err_power_down:472 kxsd9_power_down(st);473 474 return ret;475}476EXPORT_SYMBOL_NS(kxsd9_common_probe, IIO_KXSD9);477 478void kxsd9_common_remove(struct device *dev)479{480 struct iio_dev *indio_dev = dev_get_drvdata(dev);481 struct kxsd9_state *st = iio_priv(indio_dev);482 483 iio_triggered_buffer_cleanup(indio_dev);484 iio_device_unregister(indio_dev);485 pm_runtime_get_sync(dev);486 pm_runtime_put_noidle(dev);487 pm_runtime_disable(dev);488 kxsd9_power_down(st);489}490EXPORT_SYMBOL_NS(kxsd9_common_remove, IIO_KXSD9);491 492static int kxsd9_runtime_suspend(struct device *dev)493{494 struct iio_dev *indio_dev = dev_get_drvdata(dev);495 struct kxsd9_state *st = iio_priv(indio_dev);496 497 return kxsd9_power_down(st);498}499 500static int kxsd9_runtime_resume(struct device *dev)501{502 struct iio_dev *indio_dev = dev_get_drvdata(dev);503 struct kxsd9_state *st = iio_priv(indio_dev);504 505 return kxsd9_power_up(st);506}507 508EXPORT_NS_RUNTIME_DEV_PM_OPS(kxsd9_dev_pm_ops, kxsd9_runtime_suspend,509 kxsd9_runtime_resume, NULL, IIO_KXSD9);510 511MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");512MODULE_DESCRIPTION("Kionix KXSD9 driver");513MODULE_LICENSE("GPL v2");514