diff --git a/drivers/input/sensors/accel/Kconfig b/drivers/input/sensors/accel/Kconfig index 4576b8ccdb69..fb10b4c50c83 100644 --- a/drivers/input/sensors/accel/Kconfig +++ b/drivers/input/sensors/accel/Kconfig @@ -158,6 +158,12 @@ config ICM2060X_ACC To have support for your specific gsesnor you will have to select the proper drivers which depend on this option. +config ICM4260X_ACC + tristate "gsensor icm4260x" + help + To have support for your specific gsesnor you will have to + select the proper drivers which depend on this option. + config IAM20680_ACC tristate "gsensor iam20680" default n diff --git a/drivers/input/sensors/accel/Makefile b/drivers/input/sensors/accel/Makefile index 96f6cc6ee8e9..67e0bcdde3da 100644 --- a/drivers/input/sensors/accel/Makefile +++ b/drivers/input/sensors/accel/Makefile @@ -21,5 +21,6 @@ obj-$(CONFIG_GS_DA215S) += da215s/ obj-$(CONFIG_GS_DA223) += da223.o obj-$(CONFIG_GS_DA228E) += da228e/ obj-$(CONFIG_ICM2060X_ACC) += icm2060x_acc.o +obj-$(CONFIG_ICM4260X_ACC) += icm4260x_acc.o da223-y := da223_cust.o da223_core.o obj-$(CONFIG_IAM20680_ACC) += iam20680_acc.o diff --git a/drivers/input/sensors/accel/icm4260x_acc.c b/drivers/input/sensors/accel/icm4260x_acc.c new file mode 100644 index 000000000000..afc67123a844 --- /dev/null +++ b/drivers/input/sensors/accel/icm4260x_acc.c @@ -0,0 +1,470 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2023 Rockchip Co.,Ltd. + * Author: Wangqiang Guo + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include +#include + +/** + * icm4260x_set_idle() - Set Idle bit in PWR_MGMT_0 register + * @client: struct i2c_client.. + * + * Set ACCEL_LP_CLK_SEL as well when necessary with a proper wait + * + * Return: 0 when successful. + */ +static int icm4260x_set_idle(struct i2c_client *client) +{ + u8 reg_pwr_mgmt_0; + u8 d; + int ret = 0; + + reg_pwr_mgmt_0 = sensor_read_reg(client, ICM4260X_PWR_MGMT_0); + /* set Idle bit. + * when accel LPM is already enabled, set ACCEL_LP_CLK_SEL bit as well. + */ + d = reg_pwr_mgmt_0; + d |= BIT_IDLE; + if ((d & BIT_ACCEL_MODE_MASK) == BIT_ACCEL_MODE_LPM) + d |= BIT_ACCEL_LP_CLK_SEL; + + ret = sensor_write_reg(client, ICM4260X_PWR_MGMT_0, d); + usleep_range(20, 21); + + return ret; +} + +/** + * icm4260x_mreg_read() - Multiple byte read from MREG area. + * @client: struct i2c_client. + * @addr: MREG register start address including bank in upper byte. + * @len: length to read in byte. + * @data: pointer to store read data. + * + * Return: 0 when successful. + */ +static int icm4260x_mreg_read(struct i2c_client *client, int addr, int len, u8 *data) +{ + int ret; + u8 reg_pwr_mgmt_0; + + reg_pwr_mgmt_0 = sensor_read_reg(client, ICM4260X_PWR_MGMT_0); + + ret = icm4260x_set_idle(client); + if (ret) + return ret; + + ret = sensor_write_reg(client, ICM4260X_BLK_SEL_R, (addr >> 8) & 0xff); + usleep_range(INV_ICM42607_BLK_SEL_WAIT_US, + INV_ICM42607_BLK_SEL_WAIT_US + 1); + if (ret) + goto restore_bank; + + ret = sensor_write_reg(client, ICM4260X_MADDR_R, addr & 0xff); + usleep_range(INV_ICM42607_MADDR_WAIT_US, + INV_ICM42607_MADDR_WAIT_US + 1); + if (ret) + goto restore_bank; + + *data = ICM4260X_M_R; + ret = sensor_rx_data(client, data, len); + usleep_range(INV_ICM42607_M_RW_WAIT_US, + INV_ICM42607_M_RW_WAIT_US + 1); + if (ret) + goto restore_bank; + +restore_bank: + ret |= sensor_write_reg(client, ICM4260X_BLK_SEL_R, 0); + usleep_range(INV_ICM42607_BLK_SEL_WAIT_US, + INV_ICM42607_BLK_SEL_WAIT_US + 1); + + ret |= sensor_write_reg(client, ICM4260X_PWR_MGMT_0, reg_pwr_mgmt_0); + + return ret; +} + +/** + * icm4260x_mreg_single_write() - Single byte write to MREG area. + * @client: struct i2c_client. + * @addr: MREG register address including bank in upper byte. + * @data: data to write. + * + * Return: 0 when successful. + */ +static int icm4260x_mreg_single_write(struct i2c_client *client, int addr, u8 data) +{ + int ret; + u8 reg_pwr_mgmt_0; + + reg_pwr_mgmt_0 = sensor_read_reg(client, ICM4260X_PWR_MGMT_0); + + ret = icm4260x_set_idle(client); + if (ret) + return ret; + + ret = sensor_write_reg(client, ICM4260X_BLK_SEL_W, (addr >> 8) & 0xff); + usleep_range(INV_ICM42607_BLK_SEL_WAIT_US, + INV_ICM42607_BLK_SEL_WAIT_US + 1); + if (ret) + goto restore_bank; + + ret = sensor_write_reg(client, ICM4260X_MADDR_W, addr & 0xff); + usleep_range(INV_ICM42607_MADDR_WAIT_US, + INV_ICM42607_MADDR_WAIT_US + 1); + if (ret) + goto restore_bank; + + ret = sensor_write_reg(client, ICM4260X_M_W, data); + usleep_range(INV_ICM42607_M_RW_WAIT_US, + INV_ICM42607_M_RW_WAIT_US + 1); + if (ret) + goto restore_bank; + +restore_bank: + ret |= sensor_write_reg(client, ICM4260X_BLK_SEL_W, 0); + usleep_range(INV_ICM42607_BLK_SEL_WAIT_US, + INV_ICM42607_BLK_SEL_WAIT_US + 1); + + ret |= sensor_write_reg(client, ICM4260X_PWR_MGMT_0, reg_pwr_mgmt_0); + + return ret; +} + +/* + * OTP reload procedure. + */ +static int icm4260x_otp_reload(struct i2c_client *client) +{ + int ret; + u8 rb = 0; + + /* set idle bit */ + ret = icm4260x_set_idle(client); + if (ret) + return ret; + + /* Set OTP_COPY_MODE to 2'b01 */ + ret = icm4260x_mreg_read(client, ICM4260X_OTP_CONFIG_MREG_TOP1, 1, &rb); + if (ret) + return ret; + rb &= ~OTP_COPY_MODE_MASK; + rb |= BIT_OTP_COPY_NORMAL; + ret = icm4260x_mreg_single_write(client, ICM4260X_OTP_CONFIG_MREG_TOP1, rb); + if (ret) + return ret; + + /* set OTP_PWR_DOWN to 1'b0 and wait for 300us */ + ret = icm4260x_mreg_read(client, ICM4260X_OTP_CTRL7_MREG_OTP, 1, &rb); + if (ret) + return ret; + rb &= ~BIT_OTP_PWR_DOWN; + ret = icm4260x_mreg_single_write(client, ICM4260X_OTP_CTRL7_MREG_OTP, rb); + if (ret) + return ret; + usleep_range(300, 400); + + /* set OTP_RELOAD to 1'b1 and wait for 280us */ + ret = icm4260x_mreg_read(client, ICM4260X_OTP_CTRL7_MREG_OTP, 1, &rb); + if (ret) + return ret; + rb |= BIT_OTP_RELOAD; + ret = icm4260x_mreg_single_write(client, ICM4260X_OTP_CTRL7_MREG_OTP, rb); + if (ret) + return ret; + usleep_range(280, 380); + + return 0; +} + +static int sensor_active(struct i2c_client *client, int enable, int rate) +{ + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(client); + int result = 0; + u8 status = 0; + + sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg); + + if (!enable) { + status = (0xff & ~BIT_ACCEL_MODE_MASK); + sensor->ops->ctrl_data &= status; + } else { + status = BIT_ACCEL_MODE_LNM; + sensor->ops->ctrl_data |= status; + sensor->ops->ctrl_data &= ~BIT_IDLE; + } + + result = sensor_write_reg(client, sensor->ops->ctrl_reg, + sensor->ops->ctrl_data); + if (result) { + dev_err(&client->dev, + "%s: fail to set pwr_mgmt0(%d)\n", __func__, result); + return result; + } + usleep_range(250, 260); + + return result; +} + +/* + * write POR value + */ + +static int icm4260x_set_default_register(struct i2c_client *client) +{ + int status = 0; + + status |= sensor_write_reg(client, ICM4260X_GYRO_CONFIG0, 0x06); + status |= sensor_write_reg(client, ICM4260X_ACCEL_CONFIG0, 0x06); + status |= sensor_write_reg(client, ICM4260X_APEX_CONFIG0, 0x08); + status |= sensor_write_reg(client, ICM4260X_APEX_CONFIG1, 0x02); + status |= sensor_write_reg(client, ICM4260X_WOM_CONFIG, 0); + status |= sensor_write_reg(client, ICM4260X_FIFO_CONFIG1, 0x01); + status |= sensor_write_reg(client, ICM4260X_FIFO_CONFIG2, 0); + status |= sensor_write_reg(client, ICM4260X_FIFO_CONFIG3, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_FIFO_CONFIG5_MREG_TOP1, 0x20); + status |= icm4260x_mreg_single_write(client, ICM4260X_ST_CONFIG_MREG_TOP1, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_INT_SOURCE7_MREG_TOP1, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_INT_SOURCE8_MREG_TOP1, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_INT_SOURCE9_MREG_TOP1, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_INT_SOURCE10_MREG_TOP1, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_APEX_CONFIG2_MREG_TOP1, 0xA2); + status |= icm4260x_mreg_single_write(client, ICM4260X_APEX_CONFIG3_MREG_TOP1, 0x85); + status |= icm4260x_mreg_single_write(client, ICM4260X_APEX_CONFIG4_MREG_TOP1, 0x51); + status |= icm4260x_mreg_single_write(client, ICM4260X_APEX_CONFIG5_MREG_TOP1, 0x80); + status |= icm4260x_mreg_single_write(client, ICM4260X_APEX_CONFIG9_MREG_TOP1, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_APEX_CONFIG10_MREG_TOP1, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_APEX_CONFIG11_MREG_TOP1, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_ACCEL_WOM_X_THR_MREG_TOP1, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_ACCEL_WOM_Y_THR_MREG_TOP1, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_ACCEL_WOM_Z_THR_MREG_TOP1, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_GOS_USER0_MREG_TOP1, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_GOS_USER1_MREG_TOP1, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_GOS_USER2_MREG_TOP1, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_GOS_USER3_MREG_TOP1, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_GOS_USER4_MREG_TOP1, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_GOS_USER5_MREG_TOP1, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_GOS_USER6_MREG_TOP1, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_GOS_USER7_MREG_TOP1, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_GOS_USER8_MREG_TOP1, 0); + status |= icm4260x_mreg_single_write(client, ICM4260X_APEX_CONFIG12_MREG_TOP1, 0); + + if (status) + return -EIO; + + return 0; +} + +static int sensor_init(struct i2c_client *client) +{ + int ret = 0; + u8 device_id = 0, value = 0; + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(client); + + device_id = sensor_read_reg(client, ICM4260X_WHO_AM_I); + if (device_id != ICM42607_DEVICE_ID) { + dev_err(&client->dev, "%s: check id err, read_id: %d\n", + __func__, device_id); + return -1; + } + + ret = icm4260x_otp_reload(client); + if (ret) { + dev_err(&client->dev, + "ICM4260X OTP reload error,ret: %d!\n", ret); + return ret; + } + + + ret = icm4260x_set_default_register(client); + if (ret) { + dev_err(&client->dev, + "set ICM4260X default_register error,ret: %d!\n", ret); + return ret; + } + + /* SPI or I2C only + * FIFO count : byte mode, big endian + * sensor data : big endian + */ + value |= BIT_FIFO_COUNT_ENDIAN; + value |= BIT_SENSOR_DATA_ENDIAN; + ret = sensor_write_reg(client, ICM4260X_INTF_CONFIG0, value); + if (ret) + return ret; + + /* configure clock */ + value = BIT_CLK_SEL_PLL | BIT_I3C_SDR_EN | BIT_I3C_DDR_EN; + ret = sensor_write_reg(client, ICM4260X_INTF_CONFIG1, value); + if (ret) + return ret; + + /* INT pin configuration */ + /* + * value = (INT_POLARITY << SHIFT_INT1_POLARITY) | + * (INT_DRIVE_CIRCUIT << SHIFT_INT1_DRIVE_CIRCUIT) | + * (INT_MODE << SHIFT_INT1_MODE); + * ret = sensor_write_reg(client, ICM4260X_INT_CONFIG_REG, value); + * if (ret) + * return ret; + */ + + /* disable sensors */ + ret = sensor_write_reg(client, ICM4260X_PWR_MGMT_0, 0); + if (ret) + return ret; + + /* set Full scale select for accelerometer UI interface output*/ + value = sensor_read_reg(client, ICM4260X_ACCEL_CONFIG0); + value &= ~BIT_ACCEL_FSR; + value |= ACCEL_FS_SEL << SHIFT_ACCEL_FS_SEL; + ret = sensor_write_reg(client, ICM4260X_ACCEL_CONFIG0, value); + if (ret) + return ret; + + /* turn on accelerometer*/ + ret = sensor->ops->active(client, 0, sensor->pdata->poll_delay_ms); + if (ret) { + dev_err(&client->dev, + "%s: fail to active sensor(%d)\n", __func__, ret); + return ret; + } + + return ret; +} + +static int gsensor_report_value(struct i2c_client *client, + struct sensor_axis *axis) +{ + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(client); + + if (sensor->status_cur == SENSOR_ON) { + /* Report acceleration sensor information */ + input_report_abs(sensor->input_dev, ABS_X, axis->x); + input_report_abs(sensor->input_dev, ABS_Y, axis->y); + input_report_abs(sensor->input_dev, ABS_Z, axis->z); + input_sync(sensor->input_dev); + } + + return 0; +} + +static int sensor_report_value(struct i2c_client *client) +{ + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(client); + struct sensor_platform_data *pdata = sensor->pdata; + int ret = 0; + short x, y, z; + struct sensor_axis axis; + u8 buffer[6] = {0}; + + if (sensor->ops->read_len < 6) { + dev_err(&client->dev, "%s: length is error, len = %d\n", + __func__, sensor->ops->read_len); + return -EINVAL; + } + + /* Data bytes from hardware xH, xL, yH, yL, zH, zL */ + *buffer = sensor->ops->read_reg; + ret = sensor_rx_data(client, buffer, sensor->ops->read_len); + if (ret < 0) { + dev_err(&client->dev, + "%s: read data failed, ret = %d\n", __func__, ret); + return ret; + } + x = ((buffer[0] << 8) & 0xff00) + (buffer[1] & 0xFF); + y = ((buffer[2] << 8) & 0xff00) + (buffer[3] & 0xFF); + z = ((buffer[4] << 8) & 0xff00) + (buffer[5] & 0xFF); + + //printk("%s,x:%d, y:%d, z:%d\n", __func__, x, y, z); + axis.x = (pdata->orientation[0]) * x + (pdata->orientation[1]) * y + + (pdata->orientation[2]) * z; + axis.y = (pdata->orientation[3]) * x + (pdata->orientation[4]) * y + + (pdata->orientation[5]) * z; + axis.z = (pdata->orientation[6]) * x + (pdata->orientation[7]) * y + + (pdata->orientation[8]) * z; + + gsensor_report_value(client, &axis); + + mutex_lock(&(sensor->data_mutex)); + sensor->axis = axis; + mutex_unlock(&(sensor->data_mutex)); + + return ret; +} + +static struct sensor_operate gsensor_icm4260x_ops = { + .name = "icm4260x_acc", + .type = SENSOR_TYPE_ACCEL, + .id_i2c = ACCEL_ID_ICM4260X, + .read_reg = ICM4260X_ACCEL_DATA_X0, + .read_len = 6, + .id_reg = SENSOR_UNKNOW_DATA, + .id_data = SENSOR_UNKNOW_DATA, + .precision = ICM4260X_PRECISION, + .ctrl_reg = ICM4260X_PWR_MGMT_0, + .int_status_reg = ICM4260X_INT_STATUS, + .range = {-32768, 32768}, + .trig = IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + .active = sensor_active, + .init = sensor_init, + .report = sensor_report_value, +}; + +/****************operate according to sensor chip:end************/ +static int gsensor_icm4260x_probe(struct i2c_client *client, + const struct i2c_device_id *devid) +{ + client->addr = ICM42607_ADDR; + return sensor_register_device(client, NULL, devid, &gsensor_icm4260x_ops); +} + +static void gsensor_icm4260x_remove(struct i2c_client *client) +{ + sensor_unregister_device(client, NULL, &gsensor_icm4260x_ops); +} + +static const struct i2c_device_id gsensor_icm4260x_id[] = { + {"icm42607_acc", ACCEL_ID_ICM4260X}, + {} +}; + +static struct i2c_driver gsensor_icm4260x_driver = { + .probe = gsensor_icm4260x_probe, + .remove = gsensor_icm4260x_remove, + .shutdown = sensor_shutdown, + .id_table = gsensor_icm4260x_id, + .driver = { + .name = "gsensor_icm4260x", +#ifdef CONFIG_PM + .pm = &sensor_pm_ops, +#endif + }, +}; + +module_i2c_driver(gsensor_icm4260x_driver); + +MODULE_AUTHOR("Wangqiang Guo "); +MODULE_DESCRIPTION("icm4260x_acc 3-Axis accelerometer driver"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/input/sensors/gyro/Kconfig b/drivers/input/sensors/gyro/Kconfig index 5b27389831ee..58b9b6dc0540 100644 --- a/drivers/input/sensors/gyro/Kconfig +++ b/drivers/input/sensors/gyro/Kconfig @@ -40,6 +40,12 @@ config GYRO_LSM330 config GYRO_ICM2060X tristate "gyroscope icm2060x_gyro" +config GYRO_ICM4260X + tristate "gyroscope icm4260x_gyro" + help + To have support for your specific gyro you will have to + select the proper drivers which depend on this option. + config GYRO_IAM20680 tristate "gyroscope iam20680_gyro" default n diff --git a/drivers/input/sensors/gyro/Makefile b/drivers/input/sensors/gyro/Makefile index 8c0a42734c65..d8c149baabc4 100644 --- a/drivers/input/sensors/gyro/Makefile +++ b/drivers/input/sensors/gyro/Makefile @@ -9,4 +9,5 @@ obj-$(CONFIG_GYRO_MPU6500) += mpu6500_gyro.o obj-$(CONFIG_GYRO_MPU6880) += mpu6880_gyro.o obj-$(CONFIG_GYRO_LSM330) += lsm330_gyro.o obj-$(CONFIG_GYRO_ICM2060X) += icm2060x_gyro.o +obj-$(CONFIG_GYRO_ICM4260X) += icm4260x_gyro.o obj-$(CONFIG_GYRO_IAM20680) += iam20680_gyro.o diff --git a/drivers/input/sensors/gyro/icm4260x_gyro.c b/drivers/input/sensors/gyro/icm4260x_gyro.c new file mode 100644 index 000000000000..e66729d25116 --- /dev/null +++ b/drivers/input/sensors/gyro/icm4260x_gyro.c @@ -0,0 +1,211 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2023 Rockchip Co.,Ltd. + * Author: Wangqiang Guo + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif +#include +#include + +static int sensor_active(struct i2c_client *client, int enable, int rate) +{ + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(client); + int result = 0; + int status = 0; + + sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg); + + if (!enable) { + status = (0xff & ~BIT_GYRO_MODE_MASK); + sensor->ops->ctrl_data &= status; + } else { + status = BIT_GYRO_MODE_LNM; + sensor->ops->ctrl_data |= status; + sensor->ops->ctrl_data &= ~BIT_IDLE; + } + + result = sensor_write_reg(client, sensor->ops->ctrl_reg, + sensor->ops->ctrl_data); + if (result) { + dev_err(&client->dev, + "%s: fail to set pwr_mgmt0(%d)\n", __func__, result); + return result; + } + /* Gyroscope needs to be kept ON for a minimum of 45ms */ + usleep_range(45*1000, 45*1010); + + return result; +} + +static int sensor_init(struct i2c_client *client) +{ + int ret = 0; + u8 value; + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(client); + + /* + * init on icm42607_acc.c + */ + + /* set Full scale select for accelerometer UI interface output*/ + value = sensor_read_reg(client, ICM4260X_GYRO_CONFIG0); + value &= ~BIT_GYRO_FSR; + value |= GYRO_FS_SEL << SHIFT_GYRO_FS_SEL; + ret = sensor_write_reg(client, ICM4260X_GYRO_CONFIG0, value); + if (ret) + return ret; + + /* turn on accelerometer*/ + ret = sensor->ops->active(client, 0, sensor->pdata->poll_delay_ms); + if (ret) { + dev_err(&client->dev, + "%s: fail to active sensor(%d)\n", __func__, ret); + return ret; + } + + return ret; +} + +static int gyro_report_value(struct i2c_client *client, + struct sensor_axis *axis) +{ + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(client); + + if (sensor->status_cur == SENSOR_ON) { + /* Report acceleration sensor information */ + input_report_abs(sensor->input_dev, ABS_RX, axis->x); + input_report_abs(sensor->input_dev, ABS_RY, axis->y); + input_report_abs(sensor->input_dev, ABS_RZ, axis->z); + input_sync(sensor->input_dev); + } + + return 0; +} + +static int sensor_report_value(struct i2c_client *client) +{ + struct sensor_private_data *sensor = + (struct sensor_private_data *) i2c_get_clientdata(client); + struct sensor_platform_data *pdata = sensor->pdata; + int ret = 0; + short x, y, z; + struct sensor_axis axis; + u8 buffer[6] = {0}; + + if (sensor->ops->read_len < 6) { + dev_err(&client->dev, "%s: length is error, len = %d\n", + __func__, sensor->ops->read_len); + return -EINVAL; + } + + *buffer = sensor->ops->read_reg; + ret = sensor_rx_data(client, buffer, sensor->ops->read_len); + if (ret < 0) { + dev_err(&client->dev, + "%s: read data failed, ret = %d\n", __func__, ret); + return ret; + } + + x = ((buffer[0] << 8) & 0xff00) + (buffer[1] & 0xFF); + y = ((buffer[2] << 8) & 0xff00) + (buffer[3] & 0xFF); + z = ((buffer[4] << 8) & 0xff00) + (buffer[5] & 0xFF); + + axis.x = (pdata->orientation[0]) * x + (pdata->orientation[1]) * y + + (pdata->orientation[2]) * z; + axis.y = (pdata->orientation[3]) * x + (pdata->orientation[4]) * y + + (pdata->orientation[5]) * z; + axis.z = (pdata->orientation[6]) * x + (pdata->orientation[7]) * y + + (pdata->orientation[8]) * z; + + gyro_report_value(client, &axis); + + mutex_lock(&(sensor->data_mutex)); + sensor->axis = axis; + mutex_unlock(&(sensor->data_mutex)); + + return ret; +} + +static struct sensor_operate gyro_icm4260x_ops = { + .name = "icm4260x_gyro", + .type = SENSOR_TYPE_GYROSCOPE, + .id_i2c = GYRO_ID_ICM4260X, + .read_reg = ICM4260X_GYRO_DATA_X0, + .read_len = 6, + .id_reg = SENSOR_UNKNOW_DATA, + .id_data = SENSOR_UNKNOW_DATA, + .precision = ICM4260X_PRECISION, + .ctrl_reg = ICM4260X_PWR_MGMT_0, + .int_status_reg = ICM4260X_INT_STATUS, + .range = {-32768, 32768}, + .trig = IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + .active = sensor_active, + .init = sensor_init, + .report = sensor_report_value, +}; + +/****************operate according to sensor chip:end************/ +static int gyro_icm4260x_probe(struct i2c_client *client, + const struct i2c_device_id *devid) +{ + client->addr = ICM42607_ADDR; + return sensor_register_device(client, NULL, devid, &gyro_icm4260x_ops); +} + +static void gyro_icm4260x_remove(struct i2c_client *client) +{ + sensor_unregister_device(client, NULL, &gyro_icm4260x_ops); +} + +static const struct i2c_device_id gyro_icm4260x_id[] = { + {"icm42607_gyro", GYRO_ID_ICM4260X}, + {} +}; + +static struct i2c_driver gyro_icm4260x_driver = { + .probe = gyro_icm4260x_probe, + .remove = gyro_icm4260x_remove, + .shutdown = sensor_shutdown, + .id_table = gyro_icm4260x_id, + .driver = { + .name = "gyro_icm4260x", +#ifdef CONFIG_PM + .pm = &sensor_pm_ops, +#endif + }, +}; + +static int __init gyro_icm4260x_init(void) +{ + return i2c_add_driver(&gyro_icm4260x_driver); +} + +static void __exit gyro_icm4260x_exit(void) +{ + i2c_del_driver(&gyro_icm4260x_driver); +} +/* must register after icm4260x_acc */ +device_initcall_sync(gyro_icm4260x_init); +module_exit(gyro_icm4260x_exit); + +MODULE_AUTHOR("Wangqiang Guo "); +MODULE_DESCRIPTION("icm4260x_gyro 3-Axis accelerometer driver"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/icm4260x.h b/include/linux/icm4260x.h new file mode 100644 index 000000000000..8917d8bc307e --- /dev/null +++ b/include/linux/icm4260x.h @@ -0,0 +1,432 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Definitions for icm4260x chip. + */ +#ifndef __ICM4260X_ACC_H +#define __ICM4260X_ACC_H + +/* Registers and associated bit definitions */ +/* Bank 0 */ +#define ICM4260X_MISC_1 0x00 +#define ICM4260X_CHIP_CONFIG_REG 0x01 +#define ICM4260X_SIGNAL_PATH_RESET 0x02 +#define ICM4260X_DRIVE_CONFIG_REG1 0x03 +#define ICM4260X_DRIVE_CONFIG_REG2 0x04 +#define ICM4260X_DRIVE_CONFIG_REG3 0x05 +#define ICM4260X_INT_CONFIG_REG 0x06 +#define ICM4260X_ODRGRID0 0x07 +#define ICM4260X_ODRGRID1 0x08 +#define ICM4260X_TEMP_DATA0 0x09 +#define ICM4260X_TEMP_DATA1 0x0a +#define ICM4260X_ACCEL_DATA_X0 0x0b +#define ICM4260X_ACCEL_DATA_X1 0x0c +#define ICM4260X_ACCEL_DATA_Y0 0x0d +#define ICM4260X_ACCEL_DATA_Y1 0x0e +#define ICM4260X_ACCEL_DATA_Z0 0x0f +#define ICM4260X_ACCEL_DATA_Z1 0x10 +#define ICM4260X_GYRO_DATA_X0 0x11 +#define ICM4260X_GYRO_DATA_X1 0x12 +#define ICM4260X_GYRO_DATA_Y0 0x13 +#define ICM4260X_GYRO_DATA_Y1 0x14 +#define ICM4260X_GYRO_DATA_Z0 0x15 +#define ICM4260X_GYRO_DATA_Z1 0x16 +#define ICM4260X_TMST_FSYNC1 0x17 +#define ICM4260X_TMST_FSYNC2 0x18 +#define ICM4260X_ODR_LP_STATUS 0x19 +#define ICM4260X_PWR_MGMT_0 0x1f +#define ICM4260X_GYRO_CONFIG0 0x20 +#define ICM4260X_ACCEL_CONFIG0 0x21 +#define ICM4260X_TEMP_CONFIG0 0x22 +#define ICM4260X_GYRO_CONFIG1 0x23 +#define ICM4260X_ACCEL_CONFIG1 0x24 +#define ICM4260X_APEX_CONFIG0 0x25 +#define ICM4260X_APEX_CONFIG1 0x26 +#define ICM4260X_WOM_CONFIG 0x27 +#define ICM4260X_FIFO_CONFIG1 0x28 +#define ICM4260X_FIFO_CONFIG2 0x29 +#define ICM4260X_FIFO_CONFIG3 0x2a +#define ICM4260X_INT_SOURCE0 0x2b +#define ICM4260X_INT_SOURCE1 0x2c +#define ICM4260X_INT_SOURCE3 0x2d +#define ICM4260X_INT_SOURCE4 0x2e +#define ICM4260X_FIFO_LOST_PKT0 0x2f +#define ICM4260X_FIFO_LOST_PKT1 0x30 +#define ICM4260X_APEX_DATA0 0x31 +#define ICM4260X_APEX_DATA1 0x32 +#define ICM4260X_APEX_DATA2 0x33 +#define ICM4260X_APEX_DATA3 0x34 +#define ICM4260X_INTF_CONFIG0 0x35 +#define ICM4260X_INTF_CONFIG1 0x36 +#define ICM4260X_INT_STATUS_DRDY 0x39 +#define ICM4260X_INT_STATUS 0x3a +#define ICM4260X_INT_STATUS2 0x3b +#define ICM4260X_INT_STATUS3 0x3c +#define ICM4260X_FIFO_BYTE_COUNT1 0x3d +#define ICM4260X_FIFO_BYTE_COUNT2 0x3e +#define ICM4260X_FIFO_DATA_REG 0x3f +#define ICM4260X_S4S_GYRO_TPH1 0x40 +#define ICM4260X_S4S_GYRO_TPH2 0x41 +#define ICM4260X_S4S_ACCEL_TPH1 0x42 +#define ICM4260X_S4S_ACCEL_TPH2 0x43 +#define ICM4260X_S4S_RR 0x44 +#define ICM4260X_GYR_BIAS_CFG1 0x46 +#define ICM4260X_WHO_AM_I 0x75 +#define ICM4260X_S4S_ST 0x76 +#define ICM4260X_S4S_ST_CLONE 0x77 +#define ICM4260X_S4S_DT 0x78 +#define ICM4260X_BLK_SEL_W 0x79 +#define ICM4260X_MADDR_W 0x7a +#define ICM4260X_M_W 0x7b +#define ICM4260X_BLK_SEL_R 0x7c +#define ICM4260X_MADDR_R 0x7d +#define ICM4260X_M_R 0x7e + +/* MREG_TOP1 */ +#define ICM4260X_TMST_CONFIG1_MREG_TOP1 0x00 +#define ICM4260X_FIFO_CONFIG5_MREG_TOP1 0x01 +#define ICM4260X_FIFO_CONFIG6_MREG_TOP1 0x02 +#define ICM4260X_FSYNC_CONFIG_MREG_TOP1 0x03 +#define ICM4260X_INT_CONFIG0_MREG_TOP1 0x04 +#define ICM4260X_INT_CONFIG1_MREG_TOP1 0x05 +#define ICM4260X_AFSR_CONFIG0_MREG_TOP1 0x07 +#define ICM4260X_AFSR_CONFIG1_MREG_TOP1 0x08 +#define ICM4260X_TBC_RCOSC_MREG_TOP1 0x0d +#define ICM4260X_TBC_PLL_MREG_TOP1 0x0e +#define ICM4260X_ST_CONFIG_MREG_TOP1 0x13 +#define ICM4260X_SELFTEST_MREG_TOP1 0x14 +#define ICM4260X_PADS_CONFIG3_MREG_TOP1 0x17 +#define ICM4260X_TEMP_CONFIG1_MREG_TOP1 0x1c +#define ICM4260X_TEMP_CONFIG3_MREG_TOP1 0x1e +#define ICM4260X_S4S_CONFIG1_MREG_TOP1 0x1f +#define ICM4260X_S4S_CONFIG2_MREG_TOP1 0x20 +#define ICM4260X_S4S_FREQ_RATIO1_MREG_TOP1 0x21 +#define ICM4260X_S4S_FREQ_RATIO2_MREG_TOP1 0x22 +#define ICM4260X_INTF_CONFIG6_MREG_TOP1 0x23 +#define ICM4260X_INTF_CONFIG10_MREG_TOP1 0x25 +#define ICM4260X_INTF_CONFIG7_MREG_TOP1 0x28 +#define ICM4260X_OTP_CONFIG_MREG_TOP1 0x2b +#define ICM4260X_INT_SOURCE6_MREG_TOP1 0x2f +#define ICM4260X_INT_SOURCE7_MREG_TOP1 0x30 +#define ICM4260X_INT_SOURCE8_MREG_TOP1 0x31 +#define ICM4260X_INT_SOURCE9_MREG_TOP1 0x32 +#define ICM4260X_INT_SOURCE10_MREG_TOP1 0x33 +#define ICM4260X_GYRO_PWR_CFG0_MREG_TOP1 0x38 +#define ICM4260X_ACCEL_CP_CFG0_MREG_TOP1 0x39 +#define ICM4260X_APEX_CONFIG2_MREG_TOP1 0x44 +#define ICM4260X_APEX_CONFIG3_MREG_TOP1 0x45 +#define ICM4260X_APEX_CONFIG4_MREG_TOP1 0x46 +#define ICM4260X_APEX_CONFIG5_MREG_TOP1 0x47 +#define ICM4260X_APEX_CONFIG9_MREG_TOP1 0x48 +#define ICM4260X_APEX_CONFIG10_MREG_TOP1 0x49 +#define ICM4260X_APEX_CONFIG11_MREG_TOP1 0x4a +#define ICM4260X_APEX_CONFIG12_MREG_TOP1 0x67 +#define ICM4260X_ACCEL_WOM_X_THR_MREG_TOP1 0x4b +#define ICM4260X_ACCEL_WOM_Y_THR_MREG_TOP1 0x4c +#define ICM4260X_ACCEL_WOM_Z_THR_MREG_TOP1 0x4d +#define ICM4260X_GOS_USER0_MREG_TOP1 0x4e +#define ICM4260X_GOS_USER1_MREG_TOP1 0x4f +#define ICM4260X_GOS_USER2_MREG_TOP1 0x50 +#define ICM4260X_GOS_USER3_MREG_TOP1 0x51 +#define ICM4260X_GOS_USER4_MREG_TOP1 0x52 +#define ICM4260X_GOS_USER5_MREG_TOP1 0x53 +#define ICM4260X_GOS_USER6_MREG_TOP1 0x54 +#define ICM4260X_GOS_USER7_MREG_TOP1 0x55 +#define ICM4260X_GOS_USER8_MREG_TOP1 0x56 +#define ICM4260X_ST_STATUS1_MREG_TOP1 0x63 +#define ICM4260X_ST_STATUS2_MREG_TOP1 0x64 + +/* MMEM_TOP */ +#define ICM4260X_XA_ST_DATA_MMEM_TOP 0x5000 +#define ICM4260X_YA_ST_DATA_MMEM_TOP 0x5001 +#define ICM4260X_ZA_ST_DATA_MMEM_TOP 0x5002 +#define ICM4260X_XG_ST_DATA_MMEM_TOP 0x5003 +#define ICM4260X_YG_ST_DATA_MMEM_TOP 0x5004 +#define ICM4260X_ZG_ST_DATA_MMEM_TOP 0x5005 + +/* MREG_OTP */ +#define ICM4260X_OTP_CTRL7_MREG_OTP 0x2806 + +/* Bank0 REG_GYRO_CONFIG0/REG_ACCEL_CONFIG0 */ +#define SHIFT_GYRO_FS_SEL 5 +#define SHIFT_ACCEL_FS_SEL 5 +#define SHIFT_ODR_CONF 0 +#define BIT_GYRO_FSR 0x60 +#define BIT_GYRO_ODR 0x0F +#define BIT_ACCEL_FSR 0x60 +#define ACCEL_FS_SEL 3 //(-2G, +2G) +#define GYRO_FS_SEL 3 //00~11:2000dps\1000dps\500dps\250dps +#define BIT_ACCEL_ODR 0x0F +#define BIT_SENSOR_ODR_800HZ 0x06 +#define BIT_SENSOR_ODR_400HZ 0x07 +#define BIT_SENSOR_ODR_200HZ 0x08 +#define BIT_SENSOR_ODR_100HZ 0x09 +#define BIT_SENSOR_ODR_50HZ 0x0A +#define BIT_SENSOR_ODR_25HZ 0x0B +#define BIT_SENSOR_ODR_12HZ 0x0C +#define BIT_SENSOR_ODR_6HZ 0x0D +#define BIT_SENSOR_ODR_3HZ 0x0E + +/* Bank0 REG_GYRO_CONFIG1 */ +#define BIT_GYR_UI_FLT_BW_BYPASS 0x00 +#define BIT_GYR_UI_FLT_BW_180HZ 0x01 +#define BIT_GYR_UI_FLT_BW_121HZ 0x02 +#define BIT_GYR_UI_FLT_BW_73HZ 0x03 +#define BIT_GYR_UI_FLT_BW_53HZ 0x04 +#define BIT_GYR_UI_FLT_BW_34HZ 0x05 +#define BIT_GYR_UI_FLT_BW_25HZ 0x06 +#define BIT_GYR_UI_FLT_BW_16HZ 0x07 +#define BIT_GYR_UI_AVG_IND_2X 0x00 +#define BIT_GYR_UI_AVG_IND_4X 0x10 +#define BIT_GYR_UI_AVG_IND_8X 0x20 +#define BIT_GYR_UI_AVG_IND_16X 0x30 +#define BIT_GYR_UI_AVG_IND_32X 0x40 +#define BIT_GYR_UI_AVG_IND_64X 0x50 + +/* Bank0 REG_ACCEL_CONFIG1 */ +#define BIT_ACC_FILT_BW_IND_BYPASS 0x00 +#define BIT_ACC_FILT_BW_IND_180HZ 0x01 +#define BIT_ACC_FILT_BW_IND_121HZ 0x02 +#define BIT_ACC_FILT_BW_IND_73HZ 0x03 +#define BIT_ACC_FILT_BW_IND_53HZ 0x04 +#define BIT_ACC_FILT_BW_IND_34HZ 0x05 +#define BIT_ACC_FILT_BW_IND_25HZ 0x06 +#define BIT_ACC_FILT_BW_IND_16HZ 0x07 +#define BIT_ACC_UI_AVG_IND_2X 0x00 +#define BIT_ACC_UI_AVG_IND_4X 0x10 +#define BIT_ACC_UI_AVG_IND_8X 0x20 +#define BIT_ACC_UI_AVG_IND_16X 0x30 +#define BIT_ACC_UI_AVG_IND_32X 0x40 +#define BIT_ACC_UI_AVG_IND_64X 0x50 + +/* Bank0 REG_INT_CONFIG_REG */ +#define SHIFT_INT1_MODE 0x02 +#define SHIFT_INT1_DRIVE_CIRCUIT 0x01 +#define SHIFT_INT1_POLARITY 0x00 + +/* Bank0 REG_PWR_MGMT_0 */ +#define BIT_ACCEL_MODE_OFF 0x00 +#define BIT_ACCEL_MODE_LPM 0x02 +#define BIT_ACCEL_MODE_LNM 0x03 +#define BIT_ACCEL_MODE_MASK 0x03 +#define BIT_GYRO_MODE_OFF 0x00 +#define BIT_GYRO_MODE_STBY 0x04 +#define BIT_GYRO_MODE_LPM 0x08 +#define BIT_GYRO_MODE_LNM 0x0c +#define BIT_GYRO_MODE_MASK 0x0c +#define BIT_IDLE 0x10 +#define BIT_ACCEL_LP_CLK_SEL 0x80 + +/* Bank0 REG_SIGNAL_PATH_RESET */ +#define BIT_FIFO_FLUSH 0x04 +#define BIT_SOFT_RESET_CHIP_CONFIG 0x10 + +/* Bank0 REG_INTF_CONFIG0 */ +#define BIT_SIFS_CFG_I2C_ONLY 0x02 +#define BIT_SIFS_CFG_SPI_ONLY 0x03 +#define BIT_SENSOR_DATA_ENDIAN 0x10 +#define BIT_FIFO_COUNT_ENDIAN 0x20 +#define BIT_FIFO_COUNT_FORMAT 0x40 +#define BIT_FIFO_SREG_INVALID_IND_DIS 0x80 + +/* Bank0 REG_INTF_CONFIG1 */ +#define BIT_CLK_SEL_RC 0x00 +#define BIT_CLK_SEL_PLL 0x01 +#define BIT_CLK_SEL_DIS 0x03 +#define BIT_I3C_DDR_EN 0x04 +#define BIT_I3C_SDR_EN 0x08 +#define BIT_GYRO_AFSR_MODE_LFS 0x00 +#define BIT_GYRO_AFSR_MODE_HFS 0x20 +#define BIT_GYRO_AFSR_MODE_DYN 0x40 + +/* Bank0 REG_FIFO_CONFIG1 */ +#define BIT_FIFO_MODE_NO_BYPASS 0x00 +#define BIT_FIFO_MODE_BYPASS 0x01 +#define BIT_FIFO_MODE_STREAM 0x00 +#define BIT_FIFO_MODE_STOPFULL 0x02 + +/* Bank 0 REG_INT_SOURCE0 */ +#define BIT_INT_AGC_RDY_INT1_EN 0x01 +#define BIT_INT_FIFO_FULL_INT1_EN 0x02 +#define BIT_INT_FIFO_THS_INT1_EN 0x04 +#define BIT_INT_DRDY_INT_EN 0x08 +#define BIT_INT_RESET_DONE_INT1_EN 0x10 +#define BIT_INT_PLL_RDY_INT1_EN 0x20 +#define BIT_INT_FSYNC_INT1_EN 0x40 +#define BIT_INT_ST_DONE_INT1_EN 0x80 + +/* Bank 0 REG_INT_SOURCE1 */ +#define BIT_INT_WOM_X_INT1_EN 0x01 +#define BIT_INT_WOM_Y_INT1_EN 0x02 +#define BIT_INT_WOM_Z_INT1_EN 0x04 +#define BIT_INT_WOM_XYZ_INT1_EN (BIT_INT_WOM_X_INT1_EN | \ + BIT_INT_WOM_Y_INT1_EN | BIT_INT_WOM_Z_INT1_EN) +#define BIT_INT_SMD_INT1_EN 0x08 +#define BIT_INT_I3C_PROTCL_ERR_INT1_EN 0x40 + +/* Bank0 REG_INT_STATUS_DRDY */ +#define BIT_INT_STATUS_DRDY 0x01 + +/* Bank0 REG_INT_STATUS */ +#define BIT_INT_STATUS_AGC_RDY 0x01 +#define BIT_INT_STATUS_FIFO_FULL 0x02 +#define BIT_INT_STATUS_FIFO_THS 0x04 +#define BIT_INT_STATUS_RESET_DONE 0x10 +#define BIT_INT_STATUS_PLL_RDY 0x20 +#define BIT_INT_STATUS_FSYNC 0x40 +#define BIT_INT_STATUS_ST_DONE 0x80 + +/* Bank0 REG_INT_STATUS2 */ +#define BIT_INT_STATUS_WOM_Z 0x01 +#define BIT_INT_STATUS_WOM_Y 0x02 +#define BIT_INT_STATUS_WOM_X 0x04 +#define BIT_INT_STATUS_WOM_XYZ (BIT_INT_STATUS_WOM_X | \ + BIT_INT_STATUS_WOM_Y | BIT_INT_STATUS_WOM_Z) +#define BIT_INT_STATUS_SMD 0x08 + +/* Bank 0 REG_INT_STATUS3 */ +#define BIT_INT_STATUS_LOWG_DET 0x02 +#define BIT_INT_STATUS_FF_DET 0x04 +#define BIT_INT_STATUS_TILT_DET 0x08 +#define BIT_INT_STATUS_STEP_CNT_OVFL 0x10 +#define BIT_INT_STATUS_STEP_DET 0x20 + +/* Bank0 REG_WOM_CONFIG */ +#define BIT_WOM_EN_OFF 0x00 +#define BIT_WOM_EN_ON 0x01 +#define BIT_WOM_MODE_INITIAL 0x00 +#define BIT_WOM_MODE_PREV 0x02 +#define BIT_WOM_INT_MODE_OR 0x00 +#define BIT_WOM_INT_MODE_AND 0x04 +#define BIT_WOM_INT_DUR_LEGACY 0x00 +#define BIT_WOM_INT_DUR_2ND 0x08 +#define BIT_WOM_INT_DUR_3RD 0x10 +#define BIT_WOM_INT_DUR_4TH 0x18 + +/* Bank0 REG_APEX_CONFIG0 */ +#define BIT_DMP_SRAM_RESET_APEX 0x01 +#define BIT_DMP_INIT_EN 0x04 +#define BIT_DMP_POWER_SAVE_EN 0x08 + +/* Bank0 REG_APEX_CONFIG1 */ +#define BIT_DMP_ODR_25HZ 0x00 +#define BIT_DMP_ODR_50HZ 0x02 +#define BIT_DMP_ODR_100HZ 0x03 +#define BIT_DMP_PEDO_EN 0x08 +#define BIT_DMP_TILT_EN 0x10 +#define BIT_DMP_FF_EN 0x20 +#define BIT_DMP_SMD_EN 0x40 + +/* REG_OTP_CONFIG_MREG_TOP1 */ +#define BIT_OTP_COPY_NORMAL 0x04 +#define BIT_OTP_COPY_ST_DATA 0x0C +#define OTP_COPY_MODE_MASK 0x0C + +/* REG_INT_SOURCE6_MREG_TOP1 */ +#define BIT_INT_TLT_DET_INT1_EN 0x08 +#define BIT_INT_STEP_CNT_OVFL_INT1_EN 0x10 +#define BIT_INT_STEP_DET_INT1_EN 0x20 +#define BIT_INT_LOWG_INT1_EN 0x40 +#define BIT_INT_FF_INT1_EN 0x80 + +/* REG_TMST_CONFIG1_MREG_TOP1 */ +#define BIT_TMST_EN 0x01 +#define BIT_TMST_FSYNC_EN 0x02 +#define BIT_TMST_DELTA_EN 0x04 +#define BIT_TMST_RESOL 0x08 +#define BIT_TMST_ON_SREG_EN 0x10 +#define BIT_ODR_EN_WITHOUT_SENSOR 0x40 + +/* REG_FIFO_CONFIG5_MREG_TOP1 */ +#define BIT_FIFO_ACCEL_EN 0x01 +#define BIT_FIFO_GYRO_EN 0x02 +#define BIT_FIFO_TMST_FSYNC_EN 0x04 +#define BIT_FIFO_HIRES_EN 0x08 +#define BIT_RESUME_PARTIAL_RD 0x10 +#define BIT_WM_GT_TH 0x20 + +/* REG_SELFTEST_MREG_TOP1 */ +#define BIT_EN_AX_ST 0x01 +#define BIT_EN_AY_ST 0x02 +#define BIT_EN_AZ_ST 0x04 +#define BIT_EN_GX_ST 0x08 +#define BIT_EN_GY_ST 0x10 +#define BIT_EN_GZ_ST 0x20 +#define BIT_ACCEL_ST_EN 0x40 +#define BIT_GYRO_ST_EN 0x80 + +/* REG_ST_CONFIG_MREG_TOP1 */ +#define BIT_PD_ACCEL_CP45_ST_REG 0x80 +#define SHIFT_GYRO_ST_LIM 0 +#define SHIFT_ACCEL_ST_LIM 3 +#define SHIFT_ST_NUM_SAMPLE 6 + +/* REG_ST_STATUS1_MREG_TOP1 */ +#define BIT_DMP_AX_ST_PASS 0x02 +#define BIT_DMP_AY_ST_PASS 0x04 +#define BIT_DMP_AZ_ST_PASS 0x08 +#define BIT_DMP_ACCEL_ST_DONE 0x10 +#define BIT_DMP_ACCEL_ST_PASS 0x20 + +/* REG_ST_STATUS2_MREG_TOP1 */ +#define BIT_DMP_GX_ST_PASS 0x02 +#define BIT_DMP_GY_ST_PASS 0x04 +#define BIT_DMP_GZ_ST_PASS 0x08 +#define BIT_DMP_GYRO_ST_DONE 0x10 +#define BIT_DMP_GYRO_ST_PASS 0x20 +#define BIT_DMP_ST_INCOMPLETE 0x40 + +/* REG_OTP_CTRL7_MREG_OTP */ +#define BIT_OTP_RELOAD 0x08 +#define BIT_OTP_PWR_DOWN 0x02 + + +/* fifo data packet header */ +#define BIT_FIFO_HEAD_MSG 0x80 +#define BIT_FIFO_HEAD_ACCEL 0x40 +#define BIT_FIFO_HEAD_GYRO 0x20 +#define BIT_FIFO_HEAD_20 0x10 +#define BIT_FIFO_HEAD_TMSP_ODR 0x08 +#define BIT_FIFO_HEAD_TMSP_NO_ODR 0x04 +#define BIT_FIFO_HEAD_TMSP_FSYNC 0x0C +#define BIT_FIFO_HEAD_ODR_ACCEL 0x02 +#define BIT_FIFO_HEAD_ODR_GYRO 0x01 + +/* data definitions */ +#define FIFO_PACKET_BYTE_SINGLE 8 +#define FIFO_PACKET_BYTE_6X 16 +#define FIFO_PACKET_BYTE_HIRES 20 +#define FIFO_COUNT_BYTE 2 + +/* sensor startup time */ +#define INV_ICM43600_GYRO_START_TIME 100 +#define INV_ICM43600_ACCEL_START_TIME 100 + +/* sensor stop time */ +#define INV_ICM43600_GYRO_STOP_TIME 20 + +/* M-reg access wait tile */ +#define INV_ICM42607_MCLK_WAIT_US 20 +#define INV_ICM42607_BLK_SEL_WAIT_US 10 +#define INV_ICM42607_MADDR_WAIT_US 10 +#define INV_ICM42607_M_RW_WAIT_US 10 + +/* temperature sensor */ +#define TEMP_SCALE 100 /* scale by 100 */ +#define TEMP_LSB_PER_DEG 2 /* 2LSB=1degC */ +#define TEMP_OFFSET 25 /* 25 degC */ + +/* + * INT configurations + * Polarity: 0 -> Active Low, 1 -> Active High + * Drive circuit: 0 -> Open Drain, 1 -> Push-Pull + * Mode: 0 -> Pulse, 1 -> Latch + */ +#define INT_POLARITY 1 +#define INT_DRIVE_CIRCUIT 1 +#define INT_MODE 0 + +#define ICM42607_DEVICE_ID 0x61 +#define ICM4260X_PRECISION 16 +#define ICM42607_ADDR 0x68 + +#endif diff --git a/include/linux/sensor-dev.h b/include/linux/sensor-dev.h index 81d3aa1ea38b..a29d512ec0d1 100644 --- a/include/linux/sensor-dev.h +++ b/include/linux/sensor-dev.h @@ -70,6 +70,7 @@ enum sensor_id { ACCEL_ID_DA215S, ACCEL_ID_DA228E, ACCEL_ID_IAM20680, + ACCEL_ID_ICM4260X, COMPASS_ID_ALL, COMPASS_ID_AK8975, COMPASS_ID_AK8963, @@ -97,6 +98,7 @@ enum sensor_id { GYRO_ID_LSM330, GYRO_ID_ICM2060X, GYRO_ID_IAM20680, + GYRO_ID_ICM4260X, LIGHT_ID_ALL, LIGHT_ID_CM3217, LIGHT_ID_CM3218,