예제 #1
0
int inv_switch_3050_gyro_engine(struct inv_mpu_iio_s *st, bool en)
{
	struct inv_reg_map_s *reg;
	u8 data, p;
	int result;
	reg = &st->reg;
	if (en) {
		data = INV_CLK_PLL;
		p = (BITS_3050_POWER1 | data);
		result = inv_i2c_single_write(st, reg->pwr_mgmt_1, p);
		if (result)
			return result;
		p = (BITS_3050_POWER2 | data);
		result = inv_i2c_single_write(st, reg->pwr_mgmt_1, p);
		if (result)
			return result;
		p = data;
		result = inv_i2c_single_write(st, reg->pwr_mgmt_1, p);
		msleep(SENSOR_UP_TIME);
	} else {
		p = BITS_3050_GYRO_STANDBY;
		result = inv_i2c_single_write(st, reg->pwr_mgmt_1, p);
	}

	return result;
}
예제 #2
0
int set_3050_bypass(struct inv_mpu_iio_s *st, bool enable)
{
	struct inv_reg_map_s *reg;
	int result;
	u8 b;

	reg = &st->reg;
	result = inv_i2c_read(st, reg->user_ctrl, 1, &b);
	if (result)
		return result;
	if (((b & BIT_3050_AUX_IF_EN) == 0) && enable)
		return 0;
	if ((b & BIT_3050_AUX_IF_EN) && (enable == 0))
		return 0;
	b &= ~BIT_3050_AUX_IF_EN;
	if (!enable) {
		b |= BIT_3050_AUX_IF_EN;
		result = inv_i2c_single_write(st, reg->user_ctrl, b);
		return result;
	} else {
		/* Coming out of I2C is tricky due to several erratta.  Do not
		* modify this algorithm
		*/
		/*
		* 1) wait for the right time and send the command to change
		* the aux i2c slave address to an invalid address that will
		* get nack'ed
		*
		* 0x00 is broadcast.  0x7F is unlikely to be used by any aux.
		*/
		result = inv_i2c_single_write(st, REG_3050_SLAVE_ADDR,
						MPU3050_BOGUS_ADDR);
		if (result)
			return result;
		/*
		* 2) wait enough time for a nack to occur, then go into
		*    bypass mode:
		*/
		usleep_range(MPU3050_NACK_MIN_TIME, MPU3050_NACK_MAX_TIME);
		result = inv_i2c_single_write(st, reg->user_ctrl, b);
		if (result)
			return result;
		/*
		* 3) wait for up to one MPU cycle then restore the slave
		*    address
		*/
		msleep(MPU3050_ONE_MPU_TIME);

		result = inv_i2c_single_write(st, REG_3050_SLAVE_ADDR,
			st->plat_data.secondary_i2c_addr);
		if (result)
			return result;
		result = inv_i2c_single_write(st, reg->user_ctrl, b);
		if (result)
			return result;
		usleep_range(MPU3050_NACK_MIN_TIME, MPU3050_NACK_MAX_TIME);
	}
	return 0;
}
/**
 *  inv_init_config_mpu3050() - Initialize hardware, disable FIFO.
 *  @st:	Device driver instance.
 *  Initial configuration:
 *  FSR: +/- 2000DPS
 *  DLPF: 42Hz
 *  FIFO rate: 50Hz
 *  Clock source: Gyro PLL
 */
