Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc574a2d authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "input: sensors: add interrupt mode support for MPU6050"

parents 96c21c34 eb6fee87
Loading
Loading
Loading
Loading
+267 −58
Original line number Diff line number Diff line
@@ -47,11 +47,12 @@
#define MPU6050_GYRO_MIN_VALUE	-32768
#define MPU6050_GYRO_MAX_VALUE	32767

#define MPU6050_ACCEL_MIN_POLL_INTERVAL_MS	1
/* Limit mininum delay to 10ms as we do not need higher rate so far */
#define MPU6050_ACCEL_MIN_POLL_INTERVAL_MS	10
#define MPU6050_ACCEL_MAX_POLL_INTERVAL_MS	5000
#define MPU6050_ACCEL_DEFAULT_POLL_INTERVAL_MS	200

#define MPU6050_GYRO_MIN_POLL_INTERVAL_MS	1
#define MPU6050_GYRO_MIN_POLL_INTERVAL_MS	10
#define MPU6050_GYRO_MAX_POLL_INTERVAL_MS	5000
#define MPU6050_GYRO_DEFAULT_POLL_INTERVAL_MS	200

@@ -62,6 +63,8 @@
#define MPU6050_ACCEL_SCALE_SHIFT_2G	4
#define MPU6050_GYRO_SCALE_SHIFT_FS0	3

#define MPU6050_RESET_SLEEP_US	10

#define MPU6050_DEV_NAME_ACCEL	"MPU6050-accel"
#define MPU6050_DEV_NAME_GYRO	"gyroscope"

@@ -246,6 +249,8 @@ mpu6050_place_name2num[MPU6050_AXIS_REMAP_TAB_SZ] = {
/* Function declarations */
static void mpu6050_pinctrl_state(struct mpu6050_sensor *sensor,
			bool active);
static int mpu6050_set_drdy_int(struct mpu6050_sensor *sensor, bool on);


static int mpu6050_power_ctl(struct mpu6050_sensor *sensor, bool on)
{
@@ -551,18 +556,30 @@ static irqreturn_t mpu6050_interrupt_thread(int irq, void *data)
{
	struct mpu6050_sensor *sensor = data;

	if (sensor->cfg.accel_enable) {
		mpu6050_read_accel_data(sensor, &sensor->axis);
	mpu6050_read_gyro_data(sensor, &sensor->axis);

	input_report_abs(sensor->accel_dev, ABS_X, sensor->axis.x);
	input_report_abs(sensor->accel_dev, ABS_Y, sensor->axis.y);
	input_report_abs(sensor->accel_dev, ABS_Z, sensor->axis.z);
		mpu6050_remap_accel_data(&sensor->axis, sensor->pdata->place);
		input_report_abs(sensor->accel_dev, ABS_X,
			(sensor->axis.x >> MPU6050_ACCEL_SCALE_SHIFT_2G));
		input_report_abs(sensor->accel_dev, ABS_Y,
			(sensor->axis.y >> MPU6050_ACCEL_SCALE_SHIFT_2G));
		input_report_abs(sensor->accel_dev, ABS_Z,
			(sensor->axis.z >> MPU6050_ACCEL_SCALE_SHIFT_2G));
		input_sync(sensor->accel_dev);
	}

	if (sensor->cfg.gyro_enable) {
		mpu6050_read_gyro_data(sensor, &sensor->axis);
		mpu6050_remap_gyro_data(&sensor->axis, sensor->pdata->place);

	input_report_abs(sensor->gyro_dev, ABS_RX, sensor->axis.rx);
	input_report_abs(sensor->gyro_dev, ABS_RY, sensor->axis.ry);
	input_report_abs(sensor->gyro_dev, ABS_RZ, sensor->axis.rz);
		input_report_abs(sensor->gyro_dev, ABS_RX,
			(sensor->axis.rx >> MPU6050_GYRO_SCALE_SHIFT_FS0));
		input_report_abs(sensor->gyro_dev, ABS_RY,
			(sensor->axis.ry >> MPU6050_GYRO_SCALE_SHIFT_FS0));
		input_report_abs(sensor->gyro_dev, ABS_RZ,
			(sensor->axis.rz >> MPU6050_GYRO_SCALE_SHIFT_FS0));
		input_sync(sensor->gyro_dev);
	}

	return IRQ_HANDLED;
}
@@ -788,7 +805,7 @@ static int mpu6050_gyro_enable(struct mpu6050_sensor *sensor, bool on)
				sensor->reg.pwr_mgmt_1);
	if (ret < 0) {
		dev_err(&sensor->client->dev,
			"Fail to get sensor power state ret=%d\n", ret);
			"Fail to get sensor power state, ret=%d\n", ret);
		return ret;
	}

