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

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

Merge "msm: camera: sensor: I2C poll implementation"

parents 7fc1e24b 8eed1d58
Loading
Loading
Loading
Loading
+19 −22
Original line number Diff line number Diff line
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -156,7 +156,7 @@ static int msm_actuator_bivcm_handle_i2c_ops(
	uint32_t hw_dword = hw_params;
	uint16_t i2c_byte1 = 0, i2c_byte2 = 0;
	uint16_t value = 0, reg_data = 0;
	uint32_t size = a_ctrl->reg_tbl_size, i = 0, j = 0;
	uint32_t size = a_ctrl->reg_tbl_size, i = 0;
	int32_t rc = 0;
	struct msm_camera_i2c_reg_array i2c_tbl;
	struct msm_camera_i2c_reg_setting reg_setting;
@@ -266,24 +266,18 @@ static int msm_actuator_bivcm_handle_i2c_ops(
					write_arr[i].addr_type);
				break;
			}
			for (j = 0; j < ACTUATOR_MAX_POLL_COUNT; j++) {

			rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_poll(
				&a_ctrl->i2c_client,
				write_arr[i].reg_addr,
				write_arr[i].reg_data,
					write_arr[i].data_type);
				if (rc == 1)
					continue;
				write_arr[i].data_type,
				write_arr[i].delay);
			if (rc < 0) {
				pr_err("i2c poll error:%d\n", rc);
				return rc;
			}
			break;
			}
			if (j == ACTUATOR_MAX_POLL_COUNT)
				CDBG("%s:%d Poll register not as expected\n",
				__func__, __LINE__);
			break;
		case MSM_ACTUATOR_READ_WRITE:
			i2c_tbl.reg_addr = write_arr[i].reg_addr;
			i2c_tbl.delay = write_arr[i].delay;