int inv_init_config_mpu3050(struct iio_dev *indio_dev)
{
	struct inv_reg_map_s *reg;
	int result;
	u8 data;
	struct inv_mpu_iio_s *st = iio_priv(indio_dev);
	if (st->chip_config.is_asleep)
		return -EPERM;
	/*reading AUX VDDIO register */
	result = inv_i2c_read(st, REG_3050_AUX_VDDIO, 1, &data);
	if (result)
		return result;
	data &= ~BIT_3050_VDDIO;
	if (st->plat_data.level_shifter)
		data |= BIT_3050_VDDIO;
	result = inv_i2c_single_write(st, REG_3050_AUX_VDDIO, data);
	if (result)
		return result;

	reg = &st->reg;
	result = set_inv_enable(indio_dev, false);
	if (result)
		return result;
	/*2000dps full scale range*/
	result = inv_i2c_single_write(st, reg->lpf,
				(INV_FSR_2000DPS << GYRO_CONFIG_FSR_SHIFT)
				| INV_FILTER_42HZ);
	if (result)
		return result;
	st->chip_config.fsr = INV_FSR_2000DPS;
	st->chip_config.lpf = INV_FILTER_42HZ;
	result = inv_i2c_single_write(st, reg->sample_rate_div,
					ONE_K_HZ/INIT_FIFO_RATE - 1);
	if (result)
		return result;
	st->chip_config.fifo_rate = INIT_FIFO_RATE;
	st->irq_dur_ns            = INIT_DUR_TIME;
	st->chip_config.prog_start_addr = DMP_START_ADDR;
	st->chip_config.gyro_enable = 1;
	st->chip_config.gyro_fifo_enable = 1;
	if ((SECONDARY_SLAVE_TYPE_ACCEL == st->plat_data.sec_slave_type) &&
		st->mpu_slave) {
		result = st->mpu_slave->setup(st);
		if (result)
			return result;
		result = st->mpu_slave->set_fs(st, INV_FS_02G);
		if (result)
			return result;
		result = st->mpu_slave->set_lpf(st, INIT_FIFO_RATE);
		if (result)
			return result;
		st->chip_config.accl_enable = 1;
		st->chip_config.accl_fifo_enable = 1;
	}

	return 0;
}
/**
 *  set_power_mpu3050() - set power of mpu3050.
 *  @st:	Device driver instance.
 *  @power_on:  on/off
 */
