Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 16 additions & 11 deletions drivers/misc/icvs/intel_cvs.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,23 @@ static int cvs_i2c_probe(struct i2c_client *i2c)
dev_err(icvs->dev, "Failed to initialize\n");
find_oem_prod_id(handle, "OPID", &icvs->oem_prod_id);
}

mdelay(FW_PREPARE_MS);
ret = cvs_find_magic_num_support(icvs);
if (ret)
goto exit;

if (icvs->magic_num_support) {
ret = cvs_get_device_cap(&icvs->cv_fw_capability);
if (ret)
goto exit;
}

ret = cvs_write_i2c(SET_HOST_IDENTIFIER, NULL, 0);
if (ret) {
dev_err(cvs->dev, "%s:set_host_identifier cmd failed", __func__);
goto exit;
}

ret = cvs_acquire_camera_sensor_internal();
if (ret) {
dev_err(cvs->dev, "%s:Acquire sensor fail", __func__);
Expand All @@ -161,16 +176,6 @@ static int cvs_i2c_probe(struct i2c_client *i2c)
__func__);
}
icvs->icvs_sensor_state = CV_SENSOR_VISION_ACQUIRED_STATE;

ret = cvs_get_device_cap(&icvs->cv_fw_capability);
if (ret)
goto exit;

ret = cvs_write_i2c(SET_HOST_IDENTIFIER, NULL, 0);
if (ret) {
dev_err(cvs->dev, "%s:set_host_identifier cmd failed", __func__);
goto exit;
}
acpi_dev_clear_dependencies(ACPI_COMPANION(icvs->dev));

exit:
Expand Down
76 changes: 54 additions & 22 deletions drivers/misc/icvs/intel_cvs_update.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ int cvs_write_i2c(u16 cmd, u8 *data, u32 len)
union cv_host_identifiers host_identifiers;

out_buff = devm_kzalloc(ctx->dev,
(cv_host_identifier_size + sizeof(cmd)),
GFP_KERNEL);
cv_host_identifier_size + sizeof(cmd), GFP_KERNEL);
if (!out_buff) {
dev_err(cvs->dev, "%s:Buffer alloc failed", __func__);
return -ENOMEM;
Expand All @@ -59,7 +58,7 @@ int cvs_write_i2c(u16 cmd, u8 *data, u32 len)
cv_host_identifier_size);

count = i2c_master_send(client, (const char *)out_buff,
sizeof(cmd) + cv_host_identifier_size);
sizeof(cmd) + cv_host_identifier_size);

if (count != cv_host_identifier_size + sizeof(cmd))
return -EIO;
Expand Down Expand Up @@ -100,19 +99,51 @@ int cvs_get_device_cap(struct cv_ver_capability *cv_fw_cap)

if (cvs_read_i2c(GET_DEV_CAPABILITY, (char *)cv_fw_cap,
sizeof(struct cv_ver_capability)) <= 0) {
dev_err(cvs->dev, "%s:Get device_capability cmd failed", __func__);
return -EINVAL;
}

dev_info(cvs->dev, "%s:Device protocol is %d.%d", __func__,
cvs->cv_fw_capability.protocol_ver_major,
cvs->cv_fw_capability.protocol_ver_minor);
dev_info(cvs->dev, "%s:Device capability is 0x%x", __func__,
cvs->cv_fw_capability.dev_capability);

if (cvs->cv_fw_capability.protocol_ver_major > 2 ||
(cvs->cv_fw_capability.protocol_ver_major == 2 &&
cvs->cv_fw_capability.protocol_ver_minor >= 2)) {
cvs->loader_cmd_size = CMD_SIZE;
}

return 0;
}