@@ -805,11 +822,37 @@ static int mpu6050_gyro_enable(struct mpu6050_sensor *sensor, bool on)
				sensor->reg.pwr_mgmt_1, data);
		if (ret < 0) {
			dev_err(&sensor->client->dev,
				"Fail to set sensor power state ret=%d\n", ret);
				"Fail to set sensor power state, ret=%d\n",
				ret);
			return ret;
		}

		if (!sensor->cfg.int_enabled) {
			ret = mpu6050_set_drdy_int(sensor, true);
			if (ret < 0) {
				dev_err(&sensor->client->dev,
					"Fail to enable interrupt mode for gyro, ret=%d\n",
					ret);
				return ret;
			}
			enable_irq(sensor->client->irq);
			sensor->cfg.int_enabled = true;
		}

		sensor->cfg.enable = 1;
	} else {
		if (sensor->cfg.int_enabled && !sensor->cfg.accel_enable) {
			ret = mpu6050_set_drdy_int(sensor, false);
			if (ret < 0) {
				dev_err(&sensor->client->dev,
					"Fail to disable interrupt mode for gyro, ret=%d\n",
					ret);
				return ret;
			}
			disable_irq(sensor->client->irq);
			sensor->cfg.int_enabled = false;
		}

		ret = mpu6050_switch_engine(sensor, false,
			BIT_PWR_GYRO_STBY_MASK);
		if (ret)
@@ -821,7 +864,7 @@ static int mpu6050_gyro_enable(struct mpu6050_sensor *sensor, bool on)
					sensor->reg.pwr_mgmt_1, data);
			if (ret < 0) {
				dev_err(&sensor->client->dev,
					"Fail to set sensor power state ret=%d\n",
					"Fail to set sensor power state, ret=%d\n",
					ret);
				return ret;
			}
@@ -840,11 +883,25 @@ static int mpu6050_restore_context(struct mpu6050_sensor *sensor)
	struct mpu_reg_map *reg;
	struct i2c_client *client;
	int ret;
	u8 data;
	u8 data, pwr_ctrl;

	client = sensor->client;
	reg = &sensor->reg;

	/* Save power state and wakeup device from sleep */
	ret = i2c_smbus_read_byte_data(client, reg->pwr_mgmt_1);
	if (ret < 0) {
		dev_err(&client->dev, "read power ctrl failed.\n");
		goto exit;
	}
	pwr_ctrl = (u8)ret;

	ret = i2c_smbus_write_byte_data(client, reg->pwr_mgmt_1,
		BIT_WAKEUP_AFTER_RESET);
	if (ret < 0) {
		dev_err(&client->dev, "wakeup sensor failed.\n");
		goto exit;
	}
	ret = i2c_smbus_write_byte_data(client, reg->gyro_config,
			sensor->cfg.fsr << GYRO_CONFIG_FSR_SHIFT);
	if (ret < 0) {
@@ -898,9 +955,23 @@ static int mpu6050_restore_context(struct mpu6050_sensor *sensor)
	}

	ret = i2c_smbus_write_byte_data(client, reg->sample_rate_div,
			ODR_DLPF_ENA / INIT_FIFO_RATE - 1);
			sensor->cfg.rate_div);
	if (ret < 0) {
		dev_err(&client->dev, "set lpa_freq failed.\n");
		dev_err(&client->dev, "set sample_rate_div failed.\n");
		goto exit;
	}

	ret = i2c_smbus_write_byte_data(client, reg->int_pin_cfg,
			sensor->cfg.int_pin_cfg);
	if (ret < 0) {
		dev_err(&client->dev, "set int_pin_cfg failed.\n");
		goto exit;
	}

	ret = i2c_smbus_write_byte_data(client, reg->pwr_mgmt_1,
		pwr_ctrl);
	if (ret < 0) {
		dev_err(&client->dev, "Write saved power state failed.\n");
		goto exit;
	}