int set_power_mpu3050(struct inv_mpu_iio_s *st, bool power_on)
{
	struct inv_reg_map_s *reg;
	u8 data, p;
	int result;
	reg = &st->reg;
	if (power_on) {
		data = 0;
	} else {
		if (st->mpu_slave) {
			result = st->mpu_slave->suspend(st);
			if (result)
				return result;
		}
		data = BIT_SLEEP;
	}
	if (st->chip_config.gyro_enable) {
		p = (BITS_3050_POWER1 | INV_CLK_PLL);
		result = inv_i2c_single_write(st, reg->pwr_mgmt_1, data | p);
		if (result)
			return result;

		p = (BITS_3050_POWER2 | INV_CLK_PLL);
		result = inv_i2c_single_write(st, reg->pwr_mgmt_1, data | p);
		if (result)
			return result;

		p = INV_CLK_PLL;
		result = inv_i2c_single_write(st, reg->pwr_mgmt_1, data | p);
		if (result)
			return result;

		st->chip_config.clk_src = INV_CLK_PLL;
	} else {
		data |= (BITS_3050_GYRO_STANDBY | INV_CLK_INTERNAL);
		result = inv_i2c_single_write(st, reg->pwr_mgmt_1, data);
		if (result)
			return result;
		st->chip_config.clk_src = INV_CLK_INTERNAL;
	}
	if (power_on) {
		msleep(POWER_UP_TIME);
		if (st->mpu_slave) {
			result = st->mpu_slave->resume(st);
			if (result)
				return result;
		}
	}
	st->chip_config.is_asleep = !power_on;

	return 0;
}
static int mpu6500_do_powerup(struct inv_mpu_state *st)
{
	int result = 0;
	char reg;

	inv_i2c_single_write(st, MPUREG_PWR_MGMT_1, 0x1);

	mdelay(20);

	inv_i2c_read(st, MPUREG_PWR_MGMT_2, 1, &reg);

	reg &= ~(BIT_STBY_XG | BIT_STBY_YG | BIT_STBY_ZG |\
		BIT_STBY_XA | BIT_STBY_YA | BIT_STBY_ZA);
	inv_i2c_single_write(st, MPUREG_PWR_MGMT_2, reg);

	return result;
}
예제 #6
0
int invdmp_write_register(u16 addr, u16 length, const u8 data,
                        void *dbase_data)
{
        struct dmp_ctrl_t *dctl = dbase_data;

        INV_DBG_FUNC_NAME;

        return inv_i2c_single_write(dctl->i2c_handle, dctl->i2c_addr,
                                 addr, (u8) data);
}
static int mpu6500_do_test(struct inv_mpu_state *st, int self_test_flag,
	int *gyro_result, int *accel_result, int sensors)
{
	int result, i, j, k, packet_size;
	u8 data[BYTES_PER_SENSOR * 2], d;
	int fifo_count, packet_count, ind, s;

	if ((sensors & MPU6500_HWST_ALL) == MPU6500_HWST_ALL)
		packet_size = BYTES_PER_SENSOR * 2;
	else
		packet_size = BYTES_PER_SENSOR;

	result = inv_i2c_single_write(st, MPUREG_INT_ENABLE, 0);
	if (result)
		return result;
	/* disable the sensor output to FIFO */
	result = inv_i2c_single_write(st, MPUREG_FIFO_EN, 0);
	if (result)
		return result;
	/* disable fifo reading */
	result = inv_i2c_single_write(st, MPUREG_USER_CTRL, 0);
	if (result)
		return result;
	/* clear FIFO */
	result = inv_i2c_single_write(st, MPUREG_USER_CTRL, BIT_FIFO_RST);
	if (result)
		return result;
	/* setup parameters */
	result = inv_i2c_single_write(st, MPUREG_CONFIG, MPU_FILTER_184HZ);
	if (result)
		return result;
	result = inv_i2c_single_write(st, MPUREG_ACCEL_CONFIG2,
		DEF_ST_MPU6500_ACCEL_LPF);
	if (result)
		return result;
	result = inv_i2c_single_write(st, MPUREG_SMPLRT_DIV, 0x0);
	if (result)
		return result;
	result = inv_i2c_single_write(st, MPUREG_GYRO_CONFIG, self_test_flag | (MPU_FS_250DPS << 3));
	if (result)
		return result;
	result = inv_i2c_single_write(st, MPUREG_ACCEL_CONFIG,
				self_test_flag | DEF_SELFTEST_6500_ACCEL_FS);
	if (result)
		return result;

	/* wait for the output to get stable */
	mdelay(DEF_ST_STABLE_TIME);

	/* enable FIFO reading */
	result = inv_i2c_single_write(st,
			MPUREG_USER_CTRL, BIT_FIFO_EN);
	if (result)
		return result;
	/* enable sensor output to FIFO */
	d = 0;
	if (sensors & MPU6500_HWST_ACCEL)
		d |= BITS_ACCEL_OUT;
	if (sensors & MPU6500_HWST_GYRO)
		d |= BITS_GYRO_OUT;
	result = inv_i2c_single_write(st, MPUREG_FIFO_EN, d);
	if (result)
		return result;

	for (i = 0; i < THREE_AXIS; i++) {
		gyro_result[i] = 0;
		accel_result[i] = 0;
	}

	s = 0;

	while (s < INIT_SELFTEST_SAMPLES) {
		mdelay(DEF_GYRO_WAIT_TIME);
		/* stop sending data to FIFO */
		result = inv_i2c_single_write(st, MPUREG_FIFO_EN, 0);
		if (result)
			return result;

		result = inv_i2c_read(st,
			MPUREG_FIFO_COUNTH, FIFO_COUNT_BYTE, data);

		if (result)
			return result;

		fifo_count = be16_to_cpup((__be16 *)(&data[0]));
		packet_count = fifo_count / packet_size;

		for(k = 0 ; k < 5 ; k++)
		{
			result = inv_i2c_read(st, MPUREG_FIFO_R_W,
				packet_size, data);
			if (result)
				return result;
		}

		if( packet_count < (INIT_SELFTEST_SAMPLES - 3)) {
			printk(KERN_INFO "HW_SELF_TEST_PACKET_ERROR=%d", packet_count);
			return -1;
		}
		i = 0;

		while ((i < packet_count) && (s < INIT_SELFTEST_SAMPLES)) {
			result = inv_i2c_read(st, MPUREG_FIFO_R_W,
				packet_size, data);
			if (result)
				return result;

			ind = 0;

			if (sensors & MPU6500_HWST_ACCEL) {
				for (j = 0; j < THREE_AXIS; j++)
					accel_result[j] +=
					(short)be16_to_cpup((__be16 *)(&data[2 * j]));

				ind += BYTES_PER_SENSOR;
			}

			if (sensors & MPU6500_HWST_GYRO)
				for (j = 0; j < THREE_AXIS; j++)
					gyro_result[j] +=
					(short)be16_to_cpup((__be16 *)(&data[ind + 2 * j]));

			s++;
			i++;
		}
	}

	for (j = 0; j < THREE_AXIS; j++) {
		gyro_result[j] = gyro_result[j]/s;
		gyro_result[j] *= DEF_ST_PRECISION;
		accel_result[j] = accel_result[j]/s;
		accel_result[j] *= DEF_ST_PRECISION;
	}

	return 0;
}
int mpu6500_selftest_run(struct inv_mpu_state *st,
			 int packet_cnt[3],
			 int gyro_bias[3],
			 int gyro_rms[3],
			 int gyro_lsb_bias[3])
{
	int ret_val = 0;
	int result;
	int packet_count;
	long avg[3]={0};
	long rms[3]={0};
	int i, j;
	unsigned char regs[7] = {0};
	unsigned char data[FIFO_PACKET_SIZE * 2]={0}, read_data[2];
	int gyro_data[3][GYRO_MAX_PACKET_THRESH]={{0},};
	short fifo_cnt;
	int gyro_avg_tmp[3]={0};

	struct mpu6500_selftest_info test_setup = {
		DEF_GYRO_SENS, DEF_GYRO_FULLSCALE, DEF_PACKET_THRESH,
		DEF_TOTAL_TIMING_TOL, (int)DEF_BIAS_THRESH_SELF,
		DEF_RMS_LSB_THRESH_SELF * DEF_RMS_LSB_THRESH_SELF,
		/* now obsolete - has no effect */
		DEF_TESTS_PER_AXIS, DEF_N_ACCEL_SAMPLES
	};

	char a_name[3][2] = { "X", "Y", "Z" };

	/*backup registers */
	result = mpu6500_backup_register(st);
	if (result) {
		pr_err("%s, register backup error=%d", __func__, result);
		return result;
	}

	if (mpu6500_selftest.pwm_mgmt[0] & 0x60) {
		result = inv_i2c_single_write(st, MPUREG_PWR_MGMT_1, 0x00);
		if (result) {
			pr_err("%s, init PWR_MGMT error=%d", __func__, result);
			return result;
		}
	}

	regs[0] = mpu6500_selftest.pwm_mgmt[1] & ~(BIT_STBY_XG | BIT_STBY_YG | BIT_STBY_ZG);
	result = inv_i2c_single_write(st, MPUREG_PWR_MGMT_2, regs[0]);
	if (result) {
		pr_err("%s, power mgmt setting error=%d", __func__, result);
		return result;
	}

	result = inv_i2c_single_write(st, MPUREG_INT_ENABLE, 0);
	if (result) {
		pr_err("%s, INT ENABLE error=%d", __func__, result);
		return result;
	}

	/* disable the sensor output to FIFO */
	result = inv_i2c_single_write(st, MPUREG_FIFO_EN, 0);
	if (result) {
		pr_err("%s, FIFO EN error=%d", __func__, result);
		return result;
	}

	/* make sure the DMP is disabled first */
	result = inv_i2c_single_write(st, MPUREG_USER_CTRL, 0x00);
	if (result) {
		pr_err("%s, DMP disable error=%d", __func__, result);
		return result;
	}

	/* clear FIFO */
	result = inv_i2c_single_write(st, MPUREG_USER_CTRL, BIT_FIFO_RST);
	if (result) {
		pr_err("%s, USER_CTRL setting error=%d", __func__, result);
		return result;
	}

	/* sample rate *//* = 1ms */
	result = inv_i2c_single_write(st, MPUREG_SMPLRT_DIV, 0x00);
	if (result) {
		pr_err("%s, SMPLRT_DIV set error=%d", __func__, result);
		return result;
	}

	test_setup.bias_thresh = DEF_BIAS_LSB_THRESH_SELF;

	regs[0] = 0x03;		/* filter = 42Hz, analog_sample rate = 1 KHz */
	switch (test_setup.gyro_fs) {
	case 2000:
		regs[0] |= 0x18;
		break;
	case 1000:
		regs[0] |= 0x10;
		break;
	case 500:
		regs[0] |= 0x08;
		break;
	case 250:
	default:
		regs[0] |= 0x00;
		break;
	}
	result = inv_i2c_single_write(st, MPUREG_CONFIG, regs[0]);
	if (result) {
		pr_err("%s, CONFIG set error=%d", __func__, result);
		return result;
	}

	switch (test_setup.gyro_fs) {
	case 2000:
		regs[0] = 0x03;
		break;
	case 1000:
		regs[0] = 0x02;
		break;
	case 500:
		regs[0] = 0x01;
		break;
	case 250:
	default:
		regs[0] = 0x00;
		break;
	}
	result = inv_i2c_single_write(st, MPUREG_GYRO_CONFIG, regs[0] << 3);
	if (result) {
		pr_err("%s, GYRO_CONFIG set error=%d", __func__, result);
		return result;
	}

	// Wait time
//	msleep(GYRO_WAIT_TIME);
	mdelay(200);

	// Enable FIFO
	result = inv_i2c_single_write(st, MPUREG_USER_CTRL, BIT_FIFO_EN);
	if (result)
	  return result;

	// Enable gyro output to FIFO
	result = inv_i2c_single_write(st, MPUREG_FIFO_EN, BIT_GYRO_FIFO_EN);
	if (result)
	  return result;

	// Wait time
	mdelay(GYRO_WAIT_TIME);


	// Stop gyro FIFO
	result = inv_i2c_single_write(st, MPUREG_FIFO_EN, BIT_FIFO_DIS);
	if (result)
	  return result;

	// Read FIFO count
	result = inv_i2c_read(st, MPUREG_FIFO_COUNTH, 2, read_data);
	if (result)
		return result;

	fifo_cnt = be16_to_cpup((__be16 *)(&read_data[0]));

	packet_count = fifo_cnt != 0 ? (fifo_cnt/FIFO_PACKET_SIZE) : 1;

	if(packet_count > GYRO_PACKET_THRESH)
		packet_count = GYRO_PACKET_THRESH;

	// Check packet count
	if((abs(packet_count - GYRO_PACKET_THRESH) > GYRO_THRESH) && (packet_count < GYRO_PACKET_THRESH)) {
		pr_info("\r\n Gyro Packet counter Error: %d \r\n",packet_count);
	  return (ret_val |= 1);
	}

	pr_info("\r\n Gyro Packet counter : %d \r\n",packet_count);

	for (i = 0; i < packet_count; i++) {
	   /* getting FIFO data */
	     result = inv_i2c_read(st, MPUREG_FIFO_R_W, FIFO_PACKET_SIZE, data);
	     if (result)
		return result;

	   for (j = 0; j < THREE_AXIS; j++) {
		   gyro_data[j][i] = (int)mpu_big8_to_int16((&data[2*j]));
		   gyro_avg_tmp[j] += gyro_data[j][i];
		   avg[j] = (long)gyro_avg_tmp[j];
		   avg[j] /= packet_count;
	   }
	}


	pr_info("bias : %+8ld %+8ld %+8ld (LSB)\n", avg[X], avg[Y], avg[Z]);

	gyro_bias[X] = (int)((avg[X] * DEF_SCALE_FOR_FLOAT) / DEF_GYRO_SENS);
	gyro_bias[Y] = (int)((avg[Y] * DEF_SCALE_FOR_FLOAT) / DEF_GYRO_SENS);
	gyro_bias[Z] = (int)((avg[Z] * DEF_SCALE_FOR_FLOAT) / DEF_GYRO_SENS);
	gyro_lsb_bias[X] = (int)avg[X];
	gyro_lsb_bias[Y] = (int)avg[Y];
	gyro_lsb_bias[Z] = (int)avg[Z];

	if (VERBOSE_OUT) {
		pr_info("abs bias : %+8d.%03d   %+8d.%03d  %+8d.%03d (dps)\n",
		       (int)abs(gyro_bias[X]) / DEF_SCALE_FOR_FLOAT,
		       (int)abs(gyro_bias[X]) % DEF_SCALE_FOR_FLOAT,
		       (int)abs(gyro_bias[Y]) / DEF_SCALE_FOR_FLOAT,
		       (int)abs(gyro_bias[Y]) % DEF_SCALE_FOR_FLOAT,
		       (int)abs(gyro_bias[Z]) / DEF_SCALE_FOR_FLOAT,
		       (int)abs(gyro_bias[Z]) % DEF_SCALE_FOR_FLOAT);
	}

	for (j = 0; j < 3; j++) {
		if (abs(avg[j]) > test_setup.bias_thresh) {
			pr_err("%s-Gyro bias (%ld) exceeded threshold "
			       "(threshold = %d LSB)\n", a_name[j], avg[j],
			       test_setup.bias_thresh);
			ret_val |= 1 << (3 + j);
		}
	}

	/* 3rd, check RMS for dead gyros
	   If any of the RMS noise value returns zero,
	   then we might have dead gyro or FIFO/register failure,
	   the part is sleeping, or the part is not responsive */
	for (i = 0, rms[X] = 0, rms[Y] = 0, rms[Z] = 0; i < packet_count; i++) {
		rms[X] += (long)(gyro_data[0][i] - avg[X]) * (gyro_data[0][i] - avg[X]);
		rms[Y] += (long)(gyro_data[1][i] - avg[Y]) * (gyro_data[1][i] - avg[Y]);
		rms[Z] += (long)(gyro_data[2][i] - avg[Z]) * (gyro_data[2][i] - avg[Z]);
		if (rms[X] == 0 || rms[Y] == 0 || rms[Z] == 0)
			pr_err("RMS returns zero, gyro = %d %d %d (avg = %ld %ld %ld)\n",
				gyro_data[0][i], gyro_data[1][i], gyro_data[2][i],
				avg[X], avg[Y], avg[Z]);
	}

	if (rms[X] == 0 || rms[Y] == 0 || rms[Z] == 0)
		ret_val |= 1 << 6;

	if (VERBOSE_OUT) {
		pr_info("RMS ^ 2 : %+8ld %+8ld %+8ld\n",
		       (long)rms[X] / packet_count,
		       (long)rms[Y] / packet_count, (long)rms[Z] / packet_count);
	}

	{
		int dps_rms[3] = { 0 };
		u32 tmp;
		int i = 0;

		for (j = 0; j < 3; j++) {
			if (rms[j] / packet_count > test_setup.rms_thresh) {
				pr_err("%s-Gyro rms (%ld) exceeded threshold "
				       "(threshold = %d LSB)\n", a_name[j],
				       rms[j] / packet_count,
				       test_setup.rms_thresh);
				ret_val |= 1 << (7 + j);
			}
		}

		for (i = 0; i < 3; i++) {
			if (rms[i] > 10000) {
				tmp = ((u32) (rms[i] / packet_count)) * DEF_RMS_SCALE_FOR_RMS;
			} else {
				tmp = ((u32) (rms[i] * DEF_RMS_SCALE_FOR_RMS)) / packet_count;
			}

			if (rms[i] < 0)
				tmp = 1 << 31;

			dps_rms[i] = mpu6500_selftest_sqrt(tmp) / DEF_GYRO_SENS;

			gyro_rms[i] = dps_rms[i] * DEF_SCALE_FOR_FLOAT / DEF_SQRT_SCALE_FOR_RMS;
		}

		pr_info("RMS : %+8d.%03d	 %+8d.%03d	%+8d.%03d (dps)\n",
		       (int)abs(gyro_rms[X]) / DEF_SCALE_FOR_FLOAT,
		       (int)abs(gyro_rms[X]) % DEF_SCALE_FOR_FLOAT,
		       (int)abs(gyro_rms[Y]) / DEF_SCALE_FOR_FLOAT,
		       (int)abs(gyro_rms[Y]) % DEF_SCALE_FOR_FLOAT,
		       (int)abs(gyro_rms[Z]) / DEF_SCALE_FOR_FLOAT,
		       (int)abs(gyro_rms[Z]) % DEF_SCALE_FOR_FLOAT);
	}

	/*recover registers */
	result = mpu6500_recover_register(st);
	if (result) {
		pr_err("%s, register recovering error=%d", __func__, result);
		return result;
	}
	return ret_val;
}
static int mpu6500_recover_register(struct inv_mpu_state *st)
{
	int result = 0;

	result =
	    inv_i2c_single_write(st, MPUREG_CONFIG,
					 mpu6500_selftest.config);
	if (result)
		return result;

	result =
	    inv_i2c_single_write(st, MPUREG_GYRO_CONFIG,
					 mpu6500_selftest.gyro_config);
	if (result)
		return result;

	result =
		inv_i2c_single_write(st, MPUREG_ACCEL_CONFIG,
				 mpu6500_selftest.accel_config);
	if (result)
		return result;

	result =
		inv_i2c_single_write(st, MPUREG_ACCEL_CONFIG2,
				 mpu6500_selftest.accel_config2);
	if (result)
		return result;

	result =
	    inv_i2c_single_write(st, MPUREG_USER_CTRL,
					 mpu6500_selftest.user_ctrl);
	if (result)
		return result;

	result =
	    inv_i2c_single_write(st, MPUREG_SMPLRT_DIV,
					 mpu6500_selftest.smplrt_div);
	if (result)
		return result;

	result = inv_i2c_single_write(st, MPUREG_FIFO_EN,
					 mpu6500_selftest.fifo_enable);
	if (result)
		return result;

	result =
	    inv_i2c_single_write(st, MPUREG_INT_ENABLE,
					 mpu6500_selftest.int_enable);
	if (result)
		return result;

	result =
	    inv_i2c_single_write(st, MPUREG_PWR_MGMT_2,
					 mpu6500_selftest.pwm_mgmt[1]);
	if (result)
		return result;

	result =
	    inv_i2c_single_write(st, MPUREG_PWR_MGMT_1,
					 mpu6500_selftest.pwm_mgmt[0]);
	if (result)
		return result;

	return result;
}
/**
 *  set_power_mpu3050() - set power of mpu3050.
 *  @st:	Device driver instance.
 *  @power_on:  on/off
 */