int cvs_find_magic_num_support(struct intel_cvs *ctx)
{
struct i2c_client *i2c = container_of(ctx->dev, struct i2c_client, dev);
int cnt;
u16 cmd = GET_VID_PID;
u16 cvs_cmd = cpu_to_be16(cmd);
int cmd_response;

cnt = i2c_master_send(i2c, (const char *)&cvs_cmd, sizeof(cvs_cmd));
if (cnt != sizeof(cvs_cmd)) {
dev_err(ctx->dev, "sending cmd:0x%x to device failed", cmd);
return cnt < 0 ? cnt : -EIO;
}

cnt = i2c_master_recv(i2c, (char *)&cmd_response, CVMAGICNUMSIZE);
if (cnt != CVMAGICNUMSIZE) {
dev_err(ctx->dev, "failed to read back for cmd:0x%x", cmd);
return cnt < 0 ? cnt : -EIO;
}
if (cmd_response != CVMAGICNUM) {
dev_info(ctx->dev, "magic number in dev response not supported");
dev_info(cvs->dev, "%s:Device protocol is 1.0", __func__);
cvs->magic_num_support = false;
ctx->magic_num_support = false;
} else {
dev_info(cvs->dev, "%s:Device protocol is %d.%d", __func__,
cvs->cv_fw_capability.protocol_ver_major,
cvs->cv_fw_capability.protocol_ver_minor);
dev_info(cvs->dev, "%s:Device capability is 0x%x", __func__,
cvs->cv_fw_capability.dev_capability);

if ((cvs->cv_fw_capability.protocol_ver_major > 2) ||
((cvs->cv_fw_capability.protocol_ver_major == 2) && (cvs->cv_fw_capability.protocol_ver_minor >= 2))) {
cvs->loader_cmd_size = CMD_SIZE;
}
dev_info(ctx->dev, "magic number in dev response supported");
ctx->magic_num_support = true;
}

return 0;
Expand All @@ -126,8 +157,7 @@ int cvs_wait_for_host_wake(u64 time_ms)
/* wait for HOST_WAKE signal, timeout in time_ms */
timeout = msecs_to_jiffies(time_ms);
ret = wait_event_interruptible_timeout(cvs->hostwake_event,
cvs->hostwake_event_arg == 1,
timeout);
cvs->hostwake_event_arg == 1, timeout);

if (ret <= 0) {
dev_err(cvs->dev, "%s:hostwake wait timeout", __func__);
Expand All @@ -146,7 +176,6 @@ int cvs_reset_cv_device(void)
gpiod_set_value_cansleep(cvs->rst, 0);
mdelay(GPIO_RESET_MS);
gpiod_set_value_cansleep(cvs->rst, 1);
mdelay(FW_PREPARE_MS);
return 0;
}

Expand Down Expand Up @@ -199,7 +228,7 @@ int cvs_dev_fw_dl_data(void)
// Allocate memory for the buffer
out_buf = kzalloc(buf_size, GFP_KERNEL);

if (IS_ERR_OR_NULL(out_buf)) {
if (!out_buf) {
dev_err(cvs->dev, "%s:No memory for fw_buffer packet", __func__);
return -ENOMEM;
}
Expand All @@ -223,7 +252,6 @@ int cvs_dev_fw_dl_data(void)
}

do {

if (ctx->close_fw_dl_task) {
dev_info(cvs->dev, "%s:Received close_fw_dl_task", __func__);
status = -EPERM;
Expand All @@ -235,7 +263,8 @@ int cvs_dev_fw_dl_data(void)
wmb(); /* Flush WC buffers after writing out_buf */

if (fw_state & DEVICE_DWNLD_STATE_MASK) {
if (cvs_write_i2c(FW_LOADER_DATA, out_buf, I2C_PKT_SIZE + cvs->loader_cmd_size)) {
if (cvs_write_i2c(FW_LOADER_DATA, out_buf,
I2C_PKT_SIZE + cvs->loader_cmd_size)) {
dev_err(cvs->dev, "%s:fw_loader_data failed", __func__);
fw_state = DEVICE_DWNLD_ERROR_MASK;
goto i2c_packet_loop_end;
Expand Down Expand Up @@ -386,8 +415,9 @@ int cvs_dev_fw_dl(void)
ctx->icvs_sensor_state = CV_SENSOR_RELEASED_STATE;

//wait for the host_wake
if (cvs_wait_for_host_wake(ctx->max_flashtime_ms))
dev_err(cvs->dev, "%s:Firmware flash hostwake error after reset", __func__);
if (cvs_wait_for_host_wake(WAIT_HOST_WAKE_RESET_MS))
dev_info(cvs->dev, "%s:Firmware flash hostwake error after reset",
__func__);
}

dev_info(cvs->dev, "%s:Exit with status:0x%x", __func__, status);
Expand Down Expand Up @@ -459,6 +489,8 @@ void cvs_fw_dl_thread(struct work_struct *arg)
*/
if (ctx->icvs_sensor_state != CV_SENSOR_VISION_ACQUIRED_STATE &&
!ctx->cv_suspend) {
if (cvs_write_i2c(SET_HOST_IDENTIFIER, NULL, 0))
dev_err(cvs->dev, "%s:set_host_identifier cmd failed", __func__);
if (cvs_acquire_camera_sensor_internal()) {
dev_err(cvs->dev, "%s:Acquire sensor fail", __func__);
} else {
Expand Down
1 change: 1 addition & 0 deletions drivers/misc/icvs/intel_cvs_update.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
int cvs_reset_cv_device(void);
void cvs_fw_dl_thread(struct work_struct *arg);
int cvs_get_fwver_vid_pid(void);
int cvs_find_magic_num_support(struct intel_cvs *ctx);

int cvs_acquire_camera_sensor_internal(void);
int cvs_release_camera_sensor_internal(void);
Expand Down