@@ -941,7 +1012,7 @@ static void mpu6050_reset_chip(struct mpu6050_sensor *sensor)
			break;
		}

		msleep(MPU6050_RESET_WAIT_MS);
		usleep(MPU6050_RESET_SLEEP_US);
	}

exit:
@@ -980,8 +1051,6 @@ static int mpu6050_gyro_set_enable(struct mpu6050_sensor *sensor, bool enable)
		if (sensor->use_poll)
			schedule_delayed_work(&sensor->gyro_poll_work,
				msecs_to_jiffies(sensor->gyro_poll_ms));
		else
			enable_irq(sensor->client->irq);
	} else {
		ret = mpu6050_gyro_enable(sensor, false);
		if (ret) {
@@ -992,8 +1061,6 @@ static int mpu6050_gyro_set_enable(struct mpu6050_sensor *sensor, bool enable)
		}
		if (sensor->use_poll)
			cancel_delayed_work_sync(&sensor->gyro_poll_work);
		else
			disable_irq(sensor->client->irq);

	}

@@ -1002,9 +1069,109 @@ exit:
	return ret;
}

/*
  * Configure the sensor interrupt register that allow sensor to
  * issue interrupt for each new sensor event.
  */
static int mpu6050_set_drdy_int(struct mpu6050_sensor *sensor, bool on)
{
	int ret;
	u8 data;

	if (sensor->cfg.is_asleep)
		return -EINVAL;

	if (on) {
		ret = i2c_smbus_read_byte_data(sensor->client,
					sensor->reg.int_enable);
		if (ret < 0) {
			dev_err(&sensor->client->dev,
				"Fail read interrupt mode. ret=%d\n", ret);
			return ret;
		}

		data = (u8)ret;
		data |= BIT_DATA_RDY_EN;
		ret = i2c_smbus_write_byte_data(sensor->client,
				sensor->reg.int_enable, data);
		if (ret < 0) {
			dev_err(&sensor->client->dev,
				"Fail to set interrupt. ret=%d\n", ret);
			return ret;
		}
	} else {
		ret = i2c_smbus_read_byte_data(sensor->client,
					sensor->reg.int_enable);
		if (ret < 0) {
			dev_err(&sensor->client->dev,
				"Fail read interrupt mode. ret=%d\n", ret);
			return ret;
		}

		data = (u8)ret;
		data &= ~BIT_DATA_RDY_EN;
		ret = i2c_smbus_write_byte_data(sensor->client,
				sensor->reg.int_enable, data);
		if (ret < 0) {
			dev_err(&sensor->client->dev,
				"Fail to set interrupt. ret=%d\n", ret);
			return ret;
		}
	}
	return 0;
}

