mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-08 14:23:19 +00:00
iio: imu: inv_icm42600: add support of ICM-42686-P
Add ICM-42686-P chip supporting high FSRs (32G, 4000dps). Create accel and gyro iio device states with dynamic scales table set at device init. Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com> Link: https://lore.kernel.org/r/20240422152240.85974-3-inv.git-commit@tdk.com Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
parent
3b0c133612
commit
a1432b5b4f
@ -13,6 +13,7 @@
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/iio/common/inv_sensors_timestamp.h>
|
||||
|
||||
#include "inv_icm42600_buffer.h"
|
||||
|
||||
@ -21,6 +22,7 @@ enum inv_icm42600_chip {
|
||||
INV_CHIP_ICM42600,
|
||||
INV_CHIP_ICM42602,
|
||||
INV_CHIP_ICM42605,
|
||||
INV_CHIP_ICM42686,
|
||||
INV_CHIP_ICM42622,
|
||||
INV_CHIP_ICM42688,
|
||||
INV_CHIP_ICM42631,
|
||||
@ -57,6 +59,17 @@ enum inv_icm42600_gyro_fs {
|
||||
INV_ICM42600_GYRO_FS_15_625DPS,
|
||||
INV_ICM42600_GYRO_FS_NB,
|
||||
};
|
||||
enum inv_icm42686_gyro_fs {
|
||||
INV_ICM42686_GYRO_FS_4000DPS,
|
||||
INV_ICM42686_GYRO_FS_2000DPS,
|
||||
INV_ICM42686_GYRO_FS_1000DPS,
|
||||
INV_ICM42686_GYRO_FS_500DPS,
|
||||
INV_ICM42686_GYRO_FS_250DPS,
|
||||
INV_ICM42686_GYRO_FS_125DPS,
|
||||
INV_ICM42686_GYRO_FS_62_5DPS,
|
||||
INV_ICM42686_GYRO_FS_31_25DPS,
|
||||
INV_ICM42686_GYRO_FS_NB,
|
||||
};
|
||||
|
||||
/* accelerometer fullscale values */
|
||||
enum inv_icm42600_accel_fs {
|
||||
@ -66,6 +79,14 @@ enum inv_icm42600_accel_fs {
|
||||
INV_ICM42600_ACCEL_FS_2G,
|
||||
INV_ICM42600_ACCEL_FS_NB,
|
||||
};
|
||||
enum inv_icm42686_accel_fs {
|
||||
INV_ICM42686_ACCEL_FS_32G,
|
||||
INV_ICM42686_ACCEL_FS_16G,
|
||||
INV_ICM42686_ACCEL_FS_8G,
|
||||
INV_ICM42686_ACCEL_FS_4G,
|
||||
INV_ICM42686_ACCEL_FS_2G,
|
||||
INV_ICM42686_ACCEL_FS_NB,
|
||||
};
|
||||
|
||||
/* ODR suffixed by LN or LP are Low-Noise or Low-Power mode only */
|
||||
enum inv_icm42600_odr {
|
||||
@ -151,6 +172,19 @@ struct inv_icm42600_state {
|
||||
} timestamp;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* struct inv_icm42600_sensor_state - sensor state variables
|
||||
* @scales: table of scales.
|
||||
* @scales_len: length (nb of items) of the scales table.
|
||||
* @ts: timestamp module states.
|
||||
*/
|
||||
struct inv_icm42600_sensor_state {
|
||||
const int *scales;
|
||||
size_t scales_len;
|
||||
struct inv_sensors_timestamp ts;
|
||||
};
|
||||
|
||||
/* Virtual register addresses: @bank on MSB (4 upper bits), @address on LSB */
|
||||
|
||||
/* Bank selection register, available in all banks */
|
||||
@ -304,6 +338,7 @@ struct inv_icm42600_state {
|
||||
#define INV_ICM42600_WHOAMI_ICM42600 0x40
|
||||
#define INV_ICM42600_WHOAMI_ICM42602 0x41
|
||||
#define INV_ICM42600_WHOAMI_ICM42605 0x42
|
||||
#define INV_ICM42600_WHOAMI_ICM42686 0x44
|
||||
#define INV_ICM42600_WHOAMI_ICM42622 0x46
|
||||
#define INV_ICM42600_WHOAMI_ICM42688 0x47
|
||||
#define INV_ICM42600_WHOAMI_ICM42631 0x5C
|
||||
|
@ -99,7 +99,8 @@ static int inv_icm42600_accel_update_scan_mode(struct iio_dev *indio_dev,
|
||||
const unsigned long *scan_mask)
|
||||
{
|
||||
struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
|
||||
struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
|
||||
struct inv_icm42600_sensor_state *accel_st = iio_priv(indio_dev);
|
||||
struct inv_sensors_timestamp *ts = &accel_st->ts;
|
||||
struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
|
||||
unsigned int fifo_en = 0;
|
||||
unsigned int sleep_temp = 0;
|
||||
@ -210,33 +211,54 @@ static const int inv_icm42600_accel_scale[] = {
|
||||
[2 * INV_ICM42600_ACCEL_FS_2G] = 0,
|
||||
[2 * INV_ICM42600_ACCEL_FS_2G + 1] = 598550,
|
||||
};
|
||||
static const int inv_icm42686_accel_scale[] = {
|
||||
/* +/- 32G => 0.009576807 m/s-2 */
|
||||
[2 * INV_ICM42686_ACCEL_FS_32G] = 0,
|
||||
[2 * INV_ICM42686_ACCEL_FS_32G + 1] = 9576807,
|
||||
/* +/- 16G => 0.004788403 m/s-2 */
|
||||
[2 * INV_ICM42686_ACCEL_FS_16G] = 0,
|
||||
[2 * INV_ICM42686_ACCEL_FS_16G + 1] = 4788403,
|
||||
/* +/- 8G => 0.002394202 m/s-2 */
|
||||
[2 * INV_ICM42686_ACCEL_FS_8G] = 0,
|
||||
[2 * INV_ICM42686_ACCEL_FS_8G + 1] = 2394202,
|
||||
/* +/- 4G => 0.001197101 m/s-2 */
|
||||
[2 * INV_ICM42686_ACCEL_FS_4G] = 0,
|
||||
[2 * INV_ICM42686_ACCEL_FS_4G + 1] = 1197101,
|
||||
/* +/- 2G => 0.000598550 m/s-2 */
|
||||
[2 * INV_ICM42686_ACCEL_FS_2G] = 0,
|
||||
[2 * INV_ICM42686_ACCEL_FS_2G + 1] = 598550,
|
||||
};
|
||||
|
||||
static int inv_icm42600_accel_read_scale(struct inv_icm42600_state *st,
|
||||
static int inv_icm42600_accel_read_scale(struct iio_dev *indio_dev,
|
||||
int *val, int *val2)
|
||||
{
|
||||
struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
|
||||
struct inv_icm42600_sensor_state *accel_st = iio_priv(indio_dev);
|
||||
unsigned int idx;
|
||||
|
||||
idx = st->conf.accel.fs;
|
||||
|
||||
*val = inv_icm42600_accel_scale[2 * idx];
|
||||
*val2 = inv_icm42600_accel_scale[2 * idx + 1];
|
||||
*val = accel_st->scales[2 * idx];
|
||||
*val2 = accel_st->scales[2 * idx + 1];
|
||||
return IIO_VAL_INT_PLUS_NANO;
|
||||
}
|
||||
|
||||
static int inv_icm42600_accel_write_scale(struct inv_icm42600_state *st,
|
||||
static int inv_icm42600_accel_write_scale(struct iio_dev *indio_dev,
|
||||
int val, int val2)
|
||||
{
|
||||
struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
|
||||
struct inv_icm42600_sensor_state *accel_st = iio_priv(indio_dev);
|
||||
struct device *dev = regmap_get_device(st->map);
|
||||
unsigned int idx;
|
||||
struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
|
||||
int ret;
|
||||
|
||||
for (idx = 0; idx < ARRAY_SIZE(inv_icm42600_accel_scale); idx += 2) {
|
||||
if (val == inv_icm42600_accel_scale[idx] &&
|
||||
val2 == inv_icm42600_accel_scale[idx + 1])
|
||||
for (idx = 0; idx < accel_st->scales_len; idx += 2) {
|
||||
if (val == accel_st->scales[idx] &&
|
||||
val2 == accel_st->scales[idx + 1])
|
||||
break;
|
||||
}
|
||||
if (idx >= ARRAY_SIZE(inv_icm42600_accel_scale))
|
||||
if (idx >= accel_st->scales_len)
|
||||
return -EINVAL;
|
||||
|
||||
conf.fs = idx / 2;
|
||||
@ -309,7 +331,8 @@ static int inv_icm42600_accel_write_odr(struct iio_dev *indio_dev,
|
||||
int val, int val2)
|
||||
{
|
||||
struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
|
||||
struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
|
||||
struct inv_icm42600_sensor_state *accel_st = iio_priv(indio_dev);
|
||||
struct inv_sensors_timestamp *ts = &accel_st->ts;
|
||||
struct device *dev = regmap_get_device(st->map);
|
||||
unsigned int idx;
|
||||
struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
|
||||
@ -565,7 +588,7 @@ static int inv_icm42600_accel_read_raw(struct iio_dev *indio_dev,
|
||||
*val = data;
|
||||
return IIO_VAL_INT;
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
return inv_icm42600_accel_read_scale(st, val, val2);
|
||||
return inv_icm42600_accel_read_scale(indio_dev, val, val2);
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
return inv_icm42600_accel_read_odr(st, val, val2);
|
||||
case IIO_CHAN_INFO_CALIBBIAS:
|
||||
@ -580,14 +603,16 @@ static int inv_icm42600_accel_read_avail(struct iio_dev *indio_dev,
|
||||
const int **vals,
|
||||
int *type, int *length, long mask)
|
||||
{
|
||||
struct inv_icm42600_sensor_state *accel_st = iio_priv(indio_dev);
|
||||
|
||||
if (chan->type != IIO_ACCEL)
|
||||
return -EINVAL;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
*vals = inv_icm42600_accel_scale;
|
||||
*vals = accel_st->scales;
|
||||
*type = IIO_VAL_INT_PLUS_NANO;
|
||||
*length = ARRAY_SIZE(inv_icm42600_accel_scale);
|
||||
*length = accel_st->scales_len;
|
||||
return IIO_AVAIL_LIST;
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
*vals = inv_icm42600_accel_odr;
|
||||
@ -618,7 +643,7 @@ static int inv_icm42600_accel_write_raw(struct iio_dev *indio_dev,
|
||||
ret = iio_device_claim_direct_mode(indio_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = inv_icm42600_accel_write_scale(st, val, val2);
|
||||
ret = inv_icm42600_accel_write_scale(indio_dev, val, val2);
|
||||
iio_device_release_direct_mode(indio_dev);
|
||||
return ret;
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
@ -705,8 +730,8 @@ struct iio_dev *inv_icm42600_accel_init(struct inv_icm42600_state *st)
|
||||
{
|
||||
struct device *dev = regmap_get_device(st->map);
|
||||
const char *name;
|
||||
struct inv_icm42600_sensor_state *accel_st;
|
||||
struct inv_sensors_timestamp_chip ts_chip;
|
||||
struct inv_sensors_timestamp *ts;
|
||||
struct iio_dev *indio_dev;
|
||||
int ret;
|
||||
|
||||
@ -714,9 +739,21 @@ struct iio_dev *inv_icm42600_accel_init(struct inv_icm42600_state *st)
|
||||
if (!name)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
indio_dev = devm_iio_device_alloc(dev, sizeof(*ts));
|
||||
indio_dev = devm_iio_device_alloc(dev, sizeof(*accel_st));
|
||||
if (!indio_dev)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
accel_st = iio_priv(indio_dev);
|
||||
|
||||
switch (st->chip) {
|
||||
case INV_CHIP_ICM42686:
|
||||
accel_st->scales = inv_icm42686_accel_scale;
|
||||
accel_st->scales_len = ARRAY_SIZE(inv_icm42686_accel_scale);
|
||||
break;
|
||||
default:
|
||||
accel_st->scales = inv_icm42600_accel_scale;
|
||||
accel_st->scales_len = ARRAY_SIZE(inv_icm42600_accel_scale);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* clock period is 32kHz (31250ns)
|
||||
@ -725,8 +762,7 @@ struct iio_dev *inv_icm42600_accel_init(struct inv_icm42600_state *st)
|
||||
ts_chip.clock_period = 31250;
|
||||
ts_chip.jitter = 20;
|
||||
ts_chip.init_period = inv_icm42600_odr_to_period(st->conf.accel.odr);
|
||||
ts = iio_priv(indio_dev);
|
||||
inv_sensors_timestamp_init(ts, &ts_chip);
|
||||
inv_sensors_timestamp_init(&accel_st->ts, &ts_chip);
|
||||
|
||||
iio_device_set_drvdata(indio_dev, st);
|
||||
indio_dev->name = name;
|
||||
@ -751,7 +787,8 @@ struct iio_dev *inv_icm42600_accel_init(struct inv_icm42600_state *st)
|
||||
int inv_icm42600_accel_parse_fifo(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
|
||||
struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
|
||||
struct inv_icm42600_sensor_state *accel_st = iio_priv(indio_dev);
|
||||
struct inv_sensors_timestamp *ts = &accel_st->ts;
|
||||
ssize_t i, size;
|
||||
unsigned int no;
|
||||
const void *accel, *gyro, *timestamp;
|
||||
|
@ -276,7 +276,8 @@ static int inv_icm42600_buffer_preenable(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
|
||||
struct device *dev = regmap_get_device(st->map);
|
||||
struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
|
||||
struct inv_icm42600_sensor_state *sensor_st = iio_priv(indio_dev);
|
||||
struct inv_sensors_timestamp *ts = &sensor_st->ts;
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
@ -502,6 +503,8 @@ int inv_icm42600_buffer_fifo_read(struct inv_icm42600_state *st,
|
||||
|
||||
int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st)
|
||||
{
|
||||
struct inv_icm42600_sensor_state *gyro_st = iio_priv(st->indio_gyro);
|
||||
struct inv_icm42600_sensor_state *accel_st = iio_priv(st->indio_accel);
|
||||
struct inv_sensors_timestamp *ts;
|
||||
int ret;
|
||||
|
||||
@ -509,7 +512,7 @@ int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st)
|
||||
return 0;
|
||||
|
||||
/* handle gyroscope timestamp and FIFO data parsing */
|
||||
ts = iio_priv(st->indio_gyro);
|
||||
ts = &gyro_st->ts;
|
||||
inv_sensors_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total,
|
||||
st->fifo.nb.gyro, st->timestamp.gyro);
|
||||
if (st->fifo.nb.gyro > 0) {
|
||||
@ -519,7 +522,7 @@ int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st)
|
||||
}
|
||||
|
||||
/* handle accelerometer timestamp and FIFO data parsing */
|
||||
ts = iio_priv(st->indio_accel);
|
||||
ts = &accel_st->ts;
|
||||
inv_sensors_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total,
|
||||
st->fifo.nb.accel, st->timestamp.accel);
|
||||
if (st->fifo.nb.accel > 0) {
|
||||
@ -534,6 +537,8 @@ int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st)
|
||||
int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st,
|
||||
unsigned int count)
|
||||
{
|
||||
struct inv_icm42600_sensor_state *gyro_st = iio_priv(st->indio_gyro);
|
||||
struct inv_icm42600_sensor_state *accel_st = iio_priv(st->indio_accel);
|
||||
struct inv_sensors_timestamp *ts;
|
||||
int64_t gyro_ts, accel_ts;
|
||||
int ret;
|
||||
@ -549,7 +554,7 @@ int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st,
|
||||
return 0;
|
||||
|
||||
if (st->fifo.nb.gyro > 0) {
|
||||
ts = iio_priv(st->indio_gyro);
|
||||
ts = &gyro_st->ts;
|
||||
inv_sensors_timestamp_interrupt(ts, st->fifo.period,
|
||||
st->fifo.nb.total, st->fifo.nb.gyro,
|
||||
gyro_ts);
|
||||
@ -559,7 +564,7 @@ int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st,
|
||||
}
|
||||
|
||||
if (st->fifo.nb.accel > 0) {
|
||||
ts = iio_priv(st->indio_accel);
|
||||
ts = &accel_st->ts;
|
||||
inv_sensors_timestamp_interrupt(ts, st->fifo.period,
|
||||
st->fifo.nb.total, st->fifo.nb.accel,
|
||||
accel_ts);
|
||||
|
@ -66,6 +66,22 @@ static const struct inv_icm42600_conf inv_icm42600_default_conf = {
|
||||
.temp_en = false,
|
||||
};
|
||||
|
||||
static const struct inv_icm42600_conf inv_icm42686_default_conf = {
|
||||
.gyro = {
|
||||
.mode = INV_ICM42600_SENSOR_MODE_OFF,
|
||||
.fs = INV_ICM42686_GYRO_FS_4000DPS,
|
||||
.odr = INV_ICM42600_ODR_50HZ,
|
||||
.filter = INV_ICM42600_FILTER_BW_ODR_DIV_2,
|
||||
},
|
||||
.accel = {
|
||||
.mode = INV_ICM42600_SENSOR_MODE_OFF,
|
||||
.fs = INV_ICM42686_ACCEL_FS_32G,
|
||||
.odr = INV_ICM42600_ODR_50HZ,
|
||||
.filter = INV_ICM42600_FILTER_BW_ODR_DIV_2,
|
||||
},
|
||||
.temp_en = false,
|
||||
};
|
||||
|
||||
static const struct inv_icm42600_hw inv_icm42600_hw[INV_CHIP_NB] = {
|
||||
[INV_CHIP_ICM42600] = {
|
||||
.whoami = INV_ICM42600_WHOAMI_ICM42600,
|
||||
@ -82,6 +98,11 @@ static const struct inv_icm42600_hw inv_icm42600_hw[INV_CHIP_NB] = {
|
||||
.name = "icm42605",
|
||||
.conf = &inv_icm42600_default_conf,
|
||||
},
|
||||
[INV_CHIP_ICM42686] = {
|
||||
.whoami = INV_ICM42600_WHOAMI_ICM42686,
|
||||
.name = "icm42686",
|
||||
.conf = &inv_icm42686_default_conf,
|
||||
},
|
||||
[INV_CHIP_ICM42622] = {
|
||||
.whoami = INV_ICM42600_WHOAMI_ICM42622,
|
||||
.name = "icm42622",
|
||||
|
@ -99,7 +99,8 @@ static int inv_icm42600_gyro_update_scan_mode(struct iio_dev *indio_dev,
|
||||
const unsigned long *scan_mask)
|
||||
{
|
||||
struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
|
||||
struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
|
||||
struct inv_icm42600_sensor_state *gyro_st = iio_priv(indio_dev);
|
||||
struct inv_sensors_timestamp *ts = &gyro_st->ts;
|
||||
struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
|
||||
unsigned int fifo_en = 0;
|
||||
unsigned int sleep_gyro = 0;
|
||||
@ -222,33 +223,63 @@ static const int inv_icm42600_gyro_scale[] = {
|
||||
[2 * INV_ICM42600_GYRO_FS_15_625DPS] = 0,
|
||||
[2 * INV_ICM42600_GYRO_FS_15_625DPS + 1] = 8322,
|
||||
};
|
||||
static const int inv_icm42686_gyro_scale[] = {
|
||||
/* +/- 4000dps => 0.002130529 rad/s */
|
||||
[2 * INV_ICM42686_GYRO_FS_4000DPS] = 0,
|
||||
[2 * INV_ICM42686_GYRO_FS_4000DPS + 1] = 2130529,
|
||||
/* +/- 2000dps => 0.001065264 rad/s */
|
||||
[2 * INV_ICM42686_GYRO_FS_2000DPS] = 0,
|
||||
[2 * INV_ICM42686_GYRO_FS_2000DPS + 1] = 1065264,
|
||||
/* +/- 1000dps => 0.000532632 rad/s */
|
||||
[2 * INV_ICM42686_GYRO_FS_1000DPS] = 0,
|
||||
[2 * INV_ICM42686_GYRO_FS_1000DPS + 1] = 532632,
|
||||
/* +/- 500dps => 0.000266316 rad/s */
|
||||
[2 * INV_ICM42686_GYRO_FS_500DPS] = 0,
|
||||
[2 * INV_ICM42686_GYRO_FS_500DPS + 1] = 266316,
|
||||
/* +/- 250dps => 0.000133158 rad/s */
|
||||
[2 * INV_ICM42686_GYRO_FS_250DPS] = 0,
|
||||
[2 * INV_ICM42686_GYRO_FS_250DPS + 1] = 133158,
|
||||
/* +/- 125dps => 0.000066579 rad/s */
|
||||
[2 * INV_ICM42686_GYRO_FS_125DPS] = 0,
|
||||
[2 * INV_ICM42686_GYRO_FS_125DPS + 1] = 66579,
|
||||
/* +/- 62.5dps => 0.000033290 rad/s */
|
||||
[2 * INV_ICM42686_GYRO_FS_62_5DPS] = 0,
|
||||
[2 * INV_ICM42686_GYRO_FS_62_5DPS + 1] = 33290,
|
||||
/* +/- 31.25dps => 0.000016645 rad/s */
|
||||
[2 * INV_ICM42686_GYRO_FS_31_25DPS] = 0,
|
||||
[2 * INV_ICM42686_GYRO_FS_31_25DPS + 1] = 16645,
|
||||
};
|
||||
|
||||
static int inv_icm42600_gyro_read_scale(struct inv_icm42600_state *st,
|
||||
static int inv_icm42600_gyro_read_scale(struct iio_dev *indio_dev,
|
||||
int *val, int *val2)
|
||||
{
|
||||
struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
|
||||
struct inv_icm42600_sensor_state *gyro_st = iio_priv(indio_dev);
|
||||
unsigned int idx;
|
||||
|
||||
idx = st->conf.gyro.fs;
|
||||
|
||||
*val = inv_icm42600_gyro_scale[2 * idx];
|
||||
*val2 = inv_icm42600_gyro_scale[2 * idx + 1];
|
||||
*val = gyro_st->scales[2 * idx];
|
||||
*val2 = gyro_st->scales[2 * idx + 1];
|
||||
return IIO_VAL_INT_PLUS_NANO;
|
||||
}
|
||||
|
||||
static int inv_icm42600_gyro_write_scale(struct inv_icm42600_state *st,
|
||||
static int inv_icm42600_gyro_write_scale(struct iio_dev *indio_dev,
|
||||
int val, int val2)
|
||||
{
|
||||
struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
|
||||
struct inv_icm42600_sensor_state *gyro_st = iio_priv(indio_dev);
|
||||
struct device *dev = regmap_get_device(st->map);
|
||||
unsigned int idx;
|
||||
struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
|
||||
int ret;
|
||||
|
||||
for (idx = 0; idx < ARRAY_SIZE(inv_icm42600_gyro_scale); idx += 2) {
|
||||
if (val == inv_icm42600_gyro_scale[idx] &&
|
||||
val2 == inv_icm42600_gyro_scale[idx + 1])
|
||||
for (idx = 0; idx < gyro_st->scales_len; idx += 2) {
|
||||
if (val == gyro_st->scales[idx] &&
|
||||
val2 == gyro_st->scales[idx + 1])
|
||||
break;
|
||||
}
|
||||
if (idx >= ARRAY_SIZE(inv_icm42600_gyro_scale))
|
||||
if (idx >= gyro_st->scales_len)
|
||||
return -EINVAL;
|
||||
|
||||
conf.fs = idx / 2;
|
||||
@ -321,7 +352,8 @@ static int inv_icm42600_gyro_write_odr(struct iio_dev *indio_dev,
|
||||
int val, int val2)
|
||||
{
|
||||
struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
|
||||
struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
|
||||
struct inv_icm42600_sensor_state *gyro_st = iio_priv(indio_dev);
|
||||
struct inv_sensors_timestamp *ts = &gyro_st->ts;
|
||||
struct device *dev = regmap_get_device(st->map);
|
||||
unsigned int idx;
|
||||
struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
|
||||
@ -576,7 +608,7 @@ static int inv_icm42600_gyro_read_raw(struct iio_dev *indio_dev,
|
||||
*val = data;
|
||||
return IIO_VAL_INT;
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
return inv_icm42600_gyro_read_scale(st, val, val2);
|
||||
return inv_icm42600_gyro_read_scale(indio_dev, val, val2);
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
return inv_icm42600_gyro_read_odr(st, val, val2);
|
||||
case IIO_CHAN_INFO_CALIBBIAS:
|
||||
@ -591,14 +623,16 @@ static int inv_icm42600_gyro_read_avail(struct iio_dev *indio_dev,
|
||||
const int **vals,
|
||||
int *type, int *length, long mask)
|
||||
{
|
||||
struct inv_icm42600_sensor_state *gyro_st = iio_priv(indio_dev);
|
||||
|
||||
if (chan->type != IIO_ANGL_VEL)
|
||||
return -EINVAL;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
*vals = inv_icm42600_gyro_scale;
|
||||
*vals = gyro_st->scales;
|
||||
*type = IIO_VAL_INT_PLUS_NANO;
|
||||
*length = ARRAY_SIZE(inv_icm42600_gyro_scale);
|
||||
*length = gyro_st->scales_len;
|
||||
return IIO_AVAIL_LIST;
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
*vals = inv_icm42600_gyro_odr;
|
||||
@ -629,7 +663,7 @@ static int inv_icm42600_gyro_write_raw(struct iio_dev *indio_dev,
|
||||
ret = iio_device_claim_direct_mode(indio_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = inv_icm42600_gyro_write_scale(st, val, val2);
|
||||
ret = inv_icm42600_gyro_write_scale(indio_dev, val, val2);
|
||||
iio_device_release_direct_mode(indio_dev);
|
||||
return ret;
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
@ -716,8 +750,8 @@ struct iio_dev *inv_icm42600_gyro_init(struct inv_icm42600_state *st)
|
||||
{
|
||||
struct device *dev = regmap_get_device(st->map);
|
||||
const char *name;
|
||||
struct inv_icm42600_sensor_state *gyro_st;
|
||||
struct inv_sensors_timestamp_chip ts_chip;
|
||||
struct inv_sensors_timestamp *ts;
|
||||
struct iio_dev *indio_dev;
|
||||
int ret;
|
||||
|
||||
@ -725,9 +759,21 @@ struct iio_dev *inv_icm42600_gyro_init(struct inv_icm42600_state *st)
|
||||
if (!name)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
indio_dev = devm_iio_device_alloc(dev, sizeof(*ts));
|
||||
indio_dev = devm_iio_device_alloc(dev, sizeof(*gyro_st));
|
||||
if (!indio_dev)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
gyro_st = iio_priv(indio_dev);
|
||||
|
||||
switch (st->chip) {
|
||||
case INV_CHIP_ICM42686:
|
||||
gyro_st->scales = inv_icm42686_gyro_scale;
|
||||
gyro_st->scales_len = ARRAY_SIZE(inv_icm42686_gyro_scale);
|
||||
break;
|
||||
default:
|
||||
gyro_st->scales = inv_icm42600_gyro_scale;
|
||||
gyro_st->scales_len = ARRAY_SIZE(inv_icm42600_gyro_scale);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* clock period is 32kHz (31250ns)
|
||||
@ -736,8 +782,7 @@ struct iio_dev *inv_icm42600_gyro_init(struct inv_icm42600_state *st)
|
||||
ts_chip.clock_period = 31250;
|
||||
ts_chip.jitter = 20;
|
||||
ts_chip.init_period = inv_icm42600_odr_to_period(st->conf.accel.odr);
|
||||
ts = iio_priv(indio_dev);
|
||||
inv_sensors_timestamp_init(ts, &ts_chip);
|
||||
inv_sensors_timestamp_init(&gyro_st->ts, &ts_chip);
|
||||
|
||||
iio_device_set_drvdata(indio_dev, st);
|
||||
indio_dev->name = name;
|
||||
@ -763,7 +808,8 @@ struct iio_dev *inv_icm42600_gyro_init(struct inv_icm42600_state *st)
|
||||
int inv_icm42600_gyro_parse_fifo(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
|
||||
struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
|
||||
struct inv_icm42600_sensor_state *gyro_st = iio_priv(indio_dev);
|
||||
struct inv_sensors_timestamp *ts = &gyro_st->ts;
|
||||
ssize_t i, size;
|
||||
unsigned int no;
|
||||
const void *accel, *gyro, *timestamp;
|
||||
|
@ -81,6 +81,9 @@ static const struct of_device_id inv_icm42600_of_matches[] = {
|
||||
}, {
|
||||
.compatible = "invensense,icm42605",
|
||||
.data = (void *)INV_CHIP_ICM42605,
|
||||
}, {
|
||||
.compatible = "invensense,icm42686",
|
||||
.data = (void *)INV_CHIP_ICM42686,
|
||||
}, {
|
||||
.compatible = "invensense,icm42622",
|
||||
.data = (void *)INV_CHIP_ICM42622,
|
||||
|
@ -77,6 +77,9 @@ static const struct of_device_id inv_icm42600_of_matches[] = {
|
||||
}, {
|
||||
.compatible = "invensense,icm42605",
|
||||
.data = (void *)INV_CHIP_ICM42605,
|
||||
}, {
|
||||
.compatible = "invensense,icm42686",
|
||||
.data = (void *)INV_CHIP_ICM42686,
|
||||
}, {
|
||||
.compatible = "invensense,icm42622",
|
||||
.data = (void *)INV_CHIP_ICM42622,
|
||||
|
Loading…
Reference in New Issue
Block a user