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/iio/iio.h> 12 #include <linux/module.h> 13 #include <linux/regmap.h> 14 15 #include "adxl313.h" 16 17 static const struct regmap_range adxl313_readable_reg_range[] = { 18 regmap_reg_range(ADXL313_REG_DEVID0, ADXL313_REG_XID), 19 regmap_reg_range(ADXL313_REG_SOFT_RESET, ADXL313_REG_SOFT_RESET), 20 regmap_reg_range(ADXL313_REG_OFS_AXIS(0), ADXL313_REG_OFS_AXIS(2)), 21 regmap_reg_range(ADXL313_REG_THRESH_ACT, ADXL313_REG_ACT_INACT_CTL), 22 regmap_reg_range(ADXL313_REG_BW_RATE, ADXL313_REG_FIFO_STATUS), 23 }; 24 25 const struct regmap_access_table adxl313_readable_regs_table = { 26 .yes_ranges = adxl313_readable_reg_range, 27 .n_yes_ranges = ARRAY_SIZE(adxl313_readable_reg_range), 28 }; 29 EXPORT_SYMBOL_NS_GPL(adxl313_readable_regs_table, IIO_ADXL313); 30 31 static const struct regmap_range adxl313_writable_reg_range[] = { 32 regmap_reg_range(ADXL313_REG_SOFT_RESET, ADXL313_REG_SOFT_RESET), 33 regmap_reg_range(ADXL313_REG_OFS_AXIS(0), ADXL313_REG_OFS_AXIS(2)), 34 regmap_reg_range(ADXL313_REG_THRESH_ACT, ADXL313_REG_ACT_INACT_CTL), 35 regmap_reg_range(ADXL313_REG_BW_RATE, ADXL313_REG_INT_MAP), 36 regmap_reg_range(ADXL313_REG_DATA_FORMAT, ADXL313_REG_DATA_FORMAT), 37 regmap_reg_range(ADXL313_REG_FIFO_CTL, ADXL313_REG_FIFO_CTL), 38 }; 39 40 const struct regmap_access_table adxl313_writable_regs_table = { 41 .yes_ranges = adxl313_writable_reg_range, 42 .n_yes_ranges = ARRAY_SIZE(adxl313_writable_reg_range), 43 }; 44 EXPORT_SYMBOL_NS_GPL(adxl313_writable_regs_table, IIO_ADXL313); 45 46 struct adxl313_data { 47 struct regmap *regmap; 48 struct mutex lock; /* lock to protect transf_buf */ 49 __le16 transf_buf ____cacheline_aligned; 50 }; 51 52 static const int adxl313_odr_freqs[][2] = { 53 [0] = { 6, 250000 }, 54 [1] = { 12, 500000 }, 55 [2] = { 25, 0 }, 56 [3] = { 50, 0 }, 57 [4] = { 100, 0 }, 58 [5] = { 200, 0 }, 59 [6] = { 400, 0 }, 60 [7] = { 800, 0 }, 61 [8] = { 1600, 0 }, 62 [9] = { 3200, 0 }, 63 }; 64 65 #define ADXL313_ACCEL_CHANNEL(index, axis) { \ 66 .type = IIO_ACCEL, \ 67 .address = index, \ 68 .modified = 1, \ 69 .channel2 = IIO_MOD_##axis, \ 70 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 71 BIT(IIO_CHAN_INFO_CALIBBIAS), \ 72 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 73 BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 74 .info_mask_shared_by_type_available = \ 75 BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 76 .scan_type = { \ 77 .realbits = 13, \ 78 }, \ 79 } 80 81 static const struct iio_chan_spec adxl313_channels[] = { 82 ADXL313_ACCEL_CHANNEL(0, X), 83 ADXL313_ACCEL_CHANNEL(1, Y), 84 ADXL313_ACCEL_CHANNEL(2, Z), 85 }; 86 87 static int adxl313_set_odr(struct adxl313_data *data, 88 unsigned int freq1, unsigned int freq2) 89 { 90 unsigned int i; 91 92 for (i = 0; i < ARRAY_SIZE(adxl313_odr_freqs); i++) { 93 if (adxl313_odr_freqs[i][0] == freq1 && 94 adxl313_odr_freqs[i][1] == freq2) 95 break; 96 } 97 98 if (i == ARRAY_SIZE(adxl313_odr_freqs)) 99 return -EINVAL; 100 101 return regmap_update_bits(data->regmap, ADXL313_REG_BW_RATE, 102 ADXL313_RATE_MSK, 103 FIELD_PREP(ADXL313_RATE_MSK, ADXL313_RATE_BASE + i)); 104 } 105 106 static int adxl313_read_axis(struct adxl313_data *data, 107 struct iio_chan_spec const *chan) 108 { 109 int ret; 110 111 mutex_lock(&data->lock); 112 113 ret = regmap_bulk_read(data->regmap, 114 ADXL313_REG_DATA_AXIS(chan->address), 115 &data->transf_buf, sizeof(data->transf_buf)); 116 if (ret) 117 goto unlock_ret; 118 119 ret = le16_to_cpu(data->transf_buf); 120 121 unlock_ret: 122 mutex_unlock(&data->lock); 123 return ret; 124 } 125 126 static int adxl313_read_freq_avail(struct iio_dev *indio_dev, 127 struct iio_chan_spec const *chan, 128 const int **vals, int *type, int *length, 129 long mask) 130 { 131 switch (mask) { 132 case IIO_CHAN_INFO_SAMP_FREQ: 133 *vals = (const int *)adxl313_odr_freqs; 134 *length = ARRAY_SIZE(adxl313_odr_freqs) * 2; 135 *type = IIO_VAL_INT_PLUS_MICRO; 136 return IIO_AVAIL_LIST; 137 default: 138 return -EINVAL; 139 } 140 } 141 142 static int adxl313_read_raw(struct iio_dev *indio_dev, 143 struct iio_chan_spec const *chan, 144 int *val, int *val2, long mask) 145 { 146 struct adxl313_data *data = iio_priv(indio_dev); 147 unsigned int regval; 148 int ret; 149 150 switch (mask) { 151 case IIO_CHAN_INFO_RAW: 152 ret = adxl313_read_axis(data, chan); 153 if (ret < 0) 154 return ret; 155 156 *val = sign_extend32(ret, chan->scan_type.realbits - 1); 157 return IIO_VAL_INT; 158 case IIO_CHAN_INFO_SCALE: 159 /* 160 * Scale for any g range is given in datasheet as 161 * 1024 LSB/g = 0.0009765625 * 9.80665 = 0.009576806640625 m/s^2 162 */ 163 *val = 0; 164 *val2 = 9576806; 165 return IIO_VAL_INT_PLUS_NANO; 166 case IIO_CHAN_INFO_CALIBBIAS: 167 ret = regmap_read(data->regmap, 168 ADXL313_REG_OFS_AXIS(chan->address), ®val); 169 if (ret) 170 return ret; 171 172 /* 173 * 8-bit resolution at +/- 0.5g, that is 4x accel data scale 174 * factor at full resolution 175 */ 176 *val = sign_extend32(regval, 7) * 4; 177 return IIO_VAL_INT; 178 case IIO_CHAN_INFO_SAMP_FREQ: 179 ret = regmap_read(data->regmap, ADXL313_REG_BW_RATE, ®val); 180 if (ret) 181 return ret; 182 183 ret = FIELD_GET(ADXL313_RATE_MSK, regval) - ADXL313_RATE_BASE; 184 *val = adxl313_odr_freqs[ret][0]; 185 *val2 = adxl313_odr_freqs[ret][1]; 186 return IIO_VAL_INT_PLUS_MICRO; 187 default: 188 return -EINVAL; 189 } 190 } 191 192 static int adxl313_write_raw(struct iio_dev *indio_dev, 193 struct iio_chan_spec const *chan, 194 int val, int val2, long mask) 195 { 196 struct adxl313_data *data = iio_priv(indio_dev); 197 198 switch (mask) { 199 case IIO_CHAN_INFO_CALIBBIAS: 200 /* 201 * 8-bit resolution at +/- 0.5g, that is 4x accel data scale 202 * factor at full resolution 203 */ 204 if (clamp_val(val, -128 * 4, 127 * 4) != val) 205 return -EINVAL; 206 207 return regmap_write(data->regmap, 208 ADXL313_REG_OFS_AXIS(chan->address), 209 val / 4); 210 case IIO_CHAN_INFO_SAMP_FREQ: 211 return adxl313_set_odr(data, val, val2); 212 default: 213 return -EINVAL; 214 } 215 } 216 217 static const struct iio_info adxl313_info = { 218 .read_raw = adxl313_read_raw, 219 .write_raw = adxl313_write_raw, 220 .read_avail = adxl313_read_freq_avail, 221 }; 222 223 static int adxl313_setup(struct device *dev, struct adxl313_data *data, 224 int (*setup)(struct device *, struct regmap *)) 225 { 226 unsigned int regval; 227 int ret; 228 229 /* Ensures the device is in a consistent state after start up */ 230 ret = regmap_write(data->regmap, ADXL313_REG_SOFT_RESET, 231 ADXL313_SOFT_RESET); 232 if (ret) 233 return ret; 234 235 if (setup) { 236 ret = setup(dev, data->regmap); 237 if (ret) 238 return ret; 239 } 240 241 ret = regmap_read(data->regmap, ADXL313_REG_DEVID0, ®val); 242 if (ret) 243 return ret; 244 245 if (regval != ADXL313_DEVID0) { 246 dev_err(dev, "Invalid manufacturer ID: 0x%02x\n", regval); 247 return -ENODEV; 248 } 249 250 ret = regmap_read(data->regmap, ADXL313_REG_DEVID1, ®val); 251 if (ret) 252 return ret; 253 254 if (regval != ADXL313_DEVID1) { 255 dev_err(dev, "Invalid mems ID: 0x%02x\n", regval); 256 return -ENODEV; 257 } 258 259 ret = regmap_read(data->regmap, ADXL313_REG_PARTID, ®val); 260 if (ret) 261 return ret; 262 263 if (regval != ADXL313_PARTID) { 264 dev_err(dev, "Invalid device ID: 0x%02x\n", regval); 265 return -ENODEV; 266 } 267 268 /* Sets the range to +/- 4g */ 269 ret = regmap_update_bits(data->regmap, ADXL313_REG_DATA_FORMAT, 270 ADXL313_RANGE_MSK, 271 FIELD_PREP(ADXL313_RANGE_MSK, ADXL313_RANGE_4G)); 272 if (ret) 273 return ret; 274 275 /* Enables full resolution */ 276 ret = regmap_update_bits(data->regmap, ADXL313_REG_DATA_FORMAT, 277 ADXL313_FULL_RES, ADXL313_FULL_RES); 278 if (ret) 279 return ret; 280 281 /* Enables measurement mode */ 282 return regmap_update_bits(data->regmap, ADXL313_REG_POWER_CTL, 283 ADXL313_POWER_CTL_MSK, 284 ADXL313_MEASUREMENT_MODE); 285 } 286 287 /** 288 * adxl313_core_probe() - probe and setup for adxl313 accelerometer 289 * @dev: Driver model representation of the device 290 * @regmap: Register map of the device 291 * @name: Device name buffer reference 292 * @setup: Setup routine to be executed right before the standard device 293 * setup, can also be set to NULL if not required 294 * 295 * Return: 0 on success, negative errno on error cases 296 */ 297 int adxl313_core_probe(struct device *dev, 298 struct regmap *regmap, 299 const char *name, 300 int (*setup)(struct device *, struct regmap *)) 301 { 302 struct adxl313_data *data; 303 struct iio_dev *indio_dev; 304 int ret; 305 306 indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 307 if (!indio_dev) 308 return -ENOMEM; 309 310 data = iio_priv(indio_dev); 311 data->regmap = regmap; 312 mutex_init(&data->lock); 313 314 indio_dev->name = name; 315 indio_dev->info = &adxl313_info; 316 indio_dev->modes = INDIO_DIRECT_MODE; 317 indio_dev->channels = adxl313_channels; 318 indio_dev->num_channels = ARRAY_SIZE(adxl313_channels); 319 320 ret = adxl313_setup(dev, data, setup); 321 if (ret) { 322 dev_err(dev, "ADXL313 setup failed\n"); 323 return ret; 324 } 325 326 return devm_iio_device_register(dev, indio_dev); 327 } 328 EXPORT_SYMBOL_NS_GPL(adxl313_core_probe, IIO_ADXL313); 329 330 MODULE_AUTHOR("Lucas Stankus <lucas.p.stankus@gmail.com>"); 331 MODULE_DESCRIPTION("ADXL313 3-Axis Digital Accelerometer core driver"); 332 MODULE_LICENSE("GPL v2"); 333