/* Update sensor sample rate divider upon accel and gyro polling rate. */
static int mpu6050_config_sample_rate(struct mpu6050_sensor *sensor)
{
	int ret;
	u32 delay_ms;
	u8 div;

	if (sensor->cfg.is_asleep)
		return -EINVAL;

	if (sensor->accel_poll_ms <= sensor->gyro_poll_ms)
		delay_ms = sensor->accel_poll_ms;
	else
		delay_ms = sensor->gyro_poll_ms;

	/* Sample_rate = internal_ODR/(1+SMPLRT_DIV) */
	if ((sensor->cfg.lpf != MPU_DLPF_256HZ_NOLPF2) &&
		(sensor->cfg.lpf != MPU_DLPF_RESERVED)) {
		if (delay_ms > DELAY_MS_MAX_DLPF)
			delay_ms = DELAY_MS_MAX_DLPF;
		if (delay_ms < DELAY_MS_MIN_DLPF)
			delay_ms = DELAY_MS_MIN_DLPF;

		div = (u8)(((ODR_DLPF_ENA * delay_ms) / MSEC_PER_SEC) - 1);
	} else {
		if (delay_ms > DELAY_MS_MAX_NODLPF)
			delay_ms = DELAY_MS_MAX_NODLPF;
		if (delay_ms < DELAY_MS_MIN_NODLPF)
			delay_ms = DELAY_MS_MIN_NODLPF;
		div = (u8)(((ODR_DLPF_DIS * delay_ms) / MSEC_PER_SEC) - 1);
	}

	ret = i2c_smbus_write_byte_data(sensor->client,
		sensor->reg.sample_rate_div, div);
	if (ret < 0) {
		dev_err(&sensor->client->dev,
				"Update sample rate divdier fail, ret=%d\n",
				ret);
		return ret;
	}

	sensor->cfg.rate_div = div;

	return 0;
}

static int mpu6050_gyro_set_poll_delay(struct mpu6050_sensor *sensor,
					unsigned long delay)
{
	int ret;

	mutex_lock(&sensor->op_lock);
	if (delay < MPU6050_GYRO_MIN_POLL_INTERVAL_MS)
		delay = MPU6050_GYRO_MIN_POLL_INTERVAL_MS;
@@ -1016,6 +1183,11 @@ static int mpu6050_gyro_set_poll_delay(struct mpu6050_sensor *sensor,
		cancel_delayed_work_sync(&sensor->gyro_poll_work);
		schedule_delayed_work(&sensor->gyro_poll_work,
				msecs_to_jiffies(sensor->gyro_poll_ms));
	} else {
		ret = mpu6050_config_sample_rate(sensor);
		if (ret < 0)
			dev_err(&sensor->client->dev,
				"Unable to set polling delay for gyro!\n");
	}
	mutex_unlock(&sensor->op_lock);
	return 0;
@@ -1150,7 +1322,7 @@ static int mpu6050_accel_enable(struct mpu6050_sensor *sensor, bool on)
				sensor->reg.pwr_mgmt_1);
	if (ret < 0) {
		dev_err(&sensor->client->dev,
			"Fail to get sensor power state ret=%d\n", ret);
			"Fail to get sensor power state, ret=%d\n", ret);
		return ret;
	}

@@ -1167,11 +1339,37 @@ static int mpu6050_accel_enable(struct mpu6050_sensor *sensor, bool on)
				sensor->reg.pwr_mgmt_1, data);
		if (ret < 0) {
			dev_err(&sensor->client->dev,
				"Fail to set sensor power state ret=%d\n", ret);
				"Fail to set sensor power state, ret=%d\n",
				ret);
			return ret;
		}

		if (!sensor->cfg.int_enabled) {
			ret = mpu6050_set_drdy_int(sensor, true);
			if (ret < 0) {
				dev_err(&sensor->client->dev,
					"Fail to enable interrupt mode for accel, ret=%d\n",
					ret);
				return ret;
			}
			enable_irq(sensor->client->irq);
			sensor->cfg.int_enabled = true;
		}

		sensor->cfg.enable = 1;
	} else {
		if (sensor->cfg.int_enabled && !sensor->cfg.gyro_enable) {
			ret = mpu6050_set_drdy_int(sensor, false);
			if (ret < 0) {
				dev_err(&sensor->client->dev,
					"Fail to disable interrupt mode for accel, ret=%d\n",
					ret);
				return ret;
			}
			disable_irq(sensor->client->irq);
			sensor->cfg.int_enabled = false;
		}

		ret = mpu6050_switch_engine(sensor, false,
			BIT_PWR_ACCEL_STBY_MASK);
		if (ret)
@@ -1184,7 +1382,7 @@ static int mpu6050_accel_enable(struct mpu6050_sensor *sensor, bool on)
					sensor->reg.pwr_mgmt_1, data);
			if (ret < 0) {
				dev_err(&sensor->client->dev,
					"Fail to set sensor power state ret=%d\n",
					"Fail to set sensor power state for accel, ret=%d\n",
					ret);
				return ret;
			}
