1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * ADXL313 3-Axis Digital Accelerometer 4 * 5 * Copyright (c) 2021 Lucas Stankus <lucas.p.stankus@gmail.com> 6 * 7 * Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ADXL313.pdf 8 */ 9 10 #include <linux/bitfield.h> 11 #include <linux/module.h> 12 #include <linux/regmap.h> 13 14 #include "adxl313.h" 15 16 static const struct regmap_range adxl312_readable_reg_range[] = { 17 regmap_reg_range(ADXL313_REG_DEVID0, ADXL313_REG_DEVID0), 18 regmap_reg_range(ADXL313_REG_OFS_AXIS(0), ADXL313_REG_OFS_AXIS(2)), 19 regmap_reg_range(ADXL313_REG_THRESH_ACT, ADXL313_REG_ACT_INACT_CTL), 20 regmap_reg_range(ADXL313_REG_BW_RATE, ADXL313_REG_FIFO_STATUS), 21 }; 22 23 static const struct regmap_range adxl313_readable_reg_range[] = { 24 regmap_reg_range(ADXL313_REG_DEVID0, ADXL313_REG_XID), 25 regmap_reg_range(ADXL313_REG_SOFT_RESET, ADXL313_REG_SOFT_RESET), 26 regmap_reg_range(ADXL313_REG_OFS_AXIS(0), ADXL313_REG_OFS_AXIS(2)), 27 regmap_reg_range(ADXL313_REG_THRESH_ACT, ADXL313_REG_ACT_INACT_CTL), 28 regmap_reg_range(ADXL313_REG_BW_RATE, ADXL313_REG_FIFO_STATUS), 29 }; 30 31 const struct regmap_access_table adxl312_readable_regs_table = { 32 .yes_ranges = adxl312_readable_reg_range, 33 .n_yes_ranges = ARRAY_SIZE(adxl312_readable_reg_range), 34 }; 35 EXPORT_SYMBOL_NS_GPL(adxl312_readable_regs_table, IIO_ADXL313); 36 37 const struct regmap_access_table adxl313_readable_regs_table = { 38 .yes_ranges = adxl313_readable_reg_range, 39 .n_yes_ranges = ARRAY_SIZE(adxl313_readable_reg_range), 40 }; 41 EXPORT_SYMBOL_NS_GPL(adxl313_readable_regs_table, IIO_ADXL313); 42 43 const struct regmap_access_table adxl314_readable_regs_table = { 44 .yes_ranges = adxl312_readable_reg_range, 45 .n_yes_ranges = ARRAY_SIZE(adxl312_readable_reg_range), 46 }; 47 EXPORT_SYMBOL_NS_GPL(adxl314_readable_regs_table, IIO_ADXL313); 48 49 static int adxl312_check_id(struct device *dev, 50 struct adxl313_data *data) 51 { 52 unsigned int regval; 53 int ret; 54 55 ret = regmap_read(data->regmap, ADXL313_REG_DEVID0, ®val); 56 if (ret) 57 return ret; 58 59 if (regval != ADXL313_DEVID0_ADXL312_314) 60 dev_warn(dev, "Invalid manufacturer ID: %#02x\n", regval); 61 62 return 0; 63 } 64 65 static int adxl313_check_id(struct device *dev, 66 struct adxl313_data *data) 67 { 68 unsigned int regval; 69 int ret; 70 71 ret = regmap_read(data->regmap, ADXL313_REG_DEVID0, ®val); 72 if (ret) 73 return ret; 74 75 if (regval != ADXL313_DEVID0) 76 dev_warn(dev, "Invalid manufacturer ID: 0x%02x\n", regval); 77 78 /* Check DEVID1 and PARTID */ 79 if (regval == ADXL313_DEVID0) { 80 ret = regmap_read(data->regmap, ADXL313_REG_DEVID1, ®val); 81 if (ret) 82 return ret; 83 84 if (regval != ADXL313_DEVID1) 85 dev_warn(dev, "Invalid mems ID: 0x%02x\n", regval); 86 87 ret = regmap_read(data->regmap, ADXL313_REG_PARTID, ®val); 88 if (ret) 89 return ret; 90 91 if (regval != ADXL313_PARTID) 92 dev_warn(dev, "Invalid device ID: 0x%02x\n", regval); 93 } 94 95 return 0; 96 } 97 98 const struct adxl313_chip_info adxl31x_chip_info[] = { 99 [ADXL312] = { 100 .name = "adxl312", 101 .type = ADXL312, 102 .scale_factor = 28425072, 103 .variable_range = true, 104 .soft_reset = false, 105 .check_id = &adxl312_check_id, 106 }, 107 [ADXL313] = { 108 .name = "adxl313", 109 .type = ADXL313, 110 .scale_factor = 9576806, 111 .variable_range = true, 112 .soft_reset = true, 113 .check_id = &adxl313_check_id, 114 }, 115 [ADXL314] = { 116 .name = "adxl314", 117 .type = ADXL314, 118 .scale_factor = 478858719, 119 .variable_range = false, 120 .soft_reset = false, 121 .check_id = &adxl312_check_id, 122 }, 123 }; 124 EXPORT_SYMBOL_NS_GPL(adxl31x_chip_info, IIO_ADXL313); 125 126 static const struct regmap_range adxl312_writable_reg_range[] = { 127 regmap_reg_range(ADXL313_REG_OFS_AXIS(0), ADXL313_REG_OFS_AXIS(2)), 128 regmap_reg_range(ADXL313_REG_THRESH_ACT, ADXL313_REG_ACT_INACT_CTL), 129 regmap_reg_range(ADXL313_REG_BW_RATE, ADXL313_REG_INT_MAP), 130 regmap_reg_range(ADXL313_REG_DATA_FORMAT, ADXL313_REG_DATA_FORMAT), 131 regmap_reg_range(ADXL313_REG_FIFO_CTL, ADXL313_REG_FIFO_CTL), 132 }; 133 134 static const struct regmap_range adxl313_writable_reg_range[] = { 135 regmap_reg_range(ADXL313_REG_SOFT_RESET, ADXL313_REG_SOFT_RESET), 136 regmap_reg_range(ADXL313_REG_OFS_AXIS(0), ADXL313_REG_OFS_AXIS(2)), 137 regmap_reg_range(ADXL313_REG_THRESH_ACT, ADXL313_REG_ACT_INACT_CTL), 138 regmap_reg_range(ADXL313_REG_BW_RATE, ADXL313_REG_INT_MAP), 139 regmap_reg_range(ADXL313_REG_DATA_FORMAT, ADXL313_REG_DATA_FORMAT), 140 regmap_reg_range(ADXL313_REG_FIFO_CTL, ADXL313_REG_FIFO_CTL), 141 }; 142 143 const struct regmap_access_table adxl312_writable_regs_table = { 144 .yes_ranges = adxl312_writable_reg_range, 145 .n_yes_ranges = ARRAY_SIZE(adxl312_writable_reg_range), 146 }; 147 EXPORT_SYMBOL_NS_GPL(adxl312_writable_regs_table, IIO_ADXL313); 148 149 const struct regmap_access_table adxl313_writable_regs_table = { 150 .yes_ranges = adxl313_writable_reg_range, 151 .n_yes_ranges = ARRAY_SIZE(adxl313_writable_reg_range), 152 }; 153 EXPORT_SYMBOL_NS_GPL(adxl313_writable_regs_table, IIO_ADXL313); 154 155 const struct regmap_access_table adxl314_writable_regs_table = { 156 .yes_ranges = adxl312_writable_reg_range, 157 .n_yes_ranges = ARRAY_SIZE(adxl312_writable_reg_range), 158 }; 159 EXPORT_SYMBOL_NS_GPL(adxl314_writable_regs_table, IIO_ADXL313); 160 161 static const int adxl313_odr_freqs[][2] = { 162 [0] = { 6, 250000 }, 163 [1] = { 12, 500000 }, 164 [2] = { 25, 0 }, 165 [3] = { 50, 0 }, 166 [4] = { 100, 0 }, 167 [5] = { 200, 0 }, 168 [6] = { 400, 0 }, 169 [7] = { 800, 0 }, 170 [8] = { 1600, 0 }, 171 [9] = { 3200, 0 }, 172 }; 173 174 #define ADXL313_ACCEL_CHANNEL(index, axis) { \ 175 .type = IIO_ACCEL, \ 176 .address = index, \ 177 .modified = 1, \ 178 .channel2 = IIO_MOD_##axis, \ 179 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 180 BIT(IIO_CHAN_INFO_CALIBBIAS), \ 181 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 182 BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 183 .info_mask_shared_by_type_available = \ 184 BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 185 .scan_type = { \ 186 .realbits = 13, \ 187 }, \ 188 } 189 190 static const struct iio_chan_spec adxl313_channels[] = { 191 ADXL313_ACCEL_CHANNEL(0, X), 192 ADXL313_ACCEL_CHANNEL(1, Y), 193 ADXL313_ACCEL_CHANNEL(2, Z), 194 }; 195 196 static int adxl313_set_odr(struct adxl313_data *data, 197 unsigned int freq1, unsigned int freq2) 198 { 199 unsigned int i; 200 201 for (i = 0; i < ARRAY_SIZE(adxl313_odr_freqs); i++) { 202 if (adxl313_odr_freqs[i][0] == freq1 && 203 adxl313_odr_freqs[i][1] == freq2) 204 break; 205 } 206 207 if (i == ARRAY_SIZE(adxl313_odr_freqs)) 208 return -EINVAL; 209 210 return regmap_update_bits(data->regmap, ADXL313_REG_BW_RATE, 211 ADXL313_RATE_MSK, 212 FIELD_PREP(ADXL313_RATE_MSK, ADXL313_RATE_BASE + i)); 213 } 214 215 static int adxl313_read_axis(struct adxl313_data *data, 216 struct iio_chan_spec const *chan) 217 { 218 int ret; 219 220 mutex_lock(&data->lock); 221 222 ret = regmap_bulk_read(data->regmap, 223 ADXL313_REG_DATA_AXIS(chan->address), 224 &data->transf_buf, sizeof(data->transf_buf)); 225 if (ret) 226 goto unlock_ret; 227 228 ret = le16_to_cpu(data->transf_buf); 229 230 unlock_ret: 231 mutex_unlock(&data->lock); 232 return ret; 233 } 234 235 static int adxl313_read_freq_avail(struct iio_dev *indio_dev, 236 struct iio_chan_spec const *chan, 237 const int **vals, int *type, int *length, 238 long mask) 239 { 240 switch (mask) { 241 case IIO_CHAN_INFO_SAMP_FREQ: 242 *vals = (const int *)adxl313_odr_freqs; 243 *length = ARRAY_SIZE(adxl313_odr_freqs) * 2; 244 *type = IIO_VAL_INT_PLUS_MICRO; 245 return IIO_AVAIL_LIST; 246 default: 247 return -EINVAL; 248 } 249 } 250 251 static int adxl313_read_raw(struct iio_dev *indio_dev, 252 struct iio_chan_spec const *chan, 253 int *val, int *val2, long mask) 254 { 255 struct adxl313_data *data = iio_priv(indio_dev); 256 unsigned int regval; 257 int ret; 258 259 switch (mask) { 260 case IIO_CHAN_INFO_RAW: 261 ret = adxl313_read_axis(data, chan); 262 if (ret < 0) 263 return ret; 264 265 *val = sign_extend32(ret, chan->scan_type.realbits - 1); 266 return IIO_VAL_INT; 267 case IIO_CHAN_INFO_SCALE: 268 *val = 0; 269 270 *val2 = data->chip_info->scale_factor; 271 272 return IIO_VAL_INT_PLUS_NANO; 273 case IIO_CHAN_INFO_CALIBBIAS: 274 ret = regmap_read(data->regmap, 275 ADXL313_REG_OFS_AXIS(chan->address), ®val); 276 if (ret) 277 return ret; 278 279 /* 280 * 8-bit resolution at minimum range, that is 4x accel data scale 281 * factor at full resolution 282 */ 283 *val = sign_extend32(regval, 7) * 4; 284 return IIO_VAL_INT; 285 case IIO_CHAN_INFO_SAMP_FREQ: 286 ret = regmap_read(data->regmap, ADXL313_REG_BW_RATE, ®val); 287 if (ret) 288 return ret; 289 290 ret = FIELD_GET(ADXL313_RATE_MSK, regval) - ADXL313_RATE_BASE; 291 *val = adxl313_odr_freqs[ret][0]; 292 *val2 = adxl313_odr_freqs[ret][1]; 293 return IIO_VAL_INT_PLUS_MICRO; 294 default: 295 return -EINVAL; 296 } 297 } 298 299 static int adxl313_write_raw(struct iio_dev *indio_dev, 300 struct iio_chan_spec const *chan, 301 int val, int val2, long mask) 302 { 303 struct adxl313_data *data = iio_priv(indio_dev); 304 305 switch (mask) { 306 case IIO_CHAN_INFO_CALIBBIAS: 307 /* 308 * 8-bit resolution at minimum range, that is 4x accel data scale 309 * factor at full resolution 310 */ 311 if (clamp_val(val, -128 * 4, 127 * 4) != val) 312 return -EINVAL; 313 314 return regmap_write(data->regmap, 315 ADXL313_REG_OFS_AXIS(chan->address), 316 val / 4); 317 case IIO_CHAN_INFO_SAMP_FREQ: 318 return adxl313_set_odr(data, val, val2); 319 default: 320 return -EINVAL; 321 } 322 } 323 324 static const struct iio_info adxl313_info = { 325 .read_raw = adxl313_read_raw, 326 .write_raw = adxl313_write_raw, 327 .read_avail = adxl313_read_freq_avail, 328 }; 329 330 static int adxl313_setup(struct device *dev, struct adxl313_data *data, 331 int (*setup)(struct device *, struct regmap *)) 332 { 333 int ret; 334 335 /* 336 * If sw reset available, ensures the device is in a consistent 337 * state after start up 338 */ 339 if (data->chip_info->soft_reset) { 340 ret = regmap_write(data->regmap, ADXL313_REG_SOFT_RESET, 341 ADXL313_SOFT_RESET); 342 if (ret) 343 return ret; 344 } 345 346 if (setup) { 347 ret = setup(dev, data->regmap); 348 if (ret) 349 return ret; 350 } 351 352 ret = data->chip_info->check_id(dev, data); 353 if (ret) 354 return ret; 355 356 /* Sets the range to maximum, full resolution, if applicable */ 357 if (data->chip_info->variable_range) { 358 ret = regmap_update_bits(data->regmap, ADXL313_REG_DATA_FORMAT, 359 ADXL313_RANGE_MSK, 360 FIELD_PREP(ADXL313_RANGE_MSK, ADXL313_RANGE_MAX)); 361 if (ret) 362 return ret; 363 364 /* Enables full resolution */ 365 ret = regmap_update_bits(data->regmap, ADXL313_REG_DATA_FORMAT, 366 ADXL313_FULL_RES, ADXL313_FULL_RES); 367 if (ret) 368 return ret; 369 } 370 371 /* Enables measurement mode */ 372 return regmap_update_bits(data->regmap, ADXL313_REG_POWER_CTL, 373 ADXL313_POWER_CTL_MSK, 374 ADXL313_MEASUREMENT_MODE); 375 } 376 377 /** 378 * adxl313_core_probe() - probe and setup for adxl313 accelerometer 379 * @dev: Driver model representation of the device 380 * @regmap: Register map of the device 381 * @chip_info: Structure containing device specific data 382 * @setup: Setup routine to be executed right before the standard device 383 * setup, can also be set to NULL if not required 384 * 385 * Return: 0 on success, negative errno on error cases 386 */ 387 int adxl313_core_probe(struct device *dev, 388 struct regmap *regmap, 389 const struct adxl313_chip_info *chip_info, 390 int (*setup)(struct device *, struct regmap *)) 391 { 392 struct adxl313_data *data; 393 struct iio_dev *indio_dev; 394 int ret; 395 396 indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 397 if (!indio_dev) 398 return -ENOMEM; 399 400 data = iio_priv(indio_dev); 401 data->regmap = regmap; 402 data->chip_info = chip_info; 403 404 mutex_init(&data->lock); 405 406 indio_dev->name = chip_info->name; 407 indio_dev->info = &adxl313_info; 408 indio_dev->modes = INDIO_DIRECT_MODE; 409 indio_dev->channels = adxl313_channels; 410 indio_dev->num_channels = ARRAY_SIZE(adxl313_channels); 411 412 ret = adxl313_setup(dev, data, setup); 413 if (ret) { 414 dev_err(dev, "ADXL313 setup failed\n"); 415 return ret; 416 } 417 418 return devm_iio_device_register(dev, indio_dev); 419 } 420 EXPORT_SYMBOL_NS_GPL(adxl313_core_probe, IIO_ADXL313); 421 422 MODULE_AUTHOR("Lucas Stankus <lucas.p.stankus@gmail.com>"); 423 MODULE_DESCRIPTION("ADXL313 3-Axis Digital Accelerometer core driver"); 424 MODULE_LICENSE("GPL v2"); 425