1 // SPDX-License-Identifier: GPL-2.0-only 2 /** 3 * BMA220 Digital triaxial acceleration sensor driver 4 * 5 * Copyright (c) 2016, Intel Corporation. 6 */ 7 8 #include <linux/acpi.h> 9 #include <linux/kernel.h> 10 #include <linux/module.h> 11 #include <linux/iio/buffer.h> 12 #include <linux/iio/iio.h> 13 #include <linux/iio/sysfs.h> 14 #include <linux/spi/spi.h> 15 #include <linux/iio/trigger_consumer.h> 16 #include <linux/iio/triggered_buffer.h> 17 18 #define BMA220_REG_ID 0x00 19 #define BMA220_REG_ACCEL_X 0x02 20 #define BMA220_REG_ACCEL_Y 0x03 21 #define BMA220_REG_ACCEL_Z 0x04 22 #define BMA220_REG_RANGE 0x11 23 #define BMA220_REG_SUSPEND 0x18 24 25 #define BMA220_CHIP_ID 0xDD 26 #define BMA220_READ_MASK 0x80 27 #define BMA220_RANGE_MASK 0x03 28 #define BMA220_DATA_SHIFT 2 29 #define BMA220_SUSPEND_SLEEP 0xFF 30 #define BMA220_SUSPEND_WAKE 0x00 31 32 #define BMA220_DEVICE_NAME "bma220" 33 #define BMA220_SCALE_AVAILABLE "0.623 1.248 2.491 4.983" 34 35 #define BMA220_ACCEL_CHANNEL(index, reg, axis) { \ 36 .type = IIO_ACCEL, \ 37 .address = reg, \ 38 .modified = 1, \ 39 .channel2 = IIO_MOD_##axis, \ 40 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 41 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 42 .scan_index = index, \ 43 .scan_type = { \ 44 .sign = 's', \ 45 .realbits = 6, \ 46 .storagebits = 8, \ 47 .shift = BMA220_DATA_SHIFT, \ 48 .endianness = IIO_CPU, \ 49 }, \ 50 } 51 52 enum bma220_axis { 53 AXIS_X, 54 AXIS_Y, 55 AXIS_Z, 56 }; 57 58 static IIO_CONST_ATTR(in_accel_scale_available, BMA220_SCALE_AVAILABLE); 59 60 static struct attribute *bma220_attributes[] = { 61 &iio_const_attr_in_accel_scale_available.dev_attr.attr, 62 NULL, 63 }; 64 65 static const struct attribute_group bma220_attribute_group = { 66 .attrs = bma220_attributes, 67 }; 68 69 static const int bma220_scale_table[][4] = { 70 {0, 623000}, {1, 248000}, {2, 491000}, {4, 983000} 71 }; 72 73 struct bma220_data { 74 struct spi_device *spi_device; 75 struct mutex lock; 76 s8 buffer[16]; /* 3x8-bit channels + 5x8 padding + 8x8 timestamp */ 77 u8 tx_buf[2] ____cacheline_aligned; 78 }; 79 80 static const struct iio_chan_spec bma220_channels[] = { 81 BMA220_ACCEL_CHANNEL(0, BMA220_REG_ACCEL_X, X), 82 BMA220_ACCEL_CHANNEL(1, BMA220_REG_ACCEL_Y, Y), 83 BMA220_ACCEL_CHANNEL(2, BMA220_REG_ACCEL_Z, Z), 84 IIO_CHAN_SOFT_TIMESTAMP(3), 85 }; 86 87 static inline int bma220_read_reg(struct spi_device *spi, u8 reg) 88 { 89 return spi_w8r8(spi, reg | BMA220_READ_MASK); 90 } 91 92 static const unsigned long bma220_accel_scan_masks[] = { 93 BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z), 94 0 95 }; 96 97 static irqreturn_t bma220_trigger_handler(int irq, void *p) 98 { 99 int ret; 100 struct iio_poll_func *pf = p; 101 struct iio_dev *indio_dev = pf->indio_dev; 102 struct bma220_data *data = iio_priv(indio_dev); 103 struct spi_device *spi = data->spi_device; 104 105 mutex_lock(&data->lock); 106 data->tx_buf[0] = BMA220_REG_ACCEL_X | BMA220_READ_MASK; 107 ret = spi_write_then_read(spi, data->tx_buf, 1, data->buffer, 108 ARRAY_SIZE(bma220_channels) - 1); 109 if (ret < 0) 110 goto err; 111 112 iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, 113 pf->timestamp); 114 err: 115 mutex_unlock(&data->lock); 116 iio_trigger_notify_done(indio_dev->trig); 117 118 return IRQ_HANDLED; 119 } 120 121 static int bma220_read_raw(struct iio_dev *indio_dev, 122 struct iio_chan_spec const *chan, 123 int *val, int *val2, long mask) 124 { 125 int ret; 126 u8 range_idx; 127 struct bma220_data *data = iio_priv(indio_dev); 128 129 switch (mask) { 130 case IIO_CHAN_INFO_RAW: 131 ret = bma220_read_reg(data->spi_device, chan->address); 132 if (ret < 0) 133 return -EINVAL; 134 *val = sign_extend32(ret >> BMA220_DATA_SHIFT, 5); 135 return IIO_VAL_INT; 136 case IIO_CHAN_INFO_SCALE: 137 ret = bma220_read_reg(data->spi_device, BMA220_REG_RANGE); 138 if (ret < 0) 139 return ret; 140 range_idx = ret & BMA220_RANGE_MASK; 141 *val = bma220_scale_table[range_idx][0]; 142 *val2 = bma220_scale_table[range_idx][1]; 143 return IIO_VAL_INT_PLUS_MICRO; 144 } 145 146 return -EINVAL; 147 } 148 149 static int bma220_write_raw(struct iio_dev *indio_dev, 150 struct iio_chan_spec const *chan, 151 int val, int val2, long mask) 152 { 153 int i; 154 int ret; 155 int index = -1; 156 struct bma220_data *data = iio_priv(indio_dev); 157 158 switch (mask) { 159 case IIO_CHAN_INFO_SCALE: 160 for (i = 0; i < ARRAY_SIZE(bma220_scale_table); i++) 161 if (val == bma220_scale_table[i][0] && 162 val2 == bma220_scale_table[i][1]) { 163 index = i; 164 break; 165 } 166 if (index < 0) 167 return -EINVAL; 168 169 mutex_lock(&data->lock); 170 data->tx_buf[0] = BMA220_REG_RANGE; 171 data->tx_buf[1] = index; 172 ret = spi_write(data->spi_device, data->tx_buf, 173 sizeof(data->tx_buf)); 174 if (ret < 0) 175 dev_err(&data->spi_device->dev, 176 "failed to set measurement range\n"); 177 mutex_unlock(&data->lock); 178 179 return 0; 180 } 181 182 return -EINVAL; 183 } 184 185 static const struct iio_info bma220_info = { 186 .read_raw = bma220_read_raw, 187 .write_raw = bma220_write_raw, 188 .attrs = &bma220_attribute_group, 189 }; 190 191 static int bma220_init(struct spi_device *spi) 192 { 193 int ret; 194 195 ret = bma220_read_reg(spi, BMA220_REG_ID); 196 if (ret != BMA220_CHIP_ID) 197 return -ENODEV; 198 199 /* Make sure the chip is powered on */ 200 ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); 201 if (ret < 0) 202 return ret; 203 else if (ret == BMA220_SUSPEND_WAKE) 204 return bma220_read_reg(spi, BMA220_REG_SUSPEND); 205 206 return 0; 207 } 208 209 static int bma220_deinit(struct spi_device *spi) 210 { 211 int ret; 212 213 /* Make sure the chip is powered off */ 214 ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); 215 if (ret < 0) 216 return ret; 217 else if (ret == BMA220_SUSPEND_SLEEP) 218 return bma220_read_reg(spi, BMA220_REG_SUSPEND); 219 220 return 0; 221 } 222 223 static int bma220_probe(struct spi_device *spi) 224 { 225 int ret; 226 struct iio_dev *indio_dev; 227 struct bma220_data *data; 228 229 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data)); 230 if (!indio_dev) { 231 dev_err(&spi->dev, "iio allocation failed!\n"); 232 return -ENOMEM; 233 } 234 235 data = iio_priv(indio_dev); 236 data->spi_device = spi; 237 spi_set_drvdata(spi, indio_dev); 238 mutex_init(&data->lock); 239 240 indio_dev->dev.parent = &spi->dev; 241 indio_dev->info = &bma220_info; 242 indio_dev->name = BMA220_DEVICE_NAME; 243 indio_dev->modes = INDIO_DIRECT_MODE; 244 indio_dev->channels = bma220_channels; 245 indio_dev->num_channels = ARRAY_SIZE(bma220_channels); 246 indio_dev->available_scan_masks = bma220_accel_scan_masks; 247 248 ret = bma220_init(data->spi_device); 249 if (ret < 0) 250 return ret; 251 252 ret = iio_triggered_buffer_setup(indio_dev, iio_pollfunc_store_time, 253 bma220_trigger_handler, NULL); 254 if (ret < 0) { 255 dev_err(&spi->dev, "iio triggered buffer setup failed\n"); 256 goto err_suspend; 257 } 258 259 ret = iio_device_register(indio_dev); 260 if (ret < 0) { 261 dev_err(&spi->dev, "iio_device_register failed\n"); 262 iio_triggered_buffer_cleanup(indio_dev); 263 goto err_suspend; 264 } 265 266 return 0; 267 268 err_suspend: 269 return bma220_deinit(spi); 270 } 271 272 static int bma220_remove(struct spi_device *spi) 273 { 274 struct iio_dev *indio_dev = spi_get_drvdata(spi); 275 276 iio_device_unregister(indio_dev); 277 iio_triggered_buffer_cleanup(indio_dev); 278 279 return bma220_deinit(spi); 280 } 281 282 #ifdef CONFIG_PM_SLEEP 283 static int bma220_suspend(struct device *dev) 284 { 285 struct bma220_data *data = 286 iio_priv(spi_get_drvdata(to_spi_device(dev))); 287 288 /* The chip can be suspended/woken up by a simple register read. */ 289 return bma220_read_reg(data->spi_device, BMA220_REG_SUSPEND); 290 } 291 292 static int bma220_resume(struct device *dev) 293 { 294 struct bma220_data *data = 295 iio_priv(spi_get_drvdata(to_spi_device(dev))); 296 297 return bma220_read_reg(data->spi_device, BMA220_REG_SUSPEND); 298 } 299 300 static SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume); 301 302 #define BMA220_PM_OPS (&bma220_pm_ops) 303 #else 304 #define BMA220_PM_OPS NULL 305 #endif 306 307 static const struct spi_device_id bma220_spi_id[] = { 308 {"bma220", 0}, 309 {} 310 }; 311 312 static const struct acpi_device_id bma220_acpi_id[] = { 313 {"BMA0220", 0}, 314 {} 315 }; 316 317 MODULE_DEVICE_TABLE(spi, bma220_spi_id); 318 319 static struct spi_driver bma220_driver = { 320 .driver = { 321 .name = "bma220_spi", 322 .pm = BMA220_PM_OPS, 323 .acpi_match_table = ACPI_PTR(bma220_acpi_id), 324 }, 325 .probe = bma220_probe, 326 .remove = bma220_remove, 327 .id_table = bma220_spi_id, 328 }; 329 330 module_spi_driver(bma220_driver); 331 332 MODULE_AUTHOR("Tiberiu Breana <tiberiu.a.breana@intel.com>"); 333 MODULE_DESCRIPTION("BMA220 acceleration sensor driver"); 334 MODULE_LICENSE("GPL v2"); 335