@@ -1227,13 +1425,9 @@ static int mpu6050_accel_set_enable(struct mpu6050_sensor *sensor, bool enable)
		if (sensor->use_poll)
			schedule_delayed_work(&sensor->accel_poll_work,
				msecs_to_jiffies(sensor->accel_poll_ms));
		else
			enable_irq(sensor->client->irq);
	} else {
		if (sensor->use_poll)
			cancel_delayed_work_sync(&sensor->accel_poll_work);
		else
			disable_irq(sensor->client->irq);

		ret = mpu6050_accel_enable(sensor, false);
		if (ret) {
@@ -1253,7 +1447,6 @@ exit:
static int mpu6050_accel_set_poll_delay(struct mpu6050_sensor *sensor,
					unsigned long delay)
{
	u8 divider;
	int ret;

	mutex_lock(&sensor->op_lock);
@@ -1262,18 +1455,17 @@ static int mpu6050_accel_set_poll_delay(struct mpu6050_sensor *sensor,
	if (delay > MPU6050_ACCEL_MAX_POLL_INTERVAL_MS)
		delay = MPU6050_ACCEL_MAX_POLL_INTERVAL_MS;

	if (sensor->accel_poll_ms != delay) {
		/* Output frequency divider. and set timer delay */
		divider = ODR_DLPF_ENA / INIT_FIFO_RATE - 1;
		ret = i2c_smbus_write_byte_data(sensor->client,
				sensor->reg.sample_rate_div, divider);
		if (ret == 0)
	sensor->accel_poll_ms = delay;
	}

	if (sensor->use_poll) {
		cancel_delayed_work_sync(&sensor->accel_poll_work);
		schedule_delayed_work(&sensor->accel_poll_work,
				msecs_to_jiffies(sensor->accel_poll_ms));
	} else {
		ret = mpu6050_config_sample_rate(sensor);
		if (ret < 0)
			dev_err(&sensor->client->dev,
				"Unable to set polling delay for accel!\n");
	}
	mutex_unlock(&sensor->op_lock);
	return 0;
@@ -1495,6 +1687,7 @@ static void setup_mpu6050_reg(struct mpu_reg_map *reg)
	reg->raw_gyro		= REG_RAW_GYRO;
	reg->raw_accel		= REG_RAW_ACCEL;
	reg->temperature	= REG_TEMPERATURE;
	reg->int_pin_cfg	= REG_INT_PIN_CFG;
	reg->int_enable		= REG_INT_ENABLE;
	reg->int_status		= REG_INT_STATUS;
	reg->pwr_mgmt_1		= REG_PWR_MGMT_1;
@@ -1565,6 +1758,7 @@ static int mpu6050_init_config(struct mpu6050_sensor *sensor)
	struct mpu_reg_map *reg;
	struct i2c_client *client;
	s32 ret;
	u8 data;

	if (sensor->cfg.is_asleep)
		return -EINVAL;
@@ -1572,24 +1766,15 @@ static int mpu6050_init_config(struct mpu6050_sensor *sensor)
	reg = &sensor->reg;
	client = sensor->client;

	/* reset device*/
	ret = i2c_smbus_write_byte_data(client,
		reg->pwr_mgmt_1, BIT_H_RESET);
	mpu6050_reset_chip(sensor);

	memset(&sensor->cfg, 0, sizeof(struct mpu_chip_config));

	/* Wake up from sleep */
	ret = i2c_smbus_write_byte_data(client, reg->pwr_mgmt_1,
		BIT_WAKEUP_AFTER_RESET);
	if (ret < 0)
		return ret;
	do {
		usleep(10);
		/* check reset complete */
		ret = i2c_smbus_read_byte_data(client,
			reg->pwr_mgmt_1);
		if (ret < 0) {
			dev_err(&client->dev,
				"Failed to read reset status ret =%d\n",
				ret);
			return ret;
		}
	} while (ret & BIT_H_RESET);
	memset(&sensor->cfg, 0, sizeof(struct mpu_chip_config));

	/* Gyro full scale range configure */
	ret = i2c_smbus_write_byte_data(client, reg->gyro_config,
@@ -1603,11 +1788,11 @@ static int mpu6050_init_config(struct mpu6050_sensor *sensor)
		return ret;
	sensor->cfg.lpf = MPU_DLPF_42HZ;

	ret = i2c_smbus_write_byte_data(client, reg->sample_rate_div,
					ODR_DLPF_ENA / INIT_FIFO_RATE - 1);
	data = (u8)(ODR_DLPF_ENA / INIT_FIFO_RATE - 1);
	ret = i2c_smbus_write_byte_data(client, reg->sample_rate_div, data);
	if (ret < 0)
		return ret;
	sensor->cfg.fifo_rate = INIT_FIFO_RATE;
	sensor->cfg.rate_div = data;

	ret = i2c_smbus_write_byte_data(client, reg->accel_config,
		(ACCEL_FS_02G << ACCL_CONFIG_FSR_SHIFT));
@@ -1615,6 +1800,29 @@ static int mpu6050_init_config(struct mpu6050_sensor *sensor)
		return ret;
	sensor->cfg.accel_fs = ACCEL_FS_02G;

	if ((sensor->pdata->int_flags & IRQF_TRIGGER_FALLING) ||
		(sensor->pdata->int_flags & IRQF_TRIGGER_LOW))
		data = BIT_INT_CFG_DEFAULT | BIT_INT_ACTIVE_LOW;
	else
		data = BIT_INT_CFG_DEFAULT;
	ret = i2c_smbus_write_byte_data(client, reg->int_pin_cfg, data);
	if (ret < 0)
		return ret;
	sensor->cfg.int_pin_cfg = data;

	/* Put sensor into sleep mode */
	ret = i2c_smbus_read_byte_data(client,
		sensor->reg.pwr_mgmt_1);
	if (ret < 0)
		return ret;

	data = (u8)ret;
	data |=  BIT_SLEEP;
	ret = i2c_smbus_write_byte_data(client,
		sensor->reg.pwr_mgmt_1, data);
	if (ret < 0)
		return ret;

	sensor->cfg.gyro_enable = 0;
	sensor->cfg.gyro_fifo_enable = 0;
	sensor->cfg.accel_enable = 0;
@@ -1926,6 +2134,7 @@ static int mpu6050_probe(struct i2c_client *client,
			client->irq = 0;
			goto err_free_gpio;
		}
		/* Disable interrupt until event is enabled */
		disable_irq(client->irq);
	} else {
		sensor->use_poll = 1;
+38 −11
Original line number Diff line number Diff line
@@ -32,6 +32,14 @@
#define BIT_ACCEL_OUT		0x08
#define BITS_GYRO_OUT		0x70

#define REG_INT_PIN_CFG		0x37
#define BIT_INT_ACTIVE_LOW	0x80
#define BIT_INT_OPEN_DRAIN	0x40
#define BIT_INT_LATCH_EN	0x20
#define BIT_INT_RD_CLR		0x10
#define BIT_I2C_BYPASS_EN	0x02
#define BIT_INT_CFG_DEFAULT	(BIT_INT_LATCH_EN | BIT_INT_RD_CLR)

#define REG_INT_ENABLE		0x38
#define BIT_DATA_RDY_EN		0x01
#define BIT_DMP_INT_EN		0x02
@@ -40,10 +48,12 @@
#define BIT_6500_WOM_EN		0x40

#define REG_DMP_INT_STATUS	0x39

#define REG_INT_STATUS		0x3A
#define BIT_MOT_INT		0x40
#define BIT_DATA_RDY_INT	0x01
#define BIT_DMP_INT_INT		0x02
#define BIT_ZMOT_INT		0x20
#define BIT_MOT_INT		0x40
#define BIT_6500_WOM_INT	0x40

#define REG_RAW_ACCEL		0x3B
#define REG_TEMPERATURE		0x41
@@ -62,8 +72,9 @@
#define BIT_H_RESET		0x80
#define BIT_SLEEP		0x40
#define BIT_CYCLE		0x20
#define BIT_CLK_MASK		0x7
#define BIT_CLK_MASK		0x07
#define BIT_RESET_ALL		0xCF
#define BIT_WAKEUP_AFTER_RESET	0x00

#define REG_PWR_MGMT_2		0x6C
#define BIT_PWR_ACCEL_STBY_MASK	0x38
@@ -74,9 +85,20 @@
#define REG_FIFO_R_W		0x74
#define REG_WHOAMI		0x75

#define SAMPLE_DIV_MAX		0xFF
#define ODR_DLPF_DIS		8000
#define ODR_DLPF_ENA		1000

/* Min delay = MSEC_PER_SEC/ODR_DLPF_ENA */
/* Max delay = MSEC_PER_SEC/(ODR_DLPF_ENA/SAMPLE_DIV_MAX+1) */
#define DELAY_MS_MIN_DLPF	1
#define DELAY_MS_MAX_DLPF	256

/* Min delay = MSEC_PER_SEC/ODR_DLPF_DIS and round up to 1*/
/* Max delay = MSEC_PER_SEC/(ODR_DLPF_DIS/SAMPLE_DIV_MAX+1) */
#define DELAY_MS_MIN_NODLPF	1
#define DELAY_MS_MAX_NODLPF	32

/* device bootup time in millisecond */
#define POWER_UP_TIME_MS	100
/* delay to wait gyro engine stable in millisecond */
@@ -149,9 +171,10 @@ enum inv_devices {
 *  @accel_config:	accel config register
 *  @fifo_count_h:	Upper byte of FIFO count.
 *  @fifo_r_w:	FIFO register.
 *  @raw_gyro		Address of first gyro register.
 *  @raw_accl		Address of first accel register.
 *  @temperature	temperature register
 *  @raw_gyro:	Address of first gyro register.
 *  @raw_accl:	Address of first accel register.
 *  @temperature:	temperature register.
 *  @int_pin_cfg:	Interrupt pin and I2C bypass configuration.
 *  @int_enable:	Interrupt enable register.
 *  @int_status:	Interrupt flags.
 *  @pwr_mgmt_1:	Controls chip's power state and clock source.
@@ -169,6 +192,7 @@ struct mpu_reg_map {
	u8 raw_gyro;
	u8 raw_accel;
	u8 temperature;
	u8 int_pin_cfg;
	u8 int_enable;
	u8 int_status;
	u8 pwr_mgmt_1;
@@ -189,8 +213,9 @@ struct mpu_reg_map {
 *  @lpa_mod:		low power mode.
 *  @tap_on:		tap on/off.
 *  @flick_int_on:		flick interrupt on/off.
 *  @int_enabled:		interrupt is enabled.
 *  @lpa_freq:		low power frequency
 *  @fifo_rate:		FIFO update rate.
 *  @rate_div:		Sampling rate divider.
 */
struct mpu_chip_config {
	u32 fsr:2;
@@ -205,8 +230,10 @@ struct mpu_chip_config {
	u32 lpa_mode:1;
	u32 tap_on:1;
	u32 flick_int_on:1;
	u32 int_enabled:1;
	u8 int_pin_cfg;
	u16 lpa_freq;
	u16 fifo_rate;
	u16 rate_div;
};