int altek6045_exec_cmd(const hwextisp_intf_t* i, hwcam_config_data_t *data)
{
	int rc = 0;
	u8 *in_buf = NULL, *out_buf = NULL;
	u32 opcode, dir_type, block_response, out_len, in_len;
	bool out_to_block;

	cam_notice("enter %s cmd=0x%x.", __func__, data->cmd);

	dir_type = data->cmd & EXTISP_CMD_DIR_FLAG_MASK;
	block_response = data->cmd & EXTISP_CMD_RESP_FLAG_MASK;
	out_len = in_len = (data->cmd & EXTISP_CMD_LEN_MASK)>>EXTISP_CMD_LEN_SHIT;
	opcode = (data->cmd & EXTISP_CMD_OPCODE_MASK)>>EXTISP_CMD_OPCODE_SHIT;

	out_buf = in_buf = data->u.buf;
	out_to_block = (EXTISP_BLOCK_RESPONSE_CMD == block_response)? true: false;

	/* allocate kernel buf: override out_buf out_len*/
	if (out_to_block) {
		out_len = data->ext_buf.user_buf_len;
		if (out_len > 4096) {
			cam_err("%s invalid ext_buf_len=%d", __func__, out_len);
			return -EINVAL;
		}
		out_buf = kmalloc(out_len, GFP_KERNEL);
		if (NULL == out_buf) {
			cam_err("%s kmalloc failed", __func__);
			return -ENOMEM;;
		}
	}

	if (EXTISP_INOUT_CMD == dir_type) {
		rc = misp_exec_bidir_cmd((u16)opcode, data->u.buf, in_len,
							out_to_block, out_buf, out_len);
	} else if (EXTISP_SET_CMD == dir_type) {
		rc = misp_exec_unidir_cmd((u16)opcode, true,
							out_to_block, in_buf, in_len);
	} else if (EXTISP_GET_CMD == dir_type) {
		rc = misp_exec_unidir_cmd((u16)opcode, false,
							out_to_block, out_buf, out_len);
	} else {
		cam_err("%s unkown cmd direction", __func__);
		rc = -EINVAL;
	}

	/* reclaimed kernel buf*/
	if (out_to_block) {
		if (copy_to_user(data->ext_buf.user_buf_ptr, out_buf, out_len)) {
			cam_err("%s copy to user failed", __func__);
			rc = -EFAULT;
		}
		kfree(out_buf);
	}

	return rc;
}
static ssize_t altel6045_test_pipe_store(struct device_driver *drv,
												  const char *buf, size_t count)
{
	int ret = 0, test_pipe_id = -1, index = 0;
	u8 in_buf[7], out_buf[33];
	u16 opcode = 0;
	const char *pos = buf;

	cam_info("%s enter %s", __func__, buf);

	/* input:test_pipe=0 test_pipe=1 test_pipe=2 */
	if (0 == strncmp("test_pipe", pos, strlen("test_pipe"))) {
		while (*pos) {
			if (isdigit(*pos))
				break;
			else
				pos++;
		}
	}

	if (*pos == '0' ) {
		test_pipe_id = ALTEK6045_PIPE_0;
	} else if (*pos == '1') {
		test_pipe_id = ALTEK6045_PIPE_1;
	} else if (*pos == '2') {
		test_pipe_id = ALTEK6045_PIPE_DUAL;
	} else {
		test_pipe_id = -1;
		cam_info("%s invalid argument", __func__);
		goto err;
	}

	set_test_result(test_pipe_id, ALTEK6045_PIPE_TESTING);

	/* start test mode */
	memset(in_buf, 0, sizeof(in_buf));
	if (test_pipe_id == ALTEK6045_PIPE_DUAL) {
		in_buf[0] = in_buf[2] = 1;
		in_buf[1] = in_buf[3] = 99;
	} else {
		in_buf[test_pipe_id * 2] = 1;
		in_buf[test_pipe_id * 2 + 1] = 99;
	}
	opcode = ISPCMD_CAMERA_SET_SENSORMODE;
	ret = misp_exec_unidir_cmd(opcode, true, false, in_buf, sizeof(in_buf));
	if (ret) {
		set_test_result(test_pipe_id, ALTEK6045_PIPE_TEST_CMD_ERR);
		cam_err("%s set test mode cmd failed ret:%d", __func__, ret);
		goto err;
	}

	msleep(1000);

	/* get test mode */
	opcode = ISPCMD_GET_BULK_CHIPTEST_REPORT;
	memset(out_buf, 0, 33);
	ret = misp_exec_unidir_cmd(opcode, false, false, out_buf, sizeof(out_buf));
	if (ret) {
		set_test_result(test_pipe_id, ALTEK6045_PIPE_GET_CMD_ERR);
		cam_err("%s get test result cmd failed ret:%d", __func__, ret);
		goto err;
	}

	for (index = 0; index < 33; index++) {
		if(out_buf[index] != 1) {
			set_test_result(test_pipe_id, ALTEK6045_PIPE_TEST_BAD);
			goto err;
		}
	}
	set_test_result(test_pipe_id, ALTEK6045_PIPE_TEST_DONE);

err:
	msleep(100);
	return count;
}
static ssize_t altel6045_test_pipe_store(struct device_driver *drv,
        const char *buf, size_t count)
{
    int ret = 0, test_pipe_id = -1, index = 0;
    u8 in_buf[7], out_buf[53];
    u8 sizeout = 0;
    u16 opcode = 0;
    const char *pos = buf;
    int  extisp_type = EXTISP_NULL;
    u16 sensor_id = 0;
    u8  module_id = 0;

    cam_info("%s enter %s", __func__, buf);
    extisp_type = misp_get_chipid();

    if (0 == strncmp("DBC_Begin", pos, strlen("DBC_Begin")))
    {
        misp_cmd_filter = 1;
        cam_info("%s misp set  DBC mode to on",__func__);
        return count;
    }

    if (0 == strncmp("DBC_End", pos, strlen("DBC_End")))
    {
        misp_cmd_filter = 0;
        cam_info("%s misp set  DBC mode to off",__func__);
        return count;
    }

    /* input:test_pipe=0 test_pipe=1 test_pipe=2 */
    if (0 == strncmp("test_pipe", pos, strlen("test_pipe"))) {
        while (*pos) {
            if (isdigit(*pos))
                break;
            else
                pos++;
        }
    }

    if (*pos == '0' ) {
        test_pipe_id = ALTEK6045_PIPE_0;
    } else if (*pos == '1') {
        test_pipe_id = ALTEK6045_PIPE_1;
    } else if (*pos == '2') {
        test_pipe_id = ALTEK6045_PIPE_DUAL;
    } else if (*pos == '3') {
        test_pipe_id = ALTEK6045_PIPE_3;
    } else if (*pos == '4') {
        test_pipe_id = ALTEK6045_PIPE_4;
        misp_get_module_info(1,&sensor_id,&module_id);
    } else {
        //	test_pipe_id = -1;
        cam_info("%s invalid argument", __func__);
        goto err;
    }

    set_test_result(test_pipe_id, ALTEK6045_PIPE_TESTING);

    /* start test mode */
    memset(in_buf, 0, sizeof(in_buf));
    if (test_pipe_id == ALTEK6045_PIPE_DUAL) {
        in_buf[0] = in_buf[2] = 1;
        in_buf[1] = in_buf[3] = 99;
    } else {
        if(extisp_type == EXTISP_AL6045) {
            in_buf[test_pipe_id * 2] = 1;
            in_buf[test_pipe_id * 2 + 1] = 99;
            sizeout = 33;
        } else {
            in_buf[0] = 1;
            if(test_pipe_id == ALTEK6045_PIPE_0) {
                in_buf[1]=101;
            } else if (test_pipe_id == ALTEK6045_PIPE_3) {
                /*test miniisp with sensor IMX278*/
                in_buf[1]=110;
                cam_info("%s checksum : 110  test miniisp with main sensor IMX278", __func__);
            } else if (test_pipe_id == ALTEK6045_PIPE_4) {
                /*test miniisp with sensor IMX179*/
                if (sensor_id == 0x179) {
                    in_buf[1]=112;
                    cam_info("%s checksum : 112  test miniisp with front sensor IMX179", __func__);
                } else if (sensor_id == 0x8865) {
                    in_buf[1]=113;
                    cam_info("%s checksum : 113  test miniisp with front sensor ov8865", __func__);
                } else {
                    cam_err("%s front sensor id is wrong", __func__);
                    goto err;
                }
            } else {
                in_buf[1]=100;
            }
            sizeout = 53;
        }
    }
    opcode = ISPCMD_CAMERA_SET_SENSORMODE;
    ret = misp_exec_unidir_cmd(opcode, true, false, in_buf, sizeof(in_buf));
    if (ret) {
        set_test_result(test_pipe_id, ALTEK6045_PIPE_TEST_CMD_ERR);
        cam_err("%s set test mode cmd failed ret:%d", __func__, ret);
        goto err;
    }

    msleep(1000);

    /* get test mode */
    opcode = ISPCMD_GET_BULK_CHIPTEST_REPORT;
    memset(out_buf, 0, sizeout);
    ret = misp_exec_unidir_cmd(opcode, false, false, out_buf, sizeout);
    if (ret) {
        set_test_result(test_pipe_id, ALTEK6045_PIPE_GET_CMD_ERR);
        cam_err("%s get test result cmd failed ret:%d", __func__, ret);
        goto err;
    }

    for (index = 0; index < sizeout; index++) {
        if(out_buf[index] != 1) {
            set_test_result(test_pipe_id, ALTEK6045_PIPE_TEST_BAD);
            if ((index >= MIPI_ERR_MIN) && (index <= MIPI_ERR_MAX)) {
                cam_err("%s MIPI RX checksum failed, out_buf index:%d, value:%d", __func__, index,out_buf[index]);
            } else {
                cam_err("%s ISP internal checksum failed, out_buf index:%d, value:%d", __func__, index,out_buf[index]);
            }
            goto err;
        }
    }
    set_test_result(test_pipe_id, ALTEK6045_PIPE_TEST_DONE);

err:
    msleep(100);
    return count;
}
int altek6045_exec_cmd(const hwextisp_intf_t* i, hwextisp_config_data_t *data)
{
    int rc = 0;
    u8 *in_buf = NULL, *out_buf = NULL;
    u32 opcode, dir_type, block_response, out_len, in_len, bulk_len;
    bool out_to_block, out_from_block;

    if (get_boot_into_recovery_flag()||(misp_cmd_filter==1)) {
        cam_info("%s cmd=0x%x is blocked", __func__, data->cmd);
        return 0;
    }

    if(((data->cmd & 0x0000FFFF )!= 0x2106)&&((data->cmd & 0x0000FFFF )!= 0x2105))
        cam_info("%s cmd=0x%x", __func__, data->cmd);

    dir_type = (data->cmd & EXTISP_CMD_DIR_FLAG_MASK)>>EXTISP_CMD_DIR_FLAG_SHIT;
    block_response = (data->cmd & EXTISP_CMD_RESP_FLAG_MASK)>>EXTISP_CMD_RESP_FLAG_SHIT;
    out_len = (data->cmd & EXTISP_CMD_OUT_LEN_MASK)>>EXTISP_CMD_OUT_LEN_SHIT;
    in_len = (data->cmd & EXTISP_CMD_IN_LEN_MASK)>>EXTISP_CMD_IN_LEN_SHIT;
    opcode = (data->cmd & EXTISP_CMD_OPCODE_MASK)>>EXTISP_CMD_OPCODE_SHIT;
    out_buf = in_buf = data->u.buf;
    out_to_block = (EXTISP_BLOCK_RESPONSE_CMD == block_response)? true: false;
    out_from_block = (EXTISP_BLOCK_WRITE_CMD == block_response) ? true : false;

    /* allocate kernel buf: override out_buf out_len*/
    if (out_to_block) {
        out_len = data->ext_buf.user_buf_len;
        if (out_len > 4096) {
            cam_err("%s invalid ext_buf_len=%d", __func__, out_len);
            return -EINVAL;
        }
        out_buf = kmalloc(out_len, GFP_KERNEL);
        if (NULL == out_buf) {
            cam_err("%s kmalloc failed", __func__);
            return -ENOMEM;;
        }
        memset(out_buf,0,out_len);
    }

    if(out_from_block) {
        bulk_len = data->ext_buf.user_buf_len;
        out_buf = kmalloc(bulk_len, GFP_KERNEL);
        if(copy_from_user(out_buf, data->ext_buf.user_buf_ptr, bulk_len)) {
            cam_err("%s copy from user failed", __func__);
            rc = -EFAULT;
        }
    }

    if (EXTISP_INOUT_CMD == dir_type) {
        if(out_from_block) {
            rc = misp_exec_write_block_res((u16)opcode, in_buf, in_len,
                                           out_to_block, out_buf,bulk_len, out_len);
        } else {
            rc = misp_exec_bidir_cmd((u16)opcode, data->u.buf, in_len,
                                     out_to_block, out_buf, out_len);
        }
    } else if (EXTISP_SET_CMD == dir_type) {
        if(out_from_block) {
            rc = misp_exec_write_block((u16)opcode, in_buf, in_len, out_buf, bulk_len);
        } else {
            rc = misp_exec_unidir_cmd((u16)opcode, true,
                                      out_to_block, in_buf, in_len);
        }
    } else if (EXTISP_GET_CMD == dir_type) {
        rc = misp_exec_unidir_cmd((u16)opcode, false,
                                  out_to_block, out_buf, out_len);
    } else {
        cam_err("%s unkown cmd direction", __func__);
        rc = -EINVAL;
    }

    /* reclaimed kernel buf*/
    if (out_to_block) {
        if (copy_to_user(data->ext_buf.user_buf_ptr, out_buf, out_len)) {
            cam_err("%s copy to user failed", __func__);
            rc = -EFAULT;
        }
        kfree(out_buf);
        out_buf = NULL;
    }
    if(out_from_block) {
        if(out_buf) {
            kfree(out_buf);
        }
    }
    out_buf = NULL;

    return rc;
}