static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
{
	u8 reg;
	s16 x, y, z;
	u8 selftest;
	int ret;

	mutex_lock(&lis3->mutex);
	if (lis3_dev.whoami == WAI_12B)
		selftest = CTRL1_ST;
	else
		selftest = CTRL1_STP;

	lis3->read(lis3, CTRL_REG1, &reg);
	lis3->write(lis3, CTRL_REG1, (reg | selftest));
	msleep(lis3->pwron_delay / lis3lv02d_get_odr());

	/* Read directly to avoid axis remap */
	x = lis3->read_data(lis3, OUTX);
	y = lis3->read_data(lis3, OUTY);
	z = lis3->read_data(lis3, OUTZ);

	/* back to normal settings */
	lis3->write(lis3, CTRL_REG1, reg);
	msleep(lis3->pwron_delay / lis3lv02d_get_odr());

	results[0] = x - lis3->read_data(lis3, OUTX);
	results[1] = y - lis3->read_data(lis3, OUTY);
	results[2] = z - lis3->read_data(lis3, OUTZ);

	ret = 0;
	if (lis3->pdata) {
		int i;
		for (i = 0; i < 3; i++) {
			/* Check against selftest acceptance limits */
			if ((results[i] < lis3->pdata->st_min_limits[i]) ||
			    (results[i] > lis3->pdata->st_max_limits[i])) {
				ret = -EIO;
				goto fail;
			}
		}
	}

	/* test passed */
fail:
	mutex_unlock(&lis3->mutex);
	return ret;
}
void lis3lv02d_poweron(struct lis3lv02d *lis3)
{
	u8 reg;

	lis3->init(lis3);

	/*
	 * Common configuration
	 * BDU: (12 bits sensors only) LSB and MSB values are not updated until
	 *      both have been read. So the value read will always be correct.
	 * Set BOOT bit to refresh factory tuning values.
	 */
	if (lis3->pdata) {
		lis3->read(lis3, CTRL_REG2, &reg);
		if (lis3->whoami ==  WAI_12B)
			reg |= CTRL2_BDU | CTRL2_BOOT;
		else
			reg |= CTRL2_BOOT_8B;
		lis3->write(lis3, CTRL_REG2, reg);
	}

	/* LIS3 power on delay is quite long */
	msleep(lis3->pwron_delay / lis3lv02d_get_odr());

	if (lis3->reg_ctrl)
		lis3_context_restore(lis3);
}
void lis3lv02d_poweron(struct lis3lv02d *lis3)
{
	u8 reg;

	lis3->init(lis3);

	/* LIS3 power on delay is quite long */
	msleep(lis3->pwron_delay / lis3lv02d_get_odr());

	/*
	 * Common configuration
	 * BDU: (12 bits sensors only) LSB and MSB values are not updated until
	 *      both have been read. So the value read will always be correct.
	 */
	if (lis3->whoami ==  WAI_12B) {
		lis3->read(lis3, CTRL_REG2, &reg);
		reg |= CTRL2_BDU;
		lis3->write(lis3, CTRL_REG2, reg);
	}
}
static ssize_t lis3lv02d_rate_show(struct device *dev,
			struct device_attribute *attr, char *buf)
{
	lis3lv02d_sysfs_poweron(&lis3_dev);
	return sprintf(buf, "%d\n", lis3lv02d_get_odr());
}
static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
{
	u8 ctlreg, reg;
	s16 x, y, z;
	u8 selftest;
	int ret;
	u8 ctrl_reg_data;
	unsigned char irq_cfg;

	mutex_lock(&lis3->mutex);

	irq_cfg = lis3->irq_cfg;
	if (lis3_dev.whoami == WAI_8B) {
		lis3->data_ready_count[IRQ_LINE0] = 0;
		lis3->data_ready_count[IRQ_LINE1] = 0;

		/* Change interrupt cfg to data ready for selftest */
		atomic_inc(&lis3_dev.wake_thread);
		lis3->irq_cfg = LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY;
		lis3->read(lis3, CTRL_REG3, &ctrl_reg_data);
		lis3->write(lis3, CTRL_REG3, (ctrl_reg_data &
				~(LIS3_IRQ1_MASK | LIS3_IRQ2_MASK)) |
				(LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY));
	}

	if (lis3_dev.whoami == WAI_3DC) {
		ctlreg = CTRL_REG4;
		selftest = CTRL4_ST0;
	} else {
		ctlreg = CTRL_REG1;
		if (lis3_dev.whoami == WAI_12B)
			selftest = CTRL1_ST;
		else
			selftest = CTRL1_STP;
	}

	lis3->read(lis3, ctlreg, &reg);
	lis3->write(lis3, ctlreg, (reg | selftest));
	msleep(lis3->pwron_delay / lis3lv02d_get_odr());

	/* Read directly to avoid axis remap */
	x = lis3->read_data(lis3, OUTX);
	y = lis3->read_data(lis3, OUTY);
	z = lis3->read_data(lis3, OUTZ);

	/* back to normal settings */
	lis3->write(lis3, ctlreg, reg);
	msleep(lis3->pwron_delay / lis3lv02d_get_odr());

	results[0] = x - lis3->read_data(lis3, OUTX);
	results[1] = y - lis3->read_data(lis3, OUTY);
	results[2] = z - lis3->read_data(lis3, OUTZ);

	ret = 0;

	if (lis3_dev.whoami == WAI_8B) {
		/* Restore original interrupt configuration */
		atomic_dec(&lis3_dev.wake_thread);
		lis3->write(lis3, CTRL_REG3, ctrl_reg_data);
		lis3->irq_cfg = irq_cfg;

		if ((irq_cfg & LIS3_IRQ1_MASK) &&
			lis3->data_ready_count[IRQ_LINE0] < 2) {
			ret = SELFTEST_IRQ;
			goto fail;
		}

		if ((irq_cfg & LIS3_IRQ2_MASK) &&
			lis3->data_ready_count[IRQ_LINE1] < 2) {
			ret = SELFTEST_IRQ;
			goto fail;
		}
	}

	if (lis3->pdata) {
		int i;
		for (i = 0; i < 3; i++) {
			/* Check against selftest acceptance limits */
			if ((results[i] < lis3->pdata->st_min_limits[i]) ||
			    (results[i] > lis3->pdata->st_max_limits[i])) {
				ret = SELFTEST_FAIL;
				goto fail;
			}
		}
	}

	/* test passed */
fail:
	mutex_unlock(&lis3->mutex);
	return ret;
}
static ssize_t lis3lv02d_rate_show(struct device *dev,
			struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "%d\n", lis3lv02d_get_odr());
}