@@ -386,13 +380,19 @@ static int32_t msm_actuator_init_focus(struct msm_actuator_ctrl_t *a_ctrl,
				settings[i].reg_addr,
				settings[i].reg_data,
				settings[i].data_type);
			if (settings[i].delay > 20)
				msleep(settings[i].delay);
			else if (0 != settings[i].delay)
				usleep_range(settings[i].delay * 1000,
					(settings[i].delay * 1000) + 1000);
			break;
		case MSM_ACT_POLL:
			rc = a_ctrl->i2c_client.i2c_func_tbl->i2c_poll(
				&a_ctrl->i2c_client,
				settings[i].reg_addr,
				settings[i].reg_data,
				settings[i].data_type);
				settings[i].data_type,
				settings[i].delay);
			break;
		default:
			pr_err("Unsupport i2c_operation: %d\n",
@@ -400,9 +400,6 @@ static int32_t msm_actuator_init_focus(struct msm_actuator_ctrl_t *a_ctrl,
			break;
		}

		if (0 != settings[i].delay)
			msleep(settings[i].delay);

		if (rc < 0) {
			pr_err("%s:%d fail addr = 0X%X, data = 0X%X, dt = %d",
				__func__, __LINE__, settings[i].reg_addr,
+5 −5
Original line number Diff line number Diff line
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -194,8 +194,8 @@ static int read_eeprom_memory(struct msm_eeprom_ctrl_t *e_ctrl,
			e_ctrl->i2c_client.addr_type = emap[j].poll.addr_t;
			rc = e_ctrl->i2c_client.i2c_func_tbl->i2c_poll(
				&(e_ctrl->i2c_client), emap[j].poll.addr,
				emap[j].poll.data, emap[j].poll.data_t);
				msleep(emap[j].poll.delay);
				emap[j].poll.data, emap[j].poll.data_t,
				emap[j].poll.delay);
			if (rc < 0) {
				pr_err("%s: poll failed\n", __func__);
				return rc;
@@ -380,8 +380,8 @@ static int eeprom_parse_memory_map(struct msm_eeprom_ctrl_t *e_ctrl,
					&(e_ctrl->i2c_client),
					eeprom_map->mem_settings[i].reg_addr,
					eeprom_map->mem_settings[i].reg_data,
					eeprom_map->mem_settings[i].data_type);
				msleep(eeprom_map->mem_settings[i].delay);
					eeprom_map->mem_settings[i].data_type,
					eeprom_map->mem_settings[i].delay);
				if (rc < 0) {
					pr_err("%s: poll failed\n",
						__func__);
+25 −9
Original line number Diff line number Diff line
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -18,10 +18,6 @@
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
#define S_I2C_DBG(fmt, args...) pr_debug(fmt, ##args)

#define I2C_COMPARE_MATCH 0
#define I2C_COMPARE_MISMATCH 1
#define I2C_POLL_MAX_ITERATION 20

int32_t msm_camera_cci_i2c_read(struct msm_camera_i2c_client *client,
	uint32_t addr, uint16_t *data,
	enum msm_camera_i2c_data_type data_type)
@@ -384,14 +380,34 @@ static int32_t msm_camera_cci_i2c_compare(struct msm_camera_i2c_client *client,

int32_t msm_camera_cci_i2c_poll(struct msm_camera_i2c_client *client,
	uint32_t addr, uint16_t data,
	enum msm_camera_i2c_data_type data_type)
	enum msm_camera_i2c_data_type data_type, uint32_t delay_ms)
{
	int32_t rc;
	int32_t i = 0;
	S_I2C_DBG("%s: addr: 0x%x data: 0x%x dt: %d\n",
		__func__, addr, data, data_type);

	if (delay_ms > MAX_POLL_DELAY_MS) {
		pr_err("%s:%d invalid delay = %d max_delay = %d\n",
			__func__, __LINE__, delay_ms, MAX_POLL_DELAY_MS);
		return -EINVAL;
	}
	for (i = 0; i < delay_ms; i++) {
		rc = msm_camera_cci_i2c_compare(client,
			addr, data, data_type);
		if (!rc)
			return rc;
		usleep_range(1000, 1010);
	}

	/* If rc is 1 then read is successful but poll is failure */
	if (rc == 1)
		pr_err("%s:%d poll failed rc=%d(non-fatal)\n",
			__func__, __LINE__, rc);

	if (rc < 0)
		pr_err("%s:%d poll failed rc=%d\n", __func__, __LINE__, rc);

	return rc;
}

@@ -465,7 +481,7 @@ int32_t msm_camera_cci_i2c_write_conf_tbl(
			rc = msm_camera_cci_i2c_poll(client,
				reg_conf_tbl->reg_addr,
				reg_conf_tbl->reg_data,
				reg_conf_tbl->dt);
				reg_conf_tbl->dt, I2C_POLL_TIME_MS);
		} else {
			if (reg_conf_tbl->dt == 0)
				dt = data_type;
+10 −4
Original line number Diff line number Diff line
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -17,6 +17,12 @@
#include <media/v4l2-subdev.h>
#include <media/msm_cam_sensor.h>

#define I2C_POLL_TIME_MS 5
#define MAX_POLL_DELAY_MS 100

#define I2C_COMPARE_MATCH 0
#define I2C_COMPARE_MISMATCH 1

struct msm_camera_i2c_client {
	struct msm_camera_i2c_fn_t *i2c_func_tbl;
	struct i2c_client *client;
@@ -47,7 +53,7 @@ struct msm_camera_i2c_fn_t {
		enum msm_camera_i2c_data_type data_type);
	int32_t (*i2c_poll)(struct msm_camera_i2c_client *client,
		uint32_t addr, uint16_t data,
		enum msm_camera_i2c_data_type data_type);
		enum msm_camera_i2c_data_type data_type, uint32_t delay_ms);
	int32_t (*i2c_read_burst)(struct msm_camera_i2c_client *client,
		uint32_t read_byte, uint8_t *buffer, uint32_t addr,
		enum msm_camera_i2c_data_type data_type);
@@ -111,7 +117,7 @@ int32_t msm_sensor_cci_i2c_util(struct msm_camera_i2c_client *client,

int32_t msm_camera_cci_i2c_poll(struct msm_camera_i2c_client *client,
	uint32_t addr, uint16_t data,
	enum msm_camera_i2c_data_type data_type);
	enum msm_camera_i2c_data_type data_type, uint32_t delay_ms);

int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client,
	uint32_t addr, uint16_t *data,
@@ -144,6 +150,6 @@ int32_t msm_camera_qup_i2c_write_conf_tbl(

int32_t msm_camera_qup_i2c_poll(struct msm_camera_i2c_client *client,
	uint32_t addr, uint16_t data,
	enum msm_camera_i2c_data_type data_type);
	enum msm_camera_i2c_data_type data_type, uint32_t delay_ms);

#endif
+19 −12
Original line number Diff line number Diff line
/* Copyright (c) 2011, 2013-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011, 2013-2016, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -22,10 +22,6 @@
#define S_I2C_DBG(fmt, args...) do { } while (0)
#endif

#define I2C_COMPARE_MATCH 0
#define I2C_COMPARE_MISMATCH 1
#define I2C_POLL_MAX_ITERATION 20

static int32_t msm_camera_qup_i2c_rxdata(
	struct msm_camera_i2c_client *dev_client, unsigned char *rxdata,
	int data_length)
@@ -342,8 +338,8 @@ int32_t msm_camera_qup_i2c_write_table_w_microdelay(
	return rc;
}

static int32_t msm_camera_qup_i2c_compare(struct msm_camera_i2c_client *client,
	uint32_t addr, uint16_t data,
static int32_t msm_camera_qup_i2c_compare(
	struct msm_camera_i2c_client *client, uint32_t addr, uint16_t data,
	enum msm_camera_i2c_data_type data_type)
{
	int32_t rc;
@@ -400,19 +396,30 @@ static int32_t msm_camera_qup_i2c_compare(struct msm_camera_i2c_client *client,

int32_t msm_camera_qup_i2c_poll(struct msm_camera_i2c_client *client,
	uint32_t addr, uint16_t data,
	enum msm_camera_i2c_data_type data_type)
	enum msm_camera_i2c_data_type data_type, uint32_t delay_ms)
{
	int32_t rc;
	int i;
	S_I2C_DBG("%s: addr: 0x%x data: 0x%x dt: %d\n",
		__func__, addr, data, data_type);

	for (i = 0; i < I2C_POLL_MAX_ITERATION; i++) {
	if (delay_ms > MAX_POLL_DELAY_MS) {
		pr_err("%s:%d invalid delay = %d max_delay = %d\n",
			__func__, __LINE__, delay_ms, MAX_POLL_DELAY_MS);
		return -EINVAL;
	}

	for (i = 0; i < delay_ms; i++) {
		rc = msm_camera_qup_i2c_compare(client,
			addr, data, data_type);
		if (rc == 0 || rc < 0)
		if (rc < 0) {
			pr_err("%s:%d qup_i2c_compare failed rc = %d", __func__,
				__LINE__, rc);
			break;
		}
		if (rc == I2C_COMPARE_MISMATCH)
			break;
		usleep_range(10000, 11000);
		usleep_range(1000, 1010);
	}
	return rc;
}
@@ -489,7 +496,7 @@ int32_t msm_camera_qup_i2c_write_conf_tbl(
			rc = msm_camera_qup_i2c_poll(client,
				reg_conf_tbl->reg_addr,
				reg_conf_tbl->reg_data,
				reg_conf_tbl->dt);
				reg_conf_tbl->dt, I2C_POLL_TIME_MS);
		} else {
			if (reg_conf_tbl->dt == 0)
				dt = data_type;
Loading