0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/bits.h>
0011 #include <linux/bitfield.h>
0012 #include <linux/iio/buffer.h>
0013 #include <linux/iio/iio.h>
0014 #include <linux/iio/trigger.h>
0015 #include <linux/iio/triggered_buffer.h>
0016 #include <linux/iio/trigger_consumer.h>
0017 #include <linux/limits.h>
0018 #include <linux/math64.h>
0019 #include <linux/module.h>
0020 #include <linux/mod_devicetable.h>
0021 #include <linux/property.h>
0022 #include <linux/regmap.h>
0023 #include <linux/units.h>
0024
0025 #include <asm/unaligned.h>
0026
0027 #include "adxl355.h"
0028
0029
0030 #define ADXL355_DEVID_AD_REG 0x00
0031 #define ADXL355_DEVID_MST_REG 0x01
0032 #define ADXL355_PARTID_REG 0x02
0033 #define ADXL355_STATUS_REG 0x04
0034 #define ADXL355_FIFO_ENTRIES_REG 0x05
0035 #define ADXL355_TEMP2_REG 0x06
0036 #define ADXL355_XDATA3_REG 0x08
0037 #define ADXL355_YDATA3_REG 0x0B
0038 #define ADXL355_ZDATA3_REG 0x0E
0039 #define ADXL355_FIFO_DATA_REG 0x11
0040 #define ADXL355_OFFSET_X_H_REG 0x1E
0041 #define ADXL355_OFFSET_Y_H_REG 0x20
0042 #define ADXL355_OFFSET_Z_H_REG 0x22
0043 #define ADXL355_ACT_EN_REG 0x24
0044 #define ADXL355_ACT_THRESH_H_REG 0x25
0045 #define ADXL355_ACT_THRESH_L_REG 0x26
0046 #define ADXL355_ACT_COUNT_REG 0x27
0047 #define ADXL355_FILTER_REG 0x28
0048 #define ADXL355_FILTER_ODR_MSK GENMASK(3, 0)
0049 #define ADXL355_FILTER_HPF_MSK GENMASK(6, 4)
0050 #define ADXL355_FIFO_SAMPLES_REG 0x29
0051 #define ADXL355_INT_MAP_REG 0x2A
0052 #define ADXL355_SYNC_REG 0x2B
0053 #define ADXL355_RANGE_REG 0x2C
0054 #define ADXL355_POWER_CTL_REG 0x2D
0055 #define ADXL355_POWER_CTL_MODE_MSK GENMASK(1, 0)
0056 #define ADXL355_POWER_CTL_DRDY_MSK BIT(2)
0057 #define ADXL355_SELF_TEST_REG 0x2E
0058 #define ADXL355_RESET_REG 0x2F
0059
0060 #define ADXL355_DEVID_AD_VAL 0xAD
0061 #define ADXL355_DEVID_MST_VAL 0x1D
0062 #define ADXL355_PARTID_VAL 0xED
0063 #define ADXL355_RESET_CODE 0x52
0064
0065 static const struct regmap_range adxl355_read_reg_range[] = {
0066 regmap_reg_range(ADXL355_DEVID_AD_REG, ADXL355_FIFO_DATA_REG),
0067 regmap_reg_range(ADXL355_OFFSET_X_H_REG, ADXL355_SELF_TEST_REG),
0068 };
0069
0070 const struct regmap_access_table adxl355_readable_regs_tbl = {
0071 .yes_ranges = adxl355_read_reg_range,
0072 .n_yes_ranges = ARRAY_SIZE(adxl355_read_reg_range),
0073 };
0074 EXPORT_SYMBOL_NS_GPL(adxl355_readable_regs_tbl, IIO_ADXL355);
0075
0076 static const struct regmap_range adxl355_write_reg_range[] = {
0077 regmap_reg_range(ADXL355_OFFSET_X_H_REG, ADXL355_RESET_REG),
0078 };
0079
0080 const struct regmap_access_table adxl355_writeable_regs_tbl = {
0081 .yes_ranges = adxl355_write_reg_range,
0082 .n_yes_ranges = ARRAY_SIZE(adxl355_write_reg_range),
0083 };
0084 EXPORT_SYMBOL_NS_GPL(adxl355_writeable_regs_tbl, IIO_ADXL355);
0085
0086 enum adxl355_op_mode {
0087 ADXL355_MEASUREMENT,
0088 ADXL355_STANDBY,
0089 ADXL355_TEMP_OFF,
0090 };
0091
0092 enum adxl355_odr {
0093 ADXL355_ODR_4000HZ,
0094 ADXL355_ODR_2000HZ,
0095 ADXL355_ODR_1000HZ,
0096 ADXL355_ODR_500HZ,
0097 ADXL355_ODR_250HZ,
0098 ADXL355_ODR_125HZ,
0099 ADXL355_ODR_62_5HZ,
0100 ADXL355_ODR_31_25HZ,
0101 ADXL355_ODR_15_625HZ,
0102 ADXL355_ODR_7_813HZ,
0103 ADXL355_ODR_3_906HZ,
0104 };
0105
0106 enum adxl355_hpf_3db {
0107 ADXL355_HPF_OFF,
0108 ADXL355_HPF_24_7,
0109 ADXL355_HPF_6_2084,
0110 ADXL355_HPF_1_5545,
0111 ADXL355_HPF_0_3862,
0112 ADXL355_HPF_0_0954,
0113 ADXL355_HPF_0_0238,
0114 };
0115
0116 static const int adxl355_odr_table[][2] = {
0117 [0] = {4000, 0},
0118 [1] = {2000, 0},
0119 [2] = {1000, 0},
0120 [3] = {500, 0},
0121 [4] = {250, 0},
0122 [5] = {125, 0},
0123 [6] = {62, 500000},
0124 [7] = {31, 250000},
0125 [8] = {15, 625000},
0126 [9] = {7, 813000},
0127 [10] = {3, 906000},
0128 };
0129
0130 static const int adxl355_hpf_3db_multipliers[] = {
0131 0,
0132 247000,
0133 62084,
0134 15545,
0135 3862,
0136 954,
0137 238,
0138 };
0139
0140 enum adxl355_chans {
0141 chan_x, chan_y, chan_z,
0142 };
0143
0144 struct adxl355_chan_info {
0145 u8 data_reg;
0146 u8 offset_reg;
0147 };
0148
0149 static const struct adxl355_chan_info adxl355_chans[] = {
0150 [chan_x] = {
0151 .data_reg = ADXL355_XDATA3_REG,
0152 .offset_reg = ADXL355_OFFSET_X_H_REG
0153 },
0154 [chan_y] = {
0155 .data_reg = ADXL355_YDATA3_REG,
0156 .offset_reg = ADXL355_OFFSET_Y_H_REG
0157 },
0158 [chan_z] = {
0159 .data_reg = ADXL355_ZDATA3_REG,
0160 .offset_reg = ADXL355_OFFSET_Z_H_REG
0161 },
0162 };
0163
0164 struct adxl355_data {
0165 struct regmap *regmap;
0166 struct device *dev;
0167 struct mutex lock;
0168 enum adxl355_op_mode op_mode;
0169 enum adxl355_odr odr;
0170 enum adxl355_hpf_3db hpf_3db;
0171 int calibbias[3];
0172 int adxl355_hpf_3db_table[7][2];
0173 struct iio_trigger *dready_trig;
0174 union {
0175 u8 transf_buf[3];
0176 struct {
0177 u8 buf[14];
0178 s64 ts;
0179 } buffer;
0180 } __aligned(IIO_DMA_MINALIGN);
0181 };
0182
0183 static int adxl355_set_op_mode(struct adxl355_data *data,
0184 enum adxl355_op_mode op_mode)
0185 {
0186 int ret;
0187
0188 if (data->op_mode == op_mode)
0189 return 0;
0190
0191 ret = regmap_update_bits(data->regmap, ADXL355_POWER_CTL_REG,
0192 ADXL355_POWER_CTL_MODE_MSK, op_mode);
0193 if (ret)
0194 return ret;
0195
0196 data->op_mode = op_mode;
0197
0198 return ret;
0199 }
0200
0201 static int adxl355_data_rdy_trigger_set_state(struct iio_trigger *trig,
0202 bool state)
0203 {
0204 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
0205 struct adxl355_data *data = iio_priv(indio_dev);
0206 int ret;
0207
0208 mutex_lock(&data->lock);
0209 ret = regmap_update_bits(data->regmap, ADXL355_POWER_CTL_REG,
0210 ADXL355_POWER_CTL_DRDY_MSK,
0211 FIELD_PREP(ADXL355_POWER_CTL_DRDY_MSK,
0212 state ? 0 : 1));
0213 mutex_unlock(&data->lock);
0214
0215 return ret;
0216 }
0217
0218 static void adxl355_fill_3db_frequency_table(struct adxl355_data *data)
0219 {
0220 u32 multiplier;
0221 u64 div, rem;
0222 u64 odr;
0223 int i;
0224
0225 odr = mul_u64_u32_shr(adxl355_odr_table[data->odr][0], MEGA, 0) +
0226 adxl355_odr_table[data->odr][1];
0227
0228 for (i = 0; i < ARRAY_SIZE(adxl355_hpf_3db_multipliers); i++) {
0229 multiplier = adxl355_hpf_3db_multipliers[i];
0230 div = div64_u64_rem(mul_u64_u32_shr(odr, multiplier, 0),
0231 TERA * 100, &rem);
0232
0233 data->adxl355_hpf_3db_table[i][0] = div;
0234 data->adxl355_hpf_3db_table[i][1] = div_u64(rem, MEGA * 100);
0235 }
0236 }
0237
0238 static int adxl355_setup(struct adxl355_data *data)
0239 {
0240 unsigned int regval;
0241 int ret;
0242
0243 ret = regmap_read(data->regmap, ADXL355_DEVID_AD_REG, ®val);
0244 if (ret)
0245 return ret;
0246
0247 if (regval != ADXL355_DEVID_AD_VAL) {
0248 dev_err(data->dev, "Invalid ADI ID 0x%02x\n", regval);
0249 return -ENODEV;
0250 }
0251
0252 ret = regmap_read(data->regmap, ADXL355_DEVID_MST_REG, ®val);
0253 if (ret)
0254 return ret;
0255
0256 if (regval != ADXL355_DEVID_MST_VAL) {
0257 dev_err(data->dev, "Invalid MEMS ID 0x%02x\n", regval);
0258 return -ENODEV;
0259 }
0260
0261 ret = regmap_read(data->regmap, ADXL355_PARTID_REG, ®val);
0262 if (ret)
0263 return ret;
0264
0265 if (regval != ADXL355_PARTID_VAL) {
0266 dev_err(data->dev, "Invalid DEV ID 0x%02x\n", regval);
0267 return -ENODEV;
0268 }
0269
0270
0271
0272
0273
0274 ret = regmap_write(data->regmap, ADXL355_RESET_REG, ADXL355_RESET_CODE);
0275 if (ret)
0276 return ret;
0277
0278 ret = regmap_update_bits(data->regmap, ADXL355_POWER_CTL_REG,
0279 ADXL355_POWER_CTL_DRDY_MSK,
0280 FIELD_PREP(ADXL355_POWER_CTL_DRDY_MSK, 1));
0281 if (ret)
0282 return ret;
0283
0284 adxl355_fill_3db_frequency_table(data);
0285
0286 return adxl355_set_op_mode(data, ADXL355_MEASUREMENT);
0287 }
0288
0289 static int adxl355_get_temp_data(struct adxl355_data *data, u8 addr)
0290 {
0291 return regmap_bulk_read(data->regmap, addr, data->transf_buf, 2);
0292 }
0293
0294 static int adxl355_read_axis(struct adxl355_data *data, u8 addr)
0295 {
0296 int ret;
0297
0298 ret = regmap_bulk_read(data->regmap, addr, data->transf_buf,
0299 ARRAY_SIZE(data->transf_buf));
0300 if (ret)
0301 return ret;
0302
0303 return get_unaligned_be24(data->transf_buf);
0304 }
0305
0306 static int adxl355_find_match(const int (*freq_tbl)[2], const int n,
0307 const int val, const int val2)
0308 {
0309 int i;
0310
0311 for (i = 0; i < n; i++) {
0312 if (freq_tbl[i][0] == val && freq_tbl[i][1] == val2)
0313 return i;
0314 }
0315
0316 return -EINVAL;
0317 }
0318
0319 static int adxl355_set_odr(struct adxl355_data *data,
0320 enum adxl355_odr odr)
0321 {
0322 int ret;
0323
0324 mutex_lock(&data->lock);
0325
0326 if (data->odr == odr) {
0327 mutex_unlock(&data->lock);
0328 return 0;
0329 }
0330
0331 ret = adxl355_set_op_mode(data, ADXL355_STANDBY);
0332 if (ret)
0333 goto err_unlock;
0334
0335 ret = regmap_update_bits(data->regmap, ADXL355_FILTER_REG,
0336 ADXL355_FILTER_ODR_MSK,
0337 FIELD_PREP(ADXL355_FILTER_ODR_MSK, odr));
0338 if (ret)
0339 goto err_set_opmode;
0340
0341 data->odr = odr;
0342 adxl355_fill_3db_frequency_table(data);
0343
0344 ret = adxl355_set_op_mode(data, ADXL355_MEASUREMENT);
0345 if (ret)
0346 goto err_set_opmode;
0347
0348 mutex_unlock(&data->lock);
0349 return 0;
0350
0351 err_set_opmode:
0352 adxl355_set_op_mode(data, ADXL355_MEASUREMENT);
0353 err_unlock:
0354 mutex_unlock(&data->lock);
0355 return ret;
0356 }
0357
0358 static int adxl355_set_hpf_3db(struct adxl355_data *data,
0359 enum adxl355_hpf_3db hpf)
0360 {
0361 int ret;
0362
0363 mutex_lock(&data->lock);
0364
0365 if (data->hpf_3db == hpf) {
0366 mutex_unlock(&data->lock);
0367 return 0;
0368 }
0369
0370 ret = adxl355_set_op_mode(data, ADXL355_STANDBY);
0371 if (ret)
0372 goto err_unlock;
0373
0374 ret = regmap_update_bits(data->regmap, ADXL355_FILTER_REG,
0375 ADXL355_FILTER_HPF_MSK,
0376 FIELD_PREP(ADXL355_FILTER_HPF_MSK, hpf));
0377 if (ret)
0378 goto err_set_opmode;
0379
0380 data->hpf_3db = hpf;
0381
0382 ret = adxl355_set_op_mode(data, ADXL355_MEASUREMENT);
0383 if (ret)
0384 goto err_set_opmode;
0385
0386 mutex_unlock(&data->lock);
0387 return 0;
0388
0389 err_set_opmode:
0390 adxl355_set_op_mode(data, ADXL355_MEASUREMENT);
0391 err_unlock:
0392 mutex_unlock(&data->lock);
0393 return ret;
0394 }
0395
0396 static int adxl355_set_calibbias(struct adxl355_data *data,
0397 enum adxl355_chans chan, int calibbias)
0398 {
0399 int ret;
0400
0401 mutex_lock(&data->lock);
0402
0403 ret = adxl355_set_op_mode(data, ADXL355_STANDBY);
0404 if (ret)
0405 goto err_unlock;
0406
0407 put_unaligned_be16(calibbias, data->transf_buf);
0408 ret = regmap_bulk_write(data->regmap,
0409 adxl355_chans[chan].offset_reg,
0410 data->transf_buf, 2);
0411 if (ret)
0412 goto err_set_opmode;
0413
0414 data->calibbias[chan] = calibbias;
0415
0416 ret = adxl355_set_op_mode(data, ADXL355_MEASUREMENT);
0417 if (ret)
0418 goto err_set_opmode;
0419
0420 mutex_unlock(&data->lock);
0421 return 0;
0422
0423 err_set_opmode:
0424 adxl355_set_op_mode(data, ADXL355_MEASUREMENT);
0425 err_unlock:
0426 mutex_unlock(&data->lock);
0427 return ret;
0428 }
0429
0430 static int adxl355_read_raw(struct iio_dev *indio_dev,
0431 struct iio_chan_spec const *chan,
0432 int *val, int *val2, long mask)
0433 {
0434 struct adxl355_data *data = iio_priv(indio_dev);
0435 int ret;
0436
0437 switch (mask) {
0438 case IIO_CHAN_INFO_RAW:
0439 switch (chan->type) {
0440 case IIO_TEMP:
0441 ret = adxl355_get_temp_data(data, chan->address);
0442 if (ret < 0)
0443 return ret;
0444 *val = get_unaligned_be16(data->transf_buf);
0445
0446 return IIO_VAL_INT;
0447 case IIO_ACCEL:
0448 ret = adxl355_read_axis(data, adxl355_chans[
0449 chan->address].data_reg);
0450 if (ret < 0)
0451 return ret;
0452 *val = sign_extend32(ret >> chan->scan_type.shift,
0453 chan->scan_type.realbits - 1);
0454 return IIO_VAL_INT;
0455 default:
0456 return -EINVAL;
0457 }
0458
0459 case IIO_CHAN_INFO_SCALE:
0460 switch (chan->type) {
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470 case IIO_TEMP:
0471 *val = -110;
0472 *val2 = 497238;
0473 return IIO_VAL_INT_PLUS_MICRO;
0474
0475
0476
0477
0478 case IIO_ACCEL:
0479 *val = 0;
0480 *val2 = 38245;
0481 return IIO_VAL_INT_PLUS_NANO;
0482 default:
0483 return -EINVAL;
0484 }
0485 case IIO_CHAN_INFO_OFFSET:
0486 *val = -2111;
0487 *val2 = 250000;
0488 return IIO_VAL_INT_PLUS_MICRO;
0489 case IIO_CHAN_INFO_CALIBBIAS:
0490 *val = sign_extend32(data->calibbias[chan->address], 15);
0491 return IIO_VAL_INT;
0492 case IIO_CHAN_INFO_SAMP_FREQ:
0493 *val = adxl355_odr_table[data->odr][0];
0494 *val2 = adxl355_odr_table[data->odr][1];
0495 return IIO_VAL_INT_PLUS_MICRO;
0496 case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
0497 *val = data->adxl355_hpf_3db_table[data->hpf_3db][0];
0498 *val2 = data->adxl355_hpf_3db_table[data->hpf_3db][1];
0499 return IIO_VAL_INT_PLUS_MICRO;
0500 default:
0501 return -EINVAL;
0502 }
0503 }
0504
0505 static int adxl355_write_raw(struct iio_dev *indio_dev,
0506 struct iio_chan_spec const *chan,
0507 int val, int val2, long mask)
0508 {
0509 struct adxl355_data *data = iio_priv(indio_dev);
0510 int odr_idx, hpf_idx, calibbias;
0511
0512 switch (mask) {
0513 case IIO_CHAN_INFO_SAMP_FREQ:
0514 odr_idx = adxl355_find_match(adxl355_odr_table,
0515 ARRAY_SIZE(adxl355_odr_table),
0516 val, val2);
0517 if (odr_idx < 0)
0518 return odr_idx;
0519
0520 return adxl355_set_odr(data, odr_idx);
0521 case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
0522 hpf_idx = adxl355_find_match(data->adxl355_hpf_3db_table,
0523 ARRAY_SIZE(data->adxl355_hpf_3db_table),
0524 val, val2);
0525 if (hpf_idx < 0)
0526 return hpf_idx;
0527
0528 return adxl355_set_hpf_3db(data, hpf_idx);
0529 case IIO_CHAN_INFO_CALIBBIAS:
0530 calibbias = clamp_t(int, val, S16_MIN, S16_MAX);
0531
0532 return adxl355_set_calibbias(data, chan->address, calibbias);
0533 default:
0534 return -EINVAL;
0535 }
0536 }
0537
0538 static int adxl355_read_avail(struct iio_dev *indio_dev,
0539 struct iio_chan_spec const *chan,
0540 const int **vals, int *type, int *length,
0541 long mask)
0542 {
0543 struct adxl355_data *data = iio_priv(indio_dev);
0544
0545 switch (mask) {
0546 case IIO_CHAN_INFO_SAMP_FREQ:
0547 *vals = (const int *)adxl355_odr_table;
0548 *type = IIO_VAL_INT_PLUS_MICRO;
0549
0550 *length = ARRAY_SIZE(adxl355_odr_table) * 2;
0551
0552 return IIO_AVAIL_LIST;
0553 case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
0554 *vals = (const int *)data->adxl355_hpf_3db_table;
0555 *type = IIO_VAL_INT_PLUS_MICRO;
0556
0557 *length = ARRAY_SIZE(data->adxl355_hpf_3db_table) * 2;
0558
0559 return IIO_AVAIL_LIST;
0560 default:
0561 return -EINVAL;
0562 }
0563 }
0564
0565 static const unsigned long adxl355_avail_scan_masks[] = {
0566 GENMASK(3, 0),
0567 0
0568 };
0569
0570 static const struct iio_info adxl355_info = {
0571 .read_raw = adxl355_read_raw,
0572 .write_raw = adxl355_write_raw,
0573 .read_avail = &adxl355_read_avail,
0574 };
0575
0576 static const struct iio_trigger_ops adxl355_trigger_ops = {
0577 .set_trigger_state = &adxl355_data_rdy_trigger_set_state,
0578 .validate_device = &iio_trigger_validate_own_device,
0579 };
0580
0581 static irqreturn_t adxl355_trigger_handler(int irq, void *p)
0582 {
0583 struct iio_poll_func *pf = p;
0584 struct iio_dev *indio_dev = pf->indio_dev;
0585 struct adxl355_data *data = iio_priv(indio_dev);
0586 int ret;
0587
0588 mutex_lock(&data->lock);
0589
0590
0591
0592
0593
0594 data->buffer.buf[0] = 0;
0595
0596
0597
0598
0599
0600
0601
0602
0603 ret = regmap_bulk_read(data->regmap, ADXL355_XDATA3_REG,
0604 &data->buffer.buf[1], 3);
0605 if (ret)
0606 goto out_unlock_notify;
0607
0608 ret = regmap_bulk_read(data->regmap, ADXL355_YDATA3_REG,
0609 &data->buffer.buf[5], 3);
0610 if (ret)
0611 goto out_unlock_notify;
0612
0613 ret = regmap_bulk_read(data->regmap, ADXL355_ZDATA3_REG,
0614 &data->buffer.buf[9], 3);
0615 if (ret)
0616 goto out_unlock_notify;
0617
0618 ret = regmap_bulk_read(data->regmap, ADXL355_TEMP2_REG,
0619 &data->buffer.buf[12], 2);
0620 if (ret)
0621 goto out_unlock_notify;
0622
0623 iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer,
0624 pf->timestamp);
0625
0626 out_unlock_notify:
0627 mutex_unlock(&data->lock);
0628 iio_trigger_notify_done(indio_dev->trig);
0629
0630 return IRQ_HANDLED;
0631 }
0632
0633 #define ADXL355_ACCEL_CHANNEL(index, reg, axis) { \
0634 .type = IIO_ACCEL, \
0635 .address = reg, \
0636 .modified = 1, \
0637 .channel2 = IIO_MOD_##axis, \
0638 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
0639 BIT(IIO_CHAN_INFO_CALIBBIAS), \
0640 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
0641 BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
0642 BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), \
0643 .info_mask_shared_by_type_available = \
0644 BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
0645 BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), \
0646 .scan_index = index, \
0647 .scan_type = { \
0648 .sign = 's', \
0649 .realbits = 20, \
0650 .storagebits = 32, \
0651 .shift = 4, \
0652 .endianness = IIO_BE, \
0653 } \
0654 }
0655
0656 static const struct iio_chan_spec adxl355_channels[] = {
0657 ADXL355_ACCEL_CHANNEL(0, chan_x, X),
0658 ADXL355_ACCEL_CHANNEL(1, chan_y, Y),
0659 ADXL355_ACCEL_CHANNEL(2, chan_z, Z),
0660 {
0661 .type = IIO_TEMP,
0662 .address = ADXL355_TEMP2_REG,
0663 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
0664 BIT(IIO_CHAN_INFO_SCALE) |
0665 BIT(IIO_CHAN_INFO_OFFSET),
0666 .scan_index = 3,
0667 .scan_type = {
0668 .sign = 's',
0669 .realbits = 12,
0670 .storagebits = 16,
0671 .endianness = IIO_BE,
0672 },
0673 },
0674 IIO_CHAN_SOFT_TIMESTAMP(4),
0675 };
0676
0677 static int adxl355_probe_trigger(struct iio_dev *indio_dev, int irq)
0678 {
0679 struct adxl355_data *data = iio_priv(indio_dev);
0680 int ret;
0681
0682 data->dready_trig = devm_iio_trigger_alloc(data->dev, "%s-dev%d",
0683 indio_dev->name,
0684 iio_device_id(indio_dev));
0685 if (!data->dready_trig)
0686 return -ENOMEM;
0687
0688 data->dready_trig->ops = &adxl355_trigger_ops;
0689 iio_trigger_set_drvdata(data->dready_trig, indio_dev);
0690
0691 ret = devm_request_irq(data->dev, irq,
0692 &iio_trigger_generic_data_rdy_poll,
0693 IRQF_ONESHOT, "adxl355_irq", data->dready_trig);
0694 if (ret)
0695 return dev_err_probe(data->dev, ret, "request irq %d failed\n",
0696 irq);
0697
0698 ret = devm_iio_trigger_register(data->dev, data->dready_trig);
0699 if (ret) {
0700 dev_err(data->dev, "iio trigger register failed\n");
0701 return ret;
0702 }
0703
0704 indio_dev->trig = iio_trigger_get(data->dready_trig);
0705
0706 return 0;
0707 }
0708
0709 int adxl355_core_probe(struct device *dev, struct regmap *regmap,
0710 const char *name)
0711 {
0712 struct adxl355_data *data;
0713 struct iio_dev *indio_dev;
0714 int ret;
0715 int irq;
0716
0717 indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
0718 if (!indio_dev)
0719 return -ENOMEM;
0720
0721 data = iio_priv(indio_dev);
0722 data->regmap = regmap;
0723 data->dev = dev;
0724 data->op_mode = ADXL355_STANDBY;
0725 mutex_init(&data->lock);
0726
0727 indio_dev->name = name;
0728 indio_dev->info = &adxl355_info;
0729 indio_dev->modes = INDIO_DIRECT_MODE;
0730 indio_dev->channels = adxl355_channels;
0731 indio_dev->num_channels = ARRAY_SIZE(adxl355_channels);
0732 indio_dev->available_scan_masks = adxl355_avail_scan_masks;
0733
0734 ret = adxl355_setup(data);
0735 if (ret) {
0736 dev_err(dev, "ADXL355 setup failed\n");
0737 return ret;
0738 }
0739
0740 ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
0741 &iio_pollfunc_store_time,
0742 &adxl355_trigger_handler, NULL);
0743 if (ret) {
0744 dev_err(dev, "iio triggered buffer setup failed\n");
0745 return ret;
0746 }
0747
0748 irq = fwnode_irq_get_byname(dev_fwnode(dev), "DRDY");
0749 if (irq > 0) {
0750 ret = adxl355_probe_trigger(indio_dev, irq);
0751 if (ret)
0752 return ret;
0753 }
0754
0755 return devm_iio_device_register(dev, indio_dev);
0756 }
0757 EXPORT_SYMBOL_NS_GPL(adxl355_core_probe, IIO_ADXL355);
0758
0759 MODULE_AUTHOR("Puranjay Mohan <puranjay12@gmail.com>");
0760 MODULE_DESCRIPTION("ADXL355 3-Axis Digital Accelerometer core driver");
0761 MODULE_LICENSE("GPL v2");