int set_power_mpu3050(struct inv_mpu_iio_s *st, bool power_on)
{
	struct inv_reg_map_s *reg;
	u8 data, p;
	int result;
	reg = &st->reg;

	dev_dbg(&st->client->dev, "%s: %d", __func__, power_on);
	if (power_on) {
		result = pm_runtime_get_sync(&st->client->dev);
		if (result < 0) {
			dev_err(&st->client->dev,
					"%s, line=%d\n", __func__, __LINE__);
			pm_runtime_put_noidle(&st->client->dev);
			return result;
		}
		data = 0;
	} else {
		if (st->mpu_slave) {
			result = st->mpu_slave->suspend(st);
			if (result)
				return result;
		}
		data = BIT_SLEEP;
	}
	if (st->chip_config.gyro_enable) {
		p = (BITS_3050_POWER1 | INV_CLK_PLL);
		result = inv_i2c_single_write(st, reg->pwr_mgmt_1, data | p);
		if (result)
			return result;

		p = (BITS_3050_POWER2 | INV_CLK_PLL);
		result = inv_i2c_single_write(st, reg->pwr_mgmt_1, data | p);
		if (result)
			return result;

		p = INV_CLK_PLL;
		result = inv_i2c_single_write(st, reg->pwr_mgmt_1, data | p);
		if (result)
			return result;
	} else {
		data |= (BITS_3050_GYRO_STANDBY | INV_CLK_INTERNAL);
		result = inv_i2c_single_write(st, reg->pwr_mgmt_1, data);
		if (result)
			return result;
	}
	if (power_on) {
		msleep(POWER_UP_TIME);
		if (st->mpu_slave) {
			result = st->mpu_slave->resume(st);
			if (result)
				return result;
		}
	} else {
		pm_runtime_mark_last_busy(&st->client->dev);
		pm_runtime_put_autosuspend(&st->client->dev);
	}
	st->chip_config.is_asleep = !power_on;

	return 0;
}