Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * kxsd9.c  simple support for the Kionix KXSD9 3D
0004  *      accelerometer.
0005  *
0006  * Copyright (c) 2008-2009 Jonathan Cameron <jic23@kernel.org>
0007  *
0008  * The i2c interface is very similar, so shouldn't be a problem once
0009  * I have a suitable wire made up.
0010  *
0011  * TODO:    Support the motion detector
0012  */
0013 
0014 #include <linux/device.h>
0015 #include <linux/kernel.h>
0016 #include <linux/sysfs.h>
0017 #include <linux/slab.h>
0018 #include <linux/module.h>
0019 #include <linux/regmap.h>
0020 #include <linux/bitops.h>
0021 #include <linux/delay.h>
0022 #include <linux/regulator/consumer.h>
0023 #include <linux/pm_runtime.h>
0024 #include <linux/iio/iio.h>
0025 #include <linux/iio/sysfs.h>
0026 #include <linux/iio/buffer.h>
0027 #include <linux/iio/triggered_buffer.h>
0028 #include <linux/iio/trigger_consumer.h>
0029 
0030 #include "kxsd9.h"
0031 
0032 #define KXSD9_REG_X     0x00
0033 #define KXSD9_REG_Y     0x02
0034 #define KXSD9_REG_Z     0x04
0035 #define KXSD9_REG_AUX       0x06
0036 #define KXSD9_REG_RESET     0x0a
0037 #define KXSD9_REG_CTRL_C    0x0c
0038 
0039 #define KXSD9_CTRL_C_FS_MASK    0x03
0040 #define KXSD9_CTRL_C_FS_8G  0x00
0041 #define KXSD9_CTRL_C_FS_6G  0x01
0042 #define KXSD9_CTRL_C_FS_4G  0x02
0043 #define KXSD9_CTRL_C_FS_2G  0x03
0044 #define KXSD9_CTRL_C_MOT_LAT    BIT(3)
0045 #define KXSD9_CTRL_C_MOT_LEV    BIT(4)
0046 #define KXSD9_CTRL_C_LP_MASK    0xe0
0047 #define KXSD9_CTRL_C_LP_NONE    0x00
0048 #define KXSD9_CTRL_C_LP_2000HZC BIT(5)
0049 #define KXSD9_CTRL_C_LP_2000HZB BIT(6)
0050 #define KXSD9_CTRL_C_LP_2000HZA (BIT(5)|BIT(6))
0051 #define KXSD9_CTRL_C_LP_1000HZ  BIT(7)
0052 #define KXSD9_CTRL_C_LP_500HZ   (BIT(7)|BIT(5))
0053 #define KXSD9_CTRL_C_LP_100HZ   (BIT(7)|BIT(6))
0054 #define KXSD9_CTRL_C_LP_50HZ    (BIT(7)|BIT(6)|BIT(5))
0055 
0056 #define KXSD9_REG_CTRL_B    0x0d
0057 
0058 #define KXSD9_CTRL_B_CLK_HLD    BIT(7)
0059 #define KXSD9_CTRL_B_ENABLE BIT(6)
0060 #define KXSD9_CTRL_B_ST     BIT(5) /* Self-test */
0061 
0062 #define KXSD9_REG_CTRL_A    0x0e
0063 
0064 /**
0065  * struct kxsd9_state - device related storage
0066  * @dev: pointer to the parent device
0067  * @map: regmap to the device
0068  * @orientation: mounting matrix, flipped axis etc
0069  * @regs: regulators for this device, VDD and IOVDD
0070  * @scale: the current scaling setting
0071  */
0072 struct kxsd9_state {
0073     struct device *dev;
0074     struct regmap *map;
0075     struct iio_mount_matrix orientation;
0076     struct regulator_bulk_data regs[2];
0077     u8 scale;
0078 };
0079 
0080 #define KXSD9_SCALE_2G "0.011978"
0081 #define KXSD9_SCALE_4G "0.023927"
0082 #define KXSD9_SCALE_6G "0.035934"
0083 #define KXSD9_SCALE_8G "0.047853"
0084 
0085 /* reverse order */
0086 static const int kxsd9_micro_scales[4] = { 47853, 35934, 23927, 11978 };
0087 
0088 #define KXSD9_ZERO_G_OFFSET -2048
0089 
0090 /*
0091  * Regulator names
0092  */
0093 static const char kxsd9_reg_vdd[] = "vdd";
0094 static const char kxsd9_reg_iovdd[] = "iovdd";
0095 
0096 static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro)
0097 {
0098     int ret, i;
0099     struct kxsd9_state *st = iio_priv(indio_dev);
0100     bool foundit = false;
0101 
0102     for (i = 0; i < 4; i++)
0103         if (micro == kxsd9_micro_scales[i]) {
0104             foundit = true;
0105             break;
0106         }
0107     if (!foundit)
0108         return -EINVAL;
0109 
0110     ret = regmap_update_bits(st->map,
0111                  KXSD9_REG_CTRL_C,
0112                  KXSD9_CTRL_C_FS_MASK,
0113                  i);
0114     if (ret < 0)
0115         goto error_ret;
0116 
0117     /* Cached scale when the sensor is powered down */
0118     st->scale = i;
0119 
0120 error_ret:
0121     return ret;
0122 }
0123 
0124 static IIO_CONST_ATTR(accel_scale_available,
0125         KXSD9_SCALE_2G " "
0126         KXSD9_SCALE_4G " "
0127         KXSD9_SCALE_6G " "
0128         KXSD9_SCALE_8G);
0129 
0130 static struct attribute *kxsd9_attributes[] = {
0131     &iio_const_attr_accel_scale_available.dev_attr.attr,
0132     NULL,
0133 };
0134 
0135 static int kxsd9_write_raw(struct iio_dev *indio_dev,
0136                struct iio_chan_spec const *chan,
0137                int val,
0138                int val2,
0139                long mask)
0140 {
0141     int ret = -EINVAL;
0142     struct kxsd9_state *st = iio_priv(indio_dev);
0143 
0144     pm_runtime_get_sync(st->dev);
0145 
0146     if (mask == IIO_CHAN_INFO_SCALE) {
0147         /* Check no integer component */
0148         if (val)
0149             return -EINVAL;
0150         ret = kxsd9_write_scale(indio_dev, val2);
0151     }
0152 
0153     pm_runtime_mark_last_busy(st->dev);
0154     pm_runtime_put_autosuspend(st->dev);
0155 
0156     return ret;
0157 }
0158 
0159 static int kxsd9_read_raw(struct iio_dev *indio_dev,
0160               struct iio_chan_spec const *chan,
0161               int *val, int *val2, long mask)
0162 {
0163     int ret = -EINVAL;
0164     struct kxsd9_state *st = iio_priv(indio_dev);
0165     unsigned int regval;
0166     __be16 raw_val;
0167     u16 nval;
0168 
0169     pm_runtime_get_sync(st->dev);
0170 
0171     switch (mask) {
0172     case IIO_CHAN_INFO_RAW:
0173         ret = regmap_bulk_read(st->map, chan->address, &raw_val,
0174                        sizeof(raw_val));
0175         if (ret)
0176             goto error_ret;
0177         nval = be16_to_cpu(raw_val);
0178         /* Only 12 bits are valid */
0179         nval >>= 4;
0180         *val = nval;
0181         ret = IIO_VAL_INT;
0182         break;
0183     case IIO_CHAN_INFO_OFFSET:
0184         /* This has a bias of -2048 */
0185         *val = KXSD9_ZERO_G_OFFSET;
0186         ret = IIO_VAL_INT;
0187         break;
0188     case IIO_CHAN_INFO_SCALE:
0189         ret = regmap_read(st->map,
0190                   KXSD9_REG_CTRL_C,
0191                   &regval);
0192         if (ret < 0)
0193             goto error_ret;
0194         *val = 0;
0195         *val2 = kxsd9_micro_scales[regval & KXSD9_CTRL_C_FS_MASK];
0196         ret = IIO_VAL_INT_PLUS_MICRO;
0197         break;
0198     }
0199 
0200 error_ret:
0201     pm_runtime_mark_last_busy(st->dev);
0202     pm_runtime_put_autosuspend(st->dev);
0203 
0204     return ret;
0205 };
0206 
0207 static irqreturn_t kxsd9_trigger_handler(int irq, void *p)
0208 {
0209     const struct iio_poll_func *pf = p;
0210     struct iio_dev *indio_dev = pf->indio_dev;
0211     struct kxsd9_state *st = iio_priv(indio_dev);
0212     /*
0213      * Ensure correct positioning and alignment of timestamp.
0214      * No need to zero initialize as all elements written.
0215      */
0216     struct {
0217         __be16 chan[4];
0218         s64 ts __aligned(8);
0219     } hw_values;
0220     int ret;
0221 
0222     ret = regmap_bulk_read(st->map,
0223                    KXSD9_REG_X,
0224                    hw_values.chan,
0225                    sizeof(hw_values.chan));
0226     if (ret) {
0227         dev_err(st->dev, "error reading data: %d\n", ret);
0228         goto out;
0229     }
0230 
0231     iio_push_to_buffers_with_timestamp(indio_dev,
0232                        &hw_values,
0233                        iio_get_time_ns(indio_dev));
0234 out:
0235     iio_trigger_notify_done(indio_dev->trig);
0236 
0237     return IRQ_HANDLED;
0238 }
0239 
0240 static int kxsd9_buffer_preenable(struct iio_dev *indio_dev)
0241 {
0242     struct kxsd9_state *st = iio_priv(indio_dev);
0243 
0244     pm_runtime_get_sync(st->dev);
0245 
0246     return 0;
0247 }
0248 
0249 static int kxsd9_buffer_postdisable(struct iio_dev *indio_dev)
0250 {
0251     struct kxsd9_state *st = iio_priv(indio_dev);
0252 
0253     pm_runtime_mark_last_busy(st->dev);
0254     pm_runtime_put_autosuspend(st->dev);
0255 
0256     return 0;
0257 }
0258 
0259 static const struct iio_buffer_setup_ops kxsd9_buffer_setup_ops = {
0260     .preenable = kxsd9_buffer_preenable,
0261     .postdisable = kxsd9_buffer_postdisable,
0262 };
0263 
0264 static const struct iio_mount_matrix *
0265 kxsd9_get_mount_matrix(const struct iio_dev *indio_dev,
0266                const struct iio_chan_spec *chan)
0267 {
0268     struct kxsd9_state *st = iio_priv(indio_dev);
0269 
0270     return &st->orientation;
0271 }
0272 
0273 static const struct iio_chan_spec_ext_info kxsd9_ext_info[] = {
0274     IIO_MOUNT_MATRIX(IIO_SHARED_BY_TYPE, kxsd9_get_mount_matrix),
0275     { },
0276 };
0277 
0278 #define KXSD9_ACCEL_CHAN(axis, index)                       \
0279     {                               \
0280         .type = IIO_ACCEL,                  \
0281         .modified = 1,                      \
0282         .channel2 = IIO_MOD_##axis,             \
0283         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),       \
0284         .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |  \
0285                     BIT(IIO_CHAN_INFO_OFFSET),  \
0286         .ext_info = kxsd9_ext_info,             \
0287         .address = KXSD9_REG_##axis,                \
0288         .scan_index = index,                    \
0289         .scan_type = {                                          \
0290             .sign = 'u',                    \
0291             .realbits = 12,                 \
0292             .storagebits = 16,              \
0293             .shift = 4,                 \
0294             .endianness = IIO_BE,               \
0295         },                          \
0296     }
0297 
0298 static const struct iio_chan_spec kxsd9_channels[] = {
0299     KXSD9_ACCEL_CHAN(X, 0),
0300     KXSD9_ACCEL_CHAN(Y, 1),
0301     KXSD9_ACCEL_CHAN(Z, 2),
0302     {
0303         .type = IIO_VOLTAGE,
0304         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0305         .indexed = 1,
0306         .address = KXSD9_REG_AUX,
0307         .scan_index = 3,
0308         .scan_type = {
0309             .sign = 'u',
0310             .realbits = 12,
0311             .storagebits = 16,
0312             .shift = 4,
0313             .endianness = IIO_BE,
0314         },
0315     },
0316     IIO_CHAN_SOFT_TIMESTAMP(4),
0317 };
0318 
0319 static const struct attribute_group kxsd9_attribute_group = {
0320     .attrs = kxsd9_attributes,
0321 };
0322 
0323 static int kxsd9_power_up(struct kxsd9_state *st)
0324 {
0325     int ret;
0326 
0327     /* Enable the regulators */
0328     ret = regulator_bulk_enable(ARRAY_SIZE(st->regs), st->regs);
0329     if (ret) {
0330         dev_err(st->dev, "Cannot enable regulators\n");
0331         return ret;
0332     }
0333 
0334     /* Power up */
0335     ret = regmap_write(st->map,
0336                KXSD9_REG_CTRL_B,
0337                KXSD9_CTRL_B_ENABLE);
0338     if (ret)
0339         return ret;
0340 
0341     /*
0342      * Set 1000Hz LPF, 2g fullscale, motion wakeup threshold 1g,
0343      * latched wakeup
0344      */
0345     ret = regmap_write(st->map,
0346                KXSD9_REG_CTRL_C,
0347                KXSD9_CTRL_C_LP_1000HZ |
0348                KXSD9_CTRL_C_MOT_LEV |
0349                KXSD9_CTRL_C_MOT_LAT |
0350                st->scale);
0351     if (ret)
0352         return ret;
0353 
0354     /*
0355      * Power-up time depends on the LPF setting, but typ 15.9 ms, let's
0356      * set 20 ms to allow for some slack.
0357      */
0358     msleep(20);
0359 
0360     return 0;
0361 };
0362 
0363 static int kxsd9_power_down(struct kxsd9_state *st)
0364 {
0365     int ret;
0366 
0367     /*
0368      * Set into low power mode - since there may be more users of the
0369      * regulators this is the first step of the power saving: it will
0370      * make sure we conserve power even if there are others users on the
0371      * regulators.
0372      */
0373     ret = regmap_update_bits(st->map,
0374                  KXSD9_REG_CTRL_B,
0375                  KXSD9_CTRL_B_ENABLE,
0376                  0);
0377     if (ret)
0378         return ret;
0379 
0380     /* Disable the regulators */
0381     ret = regulator_bulk_disable(ARRAY_SIZE(st->regs), st->regs);
0382     if (ret) {
0383         dev_err(st->dev, "Cannot disable regulators\n");
0384         return ret;
0385     }
0386 
0387     return 0;
0388 }
0389 
0390 static const struct iio_info kxsd9_info = {
0391     .read_raw = &kxsd9_read_raw,
0392     .write_raw = &kxsd9_write_raw,
0393     .attrs = &kxsd9_attribute_group,
0394 };
0395 
0396 /* Four channels apart from timestamp, scan mask = 0x0f */
0397 static const unsigned long kxsd9_scan_masks[] = { 0xf, 0 };
0398 
0399 int kxsd9_common_probe(struct device *dev,
0400                struct regmap *map,
0401                const char *name)
0402 {
0403     struct iio_dev *indio_dev;
0404     struct kxsd9_state *st;
0405     int ret;
0406 
0407     indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
0408     if (!indio_dev)
0409         return -ENOMEM;
0410 
0411     st = iio_priv(indio_dev);
0412     st->dev = dev;
0413     st->map = map;
0414 
0415     indio_dev->channels = kxsd9_channels;
0416     indio_dev->num_channels = ARRAY_SIZE(kxsd9_channels);
0417     indio_dev->name = name;
0418     indio_dev->info = &kxsd9_info;
0419     indio_dev->modes = INDIO_DIRECT_MODE;
0420     indio_dev->available_scan_masks = kxsd9_scan_masks;
0421 
0422     /* Read the mounting matrix, if present */
0423     ret = iio_read_mount_matrix(dev, &st->orientation);
0424     if (ret)
0425         return ret;
0426 
0427     /* Fetch and turn on regulators */
0428     st->regs[0].supply = kxsd9_reg_vdd;
0429     st->regs[1].supply = kxsd9_reg_iovdd;
0430     ret = devm_regulator_bulk_get(dev,
0431                       ARRAY_SIZE(st->regs),
0432                       st->regs);
0433     if (ret) {
0434         dev_err(dev, "Cannot get regulators\n");
0435         return ret;
0436     }
0437     /* Default scaling */
0438     st->scale = KXSD9_CTRL_C_FS_2G;
0439 
0440     kxsd9_power_up(st);
0441 
0442     ret = iio_triggered_buffer_setup(indio_dev,
0443                      iio_pollfunc_store_time,
0444                      kxsd9_trigger_handler,
0445                      &kxsd9_buffer_setup_ops);
0446     if (ret) {
0447         dev_err(dev, "triggered buffer setup failed\n");
0448         goto err_power_down;
0449     }
0450 
0451     ret = iio_device_register(indio_dev);
0452     if (ret)
0453         goto err_cleanup_buffer;
0454 
0455     dev_set_drvdata(dev, indio_dev);
0456 
0457     /* Enable runtime PM */
0458     pm_runtime_get_noresume(dev);
0459     pm_runtime_set_active(dev);
0460     pm_runtime_enable(dev);
0461     /*
0462      * Set autosuspend to two orders of magnitude larger than the
0463      * start-up time. 20ms start-up time means 2000ms autosuspend,
0464      * i.e. 2 seconds.
0465      */
0466     pm_runtime_set_autosuspend_delay(dev, 2000);
0467     pm_runtime_use_autosuspend(dev);
0468     pm_runtime_put(dev);
0469 
0470     return 0;
0471 
0472 err_cleanup_buffer:
0473     iio_triggered_buffer_cleanup(indio_dev);
0474 err_power_down:
0475     kxsd9_power_down(st);
0476 
0477     return ret;
0478 }
0479 EXPORT_SYMBOL_NS(kxsd9_common_probe, IIO_KXSD9);
0480 
0481 void kxsd9_common_remove(struct device *dev)
0482 {
0483     struct iio_dev *indio_dev = dev_get_drvdata(dev);
0484     struct kxsd9_state *st = iio_priv(indio_dev);
0485 
0486     iio_triggered_buffer_cleanup(indio_dev);
0487     iio_device_unregister(indio_dev);
0488     pm_runtime_get_sync(dev);
0489     pm_runtime_put_noidle(dev);
0490     pm_runtime_disable(dev);
0491     kxsd9_power_down(st);
0492 }
0493 EXPORT_SYMBOL_NS(kxsd9_common_remove, IIO_KXSD9);
0494 
0495 static int kxsd9_runtime_suspend(struct device *dev)
0496 {
0497     struct iio_dev *indio_dev = dev_get_drvdata(dev);
0498     struct kxsd9_state *st = iio_priv(indio_dev);
0499 
0500     return kxsd9_power_down(st);
0501 }
0502 
0503 static int kxsd9_runtime_resume(struct device *dev)
0504 {
0505     struct iio_dev *indio_dev = dev_get_drvdata(dev);
0506     struct kxsd9_state *st = iio_priv(indio_dev);
0507 
0508     return kxsd9_power_up(st);
0509 }
0510 
0511 EXPORT_NS_RUNTIME_DEV_PM_OPS(kxsd9_dev_pm_ops, kxsd9_runtime_suspend,
0512                  kxsd9_runtime_resume, NULL, IIO_KXSD9);
0513 
0514 MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
0515 MODULE_DESCRIPTION("Kionix KXSD9 driver");
0516 MODULE_LICENSE("GPL v2");