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

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

Merge "icm20602: fix attribute show and add ldo control"

parents bb381806 1e96e31d
Loading
Loading
Loading
Loading
+11 −19
Original line number Diff line number Diff line
@@ -99,7 +99,6 @@ int icm20602_bulk_read(struct inv_icm20602_state *st,
{
	int result = MPU_SUCCESS;
	char tx_buf[2] = {0x0, 0x0};
	int tmp_size = size;
	u8 *tmp_buf = buf;
	struct i2c_msg msg[2];

@@ -225,7 +224,7 @@ int icm20602_read_raw(struct inv_icm20602_state *st,
{
	struct struct_icm20602_raw_data raw_data;

	if (type & ACCEL != 0) {
	if ((type) & (ACCEL) != 0) {
		icm20602_read_reg(st,
			reg_set_20602.ACCEL_XOUT_H.address,
			&raw_data.ACCEL_XOUT_H);
@@ -257,7 +256,7 @@ int icm20602_read_raw(struct inv_icm20602_state *st,
			raw_data.ACCEL_ZOUT_L);
	}

	if (type & GYRO != 0) {
	if ((type) & (GYRO) != 0) {
		icm20602_read_reg(st,
			reg_set_20602.GYRO_XOUT_H.address,
			&raw_data.GYRO_XOUT_H);
@@ -327,7 +326,7 @@ int icm20602_start_fifo(struct inv_icm20602_state *st)
	return MPU_SUCCESS;
}

static int icm20602_stop_fifo(struct inv_icm20602_state *st)
int icm20602_stop_fifo(struct inv_icm20602_state *st)
{
	struct icm20602_user_config *config = NULL;

@@ -434,10 +433,7 @@ static int icm20602_read_ST_code(struct inv_icm20602_state *st)
static int icm20602_set_self_test(struct inv_icm20602_state *st)
{
	uint8_t raw_data[6] = {0, 0, 0, 0, 0, 0};
	uint8_t selfTest[6];
	float factory_trim[6];
	int result = 0;
	int ii;

	reg_set_20602.SMPLRT_DIV.reg_u.REG.SMPLRT_DIV = 0;
	result |= icm20602_write_reg_simple(st, reg_set_20602.SMPLRT_DIV);
@@ -456,7 +452,7 @@ static int icm20602_set_self_test(struct inv_icm20602_state *st)
	reg_set_20602.ACCEL_CONFIG.reg_u.REG.ACCEL_FS_SEL = ICM20602_ACC_FSR_2G;
	result |= icm20602_write_reg_simple(st, reg_set_20602.ACCEL_CONFIG);

	//icm20602_read_ST_code(st);
	icm20602_read_ST_code(st);

	return 0;
}
@@ -466,8 +462,7 @@ static int icm20602_do_test_acc(struct inv_icm20602_state *st,
{
	struct struct_icm20602_real_data *real_data =
		kmalloc(sizeof(struct inv_icm20602_state), GFP_ATOMIC);
	struct icm20602_user_config *config = st->config;
	int i, j;
	int i;

	for (i = 0; i < SELFTEST_COUNT; i++) {
		icm20602_read_raw(st, real_data, ACCEL);
@@ -514,7 +509,7 @@ static int icm20602_do_test_gyro(struct inv_icm20602_state *st,
{
	struct struct_icm20602_real_data *real_data =
		kmalloc(sizeof(struct inv_icm20602_state), GFP_ATOMIC);
	int i, j;
	int i;

	for (i = 0; i < SELFTEST_COUNT; i++) {
		icm20602_read_raw(st, real_data, GYRO);
@@ -570,7 +565,7 @@ static bool icm20602_check_acc_selftest(struct inv_icm20602_state *st,
	st_otp.Y = (st_otp.Y != 0) ? mpu_st_tb[acc_ST_code.Y - 1] : 0;
	st_otp.Z = (st_otp.Z != 0) ? mpu_st_tb[acc_ST_code.Z - 1] : 0;

	if (st_otp.X & st_otp.Y & st_otp.Z == 0)
	if ((st_otp.X) & (st_otp.Y) & (st_otp.Z) == 0)
		otp_value_zero = true;

	st_shift_cust.X = acc_st->X - acc->X;
@@ -627,11 +622,11 @@ static int icm20602_check_gyro_selftest(struct inv_icm20602_state *st,
	gyro_ST_code.Y = st->config->gyro_self_test.Y;
	gyro_ST_code.Z = st->config->gyro_self_test.Z;

	st_otp.X = (st_otp.X != 0) ? mpu_st_tb[gyro_ST_code.X - 1] : 0;
	st_otp.Y = (st_otp.Y != 0) ? mpu_st_tb[gyro_ST_code.Y - 1] : 0;
	st_otp.Z = (st_otp.Z != 0) ? mpu_st_tb[gyro_ST_code.Z - 1] : 0;
	st_otp.X = (gyro_ST_code.X != 0) ? mpu_st_tb[gyro_ST_code.X - 1] : 0;
	st_otp.Y = (gyro_ST_code.Y != 0) ? mpu_st_tb[gyro_ST_code.Y - 1] : 0;
	st_otp.Z = (gyro_ST_code.Z != 0) ? mpu_st_tb[gyro_ST_code.Z - 1] : 0;

	if (st_otp.X & st_otp.Y & st_otp.Z == 0)
	if ((st_otp.X) & (st_otp.Y) & (st_otp.Z) == 0)
		otp_value_zero = true;

	st_shift_cust.X = gyro_st->X - gyro->X;
@@ -741,8 +736,6 @@ static int icm20602_initialize_gyro(struct inv_icm20602_state *st)
{
	struct icm20602_user_config *config = NULL;
	int result = MPU_SUCCESS;
	int sample_rate;
	uint8_t fchoice_b;

	if (st == NULL)
		return -MPU_FAIL;
@@ -928,7 +921,6 @@ int icm20602_detect(struct inv_icm20602_state *st)
{
	int result = MPU_SUCCESS;
	uint8_t retry = 0, val = 0;
	uint8_t usr_ctrl = 0;

	pr_debug("icm20602_detect\n");
	/* reset to make sure previous state are not there */
+104 −36
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <linux/of.h>
#include <linux/of_gpio.h>
#include "inv_icm20602_iio.h"
#include <linux/regulator/consumer.h>

/* Attribute of icm20602 device init show */
static ssize_t inv_icm20602_init_show(struct device *dev,
@@ -89,7 +90,10 @@ static IIO_DEVICE_ATTR(
static ssize_t inv_gyro_lpf_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	return 0;
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct inv_icm20602_state *st = iio_priv(indio_dev);

	return snprintf(buf, 4, "%d\n", st->config->gyro_lpf);
}

static ssize_t inv_gyro_lpf_store(struct device *dev,
@@ -105,6 +109,7 @@ static ssize_t inv_gyro_lpf_store(struct device *dev,
	if (gyro_lpf > INV_ICM20602_GYRO_LFP_NUM)
		return -EINVAL;
	config->gyro_lpf = gyro_lpf;

	return count;
}
static IIO_DEVICE_ATTR(
@@ -118,7 +123,10 @@ static IIO_DEVICE_ATTR(
static ssize_t inv_gyro_fsr_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	return 0;
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct inv_icm20602_state *st = iio_priv(indio_dev);

	return snprintf(buf, 4, "%d\n", st->config->gyro_fsr);
}

static ssize_t inv_gyro_fsr_store(struct device *dev,
@@ -145,30 +153,37 @@ static IIO_DEVICE_ATTR(
						inv_gyro_fsr_store,
						0);

/* Attribute of gyro_self_test */
static ssize_t inv_gyro_self_test_show(struct device *dev,
/* Attribute of self_test */
static ssize_t inv_self_test_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	return 0;
}

static ssize_t inv_gyro_self_test_store(struct device *dev,
static ssize_t inv_self_test_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
	return 0;
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct inv_icm20602_state *st = iio_priv(indio_dev);

	icm20602_self_test(st);
	return count;
}
static IIO_DEVICE_ATTR(
						inv_icm20602_gyro_self_test,
						inv_icm20602_self_test,
						0644,
						inv_gyro_self_test_show,
						inv_gyro_self_test_store,
						inv_self_test_show,
						inv_self_test_store,
						0);

/* Attribute of gyro fsr base on enum inv_icm20602_acc_fsr_e */
static ssize_t inv_gyro_acc_fsr_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	return 0;
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct inv_icm20602_state *st = iio_priv(indio_dev);

	return snprintf(buf, 4, "%d\n", st->config->acc_fsr);
}

static ssize_t inv_gyro_acc_fsr_store(struct device *dev,
@@ -198,7 +213,10 @@ static IIO_DEVICE_ATTR(
static ssize_t inv_gyro_acc_lpf_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	return 0;
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct inv_icm20602_state *st = iio_priv(indio_dev);

	return snprintf(buf, 4, "%d\n", st->config->acc_lpf);
}

static ssize_t inv_gyro_acc_lpf_store(struct device *dev,
@@ -224,30 +242,14 @@ static IIO_DEVICE_ATTR(
						inv_gyro_acc_lpf_store,
						0);

/* Attribute of acc_self_test */
static ssize_t inv_acc_self_test_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	return 0;
}

static ssize_t inv_acc_self_test_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
	return 0;
}
static IIO_DEVICE_ATTR(
						inv_icm20602_acc_self_test,
						0644,
						inv_acc_self_test_show,
						inv_acc_self_test_store,
						0);

/* Attribute of user_fps_in_ms */
static ssize_t inv_user_fps_in_ms_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	return 0;
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct inv_icm20602_state *st = iio_priv(indio_dev);

	return snprintf(buf, 4, "%d\n", st->config->user_fps_in_ms);
}

static ssize_t inv_user_fps_in_ms_store(struct device *dev,
@@ -277,13 +279,27 @@ static IIO_DEVICE_ATTR(
static ssize_t inv_sampling_frequency_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	return 0;
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct inv_icm20602_state *st = iio_priv(indio_dev);

	return snprintf(buf, 4, "%d\n", st->config->gyro_accel_sample_rate);
}

static ssize_t inv_sampling_frequency_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
	return 0;
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct inv_icm20602_state *st = iio_priv(indio_dev);
	struct icm20602_user_config *config = st->config;
	int gyro_accel_sample_rate;

	if (kstrtoint(buf, 10, &gyro_accel_sample_rate))
		return -EINVAL;
	if (gyro_accel_sample_rate < 10)
		return -EINVAL;

	config->gyro_accel_sample_rate = gyro_accel_sample_rate;
	return count;
}
static IIO_DEV_ATTR_SAMP_FREQ(
						0644,
@@ -293,11 +309,11 @@ static IIO_DEV_ATTR_SAMP_FREQ(
static struct attribute *inv_icm20602_attributes[] = {
	&iio_dev_attr_inv_icm20602_init.dev_attr.attr,

	&iio_dev_attr_inv_icm20602_gyro_self_test.dev_attr.attr,
	&iio_dev_attr_inv_icm20602_gyro_fsr.dev_attr.attr,
	&iio_dev_attr_inv_icm20602_gyro_lpf.dev_attr.attr,

	&iio_dev_attr_inv_icm20602_acc_self_test.dev_attr.attr,
	&iio_dev_attr_inv_icm20602_self_test.dev_attr.attr,

	&iio_dev_attr_inv_icm20602_acc_fsr.dev_attr.attr,
	&iio_dev_attr_inv_icm20602_acc_lpf.dev_attr.attr,

@@ -363,6 +379,44 @@ static const struct iio_info icm20602_info = {
	.validate_trigger = inv_icm20602_validate_trigger,
};

static int icm20602_ldo_work(struct inv_icm20602_state *st, bool enable)
{
	int ret = 0;

	if (enable) {
		ret = regulator_set_voltage(st->reg_ldo,
			ICM20602_LDO_VTG_MIN_UV, ICM20602_LDO_VTG_MAX_UV);
		if (ret)
			pr_err("Failed to request LDO voltage.\n");

		ret = regulator_enable(st->reg_ldo);
		if (ret)
			pr_err("Failed to enable LDO %d\n", ret);
	} else {
		ret = regulator_disable(st->reg_ldo);
		if (ret)
			pr_err("Failed to disable LDO %d\n", ret);
		regulator_set_load(st->reg_ldo, 0);
	}

	return MPU_SUCCESS;
}

static int icm20602_init_regulators(struct inv_icm20602_state *st)
{
	struct regulator *reg;

	reg = regulator_get(&st->client->dev, "vdd-ldo");
	if (IS_ERR_OR_NULL(reg)) {
		pr_err("Unable to get regulator for LDO\n");
		return -MPU_FAIL;
	}

	st->reg_ldo = reg;

	return MPU_SUCCESS;
}

static int of_populate_icm20602_dt(struct inv_icm20602_state *st)
{
	int result = MPU_SUCCESS;
@@ -450,6 +504,8 @@ static int inv_icm20602_probe(struct i2c_client *client,
				result);
		goto out_remove_trigger;
	}
	icm20602_init_regulators(st);
	icm20602_ldo_work(st, true);

	result = inv_icm20602_probe_trigger(indio_dev);
	if (result) {
@@ -471,7 +527,6 @@ static int inv_icm20602_probe(struct i2c_client *client,
	inv_icm20602_remove_trigger(st);
out_unreg_ring:
	iio_triggered_buffer_cleanup(indio_dev);
out_free:
	iio_device_free(indio_dev);
	gpio_free(st->gpio);

@@ -494,11 +549,24 @@ static int inv_icm20602_remove(struct i2c_client *client)

static int inv_icm20602_suspend(struct device *dev)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct inv_icm20602_state *st = iio_priv(indio_dev);

	icm20602_stop_fifo(st);
	icm20602_ldo_work(st, false);
	return 0;
}

static int inv_icm20602_resume(struct device *dev)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct inv_icm20602_state *st = iio_priv(indio_dev);

	icm20602_ldo_work(st, true);
	icm20602_detect(st);
	icm20602_init_device(st);
	icm20602_start_fifo(st);

	return 0;
}

+6 −0
Original line number Diff line number Diff line
@@ -41,6 +41,9 @@
#define INV20602_SMD_IRQ_TRIGGER    1
#endif

#define ICM20602_LDO_VTG_MIN_UV 3300000
#define ICM20602_LDO_VTG_MAX_UV 3300000

#define INV_ICM20602_TIME_STAMP_TOR           5
#define ICM20602_PACKAGE_SIZE 14

@@ -217,6 +220,7 @@ struct inv_icm20602_state {
	struct struct_icm20602_data *data_push;
	enum inv_devices chip_type;
	int gpio;
	struct regulator *reg_ldo;
	DECLARE_KFIFO(timestamps, long long, TIMESTAMP_FIFO_SIZE);
};

@@ -281,4 +285,6 @@ int icm20602_detect(struct inv_icm20602_state *st);
int icm20602_read_fifo(struct inv_icm20602_state *st,
	void *buf, const int size);
int icm20602_start_fifo(struct inv_icm20602_state *st);
int icm20602_stop_fifo(struct inv_icm20602_state *st);
bool icm20602_self_test(struct inv_icm20602_state *st);
#endif
+2 −10
Original line number Diff line number Diff line
@@ -67,9 +67,8 @@ static int inv_icm20602_read_data(struct iio_dev *indio_dev)
	struct icm20602_user_config *config = st->config;
	int package_count;
	char *buf = st->buf;
	struct struct_icm20602_data *data_push = st->data_push;
	s64 timestamp;
	u8 int_status, int_wm_status;
	u8 int_status;
	u16 fifo_count;
	int i;

@@ -81,6 +80,7 @@ static int inv_icm20602_read_data(struct iio_dev *indio_dev)
	if (int_status & BIT_FIFO_OFLOW_INT) {
		icm20602_fifo_count(st, &fifo_count);
		pr_debug("fifo_count = %d\n", fifo_count);
		inv_clear_kfifo(st);
		icm20602_reset_fifo(st);
		goto end_session;
	}
@@ -105,14 +105,6 @@ static int inv_icm20602_read_data(struct iio_dev *indio_dev)
	mutex_unlock(&indio_dev->mlock);
	iio_trigger_notify_done(indio_dev->trig);
	return MPU_SUCCESS;

flush_fifo:
	/* Flush HW and SW FIFOs. */
	inv_clear_kfifo(st);
	icm20602_reset_fifo(st);
	mutex_unlock(&indio_dev->mlock);
	iio_trigger_notify_done(indio_dev->trig);
	return MPU_SUCCESS;
}

/*