Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * BMA220 Digital triaxial acceleration sensor driver
0004  *
0005  * Copyright (c) 2016,2020 Intel Corporation.
0006  */
0007 
0008 #include <linux/bits.h>
0009 #include <linux/kernel.h>
0010 #include <linux/mod_devicetable.h>
0011 #include <linux/module.h>
0012 #include <linux/spi/spi.h>
0013 
0014 #include <linux/iio/buffer.h>
0015 #include <linux/iio/iio.h>
0016 #include <linux/iio/sysfs.h>
0017 #include <linux/iio/trigger_consumer.h>
0018 #include <linux/iio/triggered_buffer.h>
0019 
0020 #define BMA220_REG_ID               0x00
0021 #define BMA220_REG_ACCEL_X          0x02
0022 #define BMA220_REG_ACCEL_Y          0x03
0023 #define BMA220_REG_ACCEL_Z          0x04
0024 #define BMA220_REG_RANGE            0x11
0025 #define BMA220_REG_SUSPEND          0x18
0026 
0027 #define BMA220_CHIP_ID              0xDD
0028 #define BMA220_READ_MASK            BIT(7)
0029 #define BMA220_RANGE_MASK           GENMASK(1, 0)
0030 #define BMA220_SUSPEND_SLEEP            0xFF
0031 #define BMA220_SUSPEND_WAKE         0x00
0032 
0033 #define BMA220_DEVICE_NAME          "bma220"
0034 
0035 #define BMA220_ACCEL_CHANNEL(index, reg, axis) {            \
0036     .type = IIO_ACCEL,                      \
0037     .address = reg,                         \
0038     .modified = 1,                          \
0039     .channel2 = IIO_MOD_##axis,                 \
0040     .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),           \
0041     .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),       \
0042     .scan_index = index,                        \
0043     .scan_type = {                          \
0044         .sign = 's',                        \
0045         .realbits = 6,                      \
0046         .storagebits = 8,                   \
0047         .shift = 2,                     \
0048         .endianness = IIO_CPU,                  \
0049     },                              \
0050 }
0051 
0052 enum bma220_axis {
0053     AXIS_X,
0054     AXIS_Y,
0055     AXIS_Z,
0056 };
0057 
0058 static const int bma220_scale_table[][2] = {
0059     {0, 623000}, {1, 248000}, {2, 491000}, {4, 983000},
0060 };
0061 
0062 struct bma220_data {
0063     struct spi_device *spi_device;
0064     struct mutex lock;
0065     struct {
0066         s8 chans[3];
0067         /* Ensure timestamp is naturally aligned. */
0068         s64 timestamp __aligned(8);
0069     } scan;
0070     u8 tx_buf[2] __aligned(IIO_DMA_MINALIGN);
0071 };
0072 
0073 static const struct iio_chan_spec bma220_channels[] = {
0074     BMA220_ACCEL_CHANNEL(0, BMA220_REG_ACCEL_X, X),
0075     BMA220_ACCEL_CHANNEL(1, BMA220_REG_ACCEL_Y, Y),
0076     BMA220_ACCEL_CHANNEL(2, BMA220_REG_ACCEL_Z, Z),
0077     IIO_CHAN_SOFT_TIMESTAMP(3),
0078 };
0079 
0080 static inline int bma220_read_reg(struct spi_device *spi, u8 reg)
0081 {
0082     return spi_w8r8(spi, reg | BMA220_READ_MASK);
0083 }
0084 
0085 static const unsigned long bma220_accel_scan_masks[] = {
0086     BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z),
0087     0
0088 };
0089 
0090 static irqreturn_t bma220_trigger_handler(int irq, void *p)
0091 {
0092     int ret;
0093     struct iio_poll_func *pf = p;
0094     struct iio_dev *indio_dev = pf->indio_dev;
0095     struct bma220_data *data = iio_priv(indio_dev);
0096     struct spi_device *spi = data->spi_device;
0097 
0098     mutex_lock(&data->lock);
0099     data->tx_buf[0] = BMA220_REG_ACCEL_X | BMA220_READ_MASK;
0100     ret = spi_write_then_read(spi, data->tx_buf, 1, &data->scan.chans,
0101                   ARRAY_SIZE(bma220_channels) - 1);
0102     if (ret < 0)
0103         goto err;
0104 
0105     iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
0106                        pf->timestamp);
0107 err:
0108     mutex_unlock(&data->lock);
0109     iio_trigger_notify_done(indio_dev->trig);
0110 
0111     return IRQ_HANDLED;
0112 }
0113 
0114 static int bma220_read_raw(struct iio_dev *indio_dev,
0115                struct iio_chan_spec const *chan,
0116                int *val, int *val2, long mask)
0117 {
0118     int ret;
0119     u8 range_idx;
0120     struct bma220_data *data = iio_priv(indio_dev);
0121 
0122     switch (mask) {
0123     case IIO_CHAN_INFO_RAW:
0124         ret = bma220_read_reg(data->spi_device, chan->address);
0125         if (ret < 0)
0126             return -EINVAL;
0127         *val = sign_extend32(ret >> chan->scan_type.shift,
0128                      chan->scan_type.realbits - 1);
0129         return IIO_VAL_INT;
0130     case IIO_CHAN_INFO_SCALE:
0131         ret = bma220_read_reg(data->spi_device, BMA220_REG_RANGE);
0132         if (ret < 0)
0133             return ret;
0134         range_idx = ret & BMA220_RANGE_MASK;
0135         *val = bma220_scale_table[range_idx][0];
0136         *val2 = bma220_scale_table[range_idx][1];
0137         return IIO_VAL_INT_PLUS_MICRO;
0138     }
0139 
0140     return -EINVAL;
0141 }
0142 
0143 static int bma220_write_raw(struct iio_dev *indio_dev,
0144                 struct iio_chan_spec const *chan,
0145                 int val, int val2, long mask)
0146 {
0147     int i;
0148     int ret;
0149     int index = -1;
0150     struct bma220_data *data = iio_priv(indio_dev);
0151 
0152     switch (mask) {
0153     case IIO_CHAN_INFO_SCALE:
0154         for (i = 0; i < ARRAY_SIZE(bma220_scale_table); i++)
0155             if (val == bma220_scale_table[i][0] &&
0156                 val2 == bma220_scale_table[i][1]) {
0157                 index = i;
0158                 break;
0159             }
0160         if (index < 0)
0161             return -EINVAL;
0162 
0163         mutex_lock(&data->lock);
0164         data->tx_buf[0] = BMA220_REG_RANGE;
0165         data->tx_buf[1] = index;
0166         ret = spi_write(data->spi_device, data->tx_buf,
0167                 sizeof(data->tx_buf));
0168         if (ret < 0)
0169             dev_err(&data->spi_device->dev,
0170                 "failed to set measurement range\n");
0171         mutex_unlock(&data->lock);
0172 
0173         return 0;
0174     }
0175 
0176     return -EINVAL;
0177 }
0178 
0179 static int bma220_read_avail(struct iio_dev *indio_dev,
0180                  struct iio_chan_spec const *chan,
0181                  const int **vals, int *type, int *length,
0182                  long mask)
0183 {
0184     switch (mask) {
0185     case IIO_CHAN_INFO_SCALE:
0186         *vals = (int *)bma220_scale_table;
0187         *type = IIO_VAL_INT_PLUS_MICRO;
0188         *length = ARRAY_SIZE(bma220_scale_table) * 2;
0189         return IIO_AVAIL_LIST;
0190     default:
0191         return -EINVAL;
0192     }
0193 }
0194 
0195 static const struct iio_info bma220_info = {
0196     .read_raw       = bma220_read_raw,
0197     .write_raw      = bma220_write_raw,
0198     .read_avail     = bma220_read_avail,
0199 };
0200 
0201 static int bma220_init(struct spi_device *spi)
0202 {
0203     int ret;
0204 
0205     ret = bma220_read_reg(spi, BMA220_REG_ID);
0206     if (ret != BMA220_CHIP_ID)
0207         return -ENODEV;
0208 
0209     /* Make sure the chip is powered on */
0210     ret = bma220_read_reg(spi, BMA220_REG_SUSPEND);
0211     if (ret == BMA220_SUSPEND_WAKE)
0212         ret = bma220_read_reg(spi, BMA220_REG_SUSPEND);
0213     if (ret < 0)
0214         return ret;
0215     if (ret == BMA220_SUSPEND_WAKE)
0216         return -EBUSY;
0217 
0218     return 0;
0219 }
0220 
0221 static int bma220_power(struct spi_device *spi, bool up)
0222 {
0223     int i, ret;
0224 
0225     /**
0226      * The chip can be suspended/woken up by a simple register read.
0227      * So, we need up to 2 register reads of the suspend register
0228      * to make sure that the device is in the desired state.
0229      */
0230     for (i = 0; i < 2; i++) {
0231         ret = bma220_read_reg(spi, BMA220_REG_SUSPEND);
0232         if (ret < 0)
0233             return ret;
0234 
0235         if (up && ret == BMA220_SUSPEND_SLEEP)
0236             return 0;
0237 
0238         if (!up && ret == BMA220_SUSPEND_WAKE)
0239             return 0;
0240     }
0241 
0242     return -EBUSY;
0243 }
0244 
0245 static void bma220_deinit(void *spi)
0246 {
0247     bma220_power(spi, false);
0248 }
0249 
0250 static int bma220_probe(struct spi_device *spi)
0251 {
0252     int ret;
0253     struct iio_dev *indio_dev;
0254     struct bma220_data *data;
0255 
0256     indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));
0257     if (!indio_dev) {
0258         dev_err(&spi->dev, "iio allocation failed!\n");
0259         return -ENOMEM;
0260     }
0261 
0262     data = iio_priv(indio_dev);
0263     data->spi_device = spi;
0264     mutex_init(&data->lock);
0265 
0266     indio_dev->info = &bma220_info;
0267     indio_dev->name = BMA220_DEVICE_NAME;
0268     indio_dev->modes = INDIO_DIRECT_MODE;
0269     indio_dev->channels = bma220_channels;
0270     indio_dev->num_channels = ARRAY_SIZE(bma220_channels);
0271     indio_dev->available_scan_masks = bma220_accel_scan_masks;
0272 
0273     ret = bma220_init(data->spi_device);
0274     if (ret)
0275         return ret;
0276 
0277     ret = devm_add_action_or_reset(&spi->dev, bma220_deinit, spi);
0278     if (ret)
0279         return ret;
0280 
0281     ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev,
0282                           iio_pollfunc_store_time,
0283                           bma220_trigger_handler, NULL);
0284     if (ret < 0) {
0285         dev_err(&spi->dev, "iio triggered buffer setup failed\n");
0286         return ret;
0287     }
0288 
0289     return devm_iio_device_register(&spi->dev, indio_dev);
0290 }
0291 
0292 static int bma220_suspend(struct device *dev)
0293 {
0294     struct spi_device *spi = to_spi_device(dev);
0295 
0296     return bma220_power(spi, false);
0297 }
0298 
0299 static int bma220_resume(struct device *dev)
0300 {
0301     struct spi_device *spi = to_spi_device(dev);
0302 
0303     return bma220_power(spi, true);
0304 }
0305 static DEFINE_SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume);
0306 
0307 static const struct spi_device_id bma220_spi_id[] = {
0308     {"bma220", 0},
0309     {}
0310 };
0311 
0312 static const struct acpi_device_id bma220_acpi_id[] = {
0313     {"BMA0220", 0},
0314     {}
0315 };
0316 MODULE_DEVICE_TABLE(spi, bma220_spi_id);
0317 
0318 static struct spi_driver bma220_driver = {
0319     .driver = {
0320         .name = "bma220_spi",
0321         .pm = pm_sleep_ptr(&bma220_pm_ops),
0322         .acpi_match_table = bma220_acpi_id,
0323     },
0324     .probe =            bma220_probe,
0325     .id_table =         bma220_spi_id,
0326 };
0327 module_spi_driver(bma220_driver);
0328 
0329 MODULE_AUTHOR("Tiberiu Breana <tiberiu.a.breana@intel.com>");
0330 MODULE_DESCRIPTION("BMA220 acceleration sensor driver");
0331 MODULE_LICENSE("GPL v2");