From d67df23b0aa8740daee98386b6fe09ce0afc4ea5 Mon Sep 17 00:00:00 2001 From: Bhanu Murthy V Date: Fri, 9 Nov 2018 13:37:13 -0800 Subject: drivers: camera: Add sensor blob utilities Add utilities for sensor blob creation and writing in CCPLEX. The blob creation will be common across platorms for sensor drivers. Blob writing in CCPLEX will be used based on the RCE support on the platform. Add version in camera common and tvcf supported apis to evaluate and verify blob support in sensor drivers. Bug 2433156 Change-Id: Ie395be7d4ad959ae0efab9e72d1373fa7bd39d27 Signed-off-by: Bhanu Murthy V Reviewed-on: https://git-master.nvidia.com/r/1941462 (cherry picked from commit 187cb4926fbe68e653ba6e372b291da04605c946) Reviewed-on: https://git-master.nvidia.com/r/2006762 Reviewed-by: svc-mobile-coverity Tested-by: Ian Kaszubski Reviewed-by: Vincent Chung GVS: Gerrit_Virtual_Submit Reviewed-by: Frank Chen Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/media/platform/tegra/camera/Makefile | 2 +- .../media/platform/tegra/camera/tegracam_core.c | 3 +- .../media/platform/tegra/camera/tegracam_utils.c | 212 +++++++++++++++++++++ include/media/camera_common.h | 1 + include/media/tegracam_utils.h | 48 +++++ 5 files changed, 264 insertions(+), 2 deletions(-) create mode 100644 drivers/media/platform/tegra/camera/tegracam_utils.c create mode 100644 include/media/tegracam_utils.h diff --git a/drivers/media/platform/tegra/camera/Makefile b/drivers/media/platform/tegra/camera/Makefile index 8072676a8..a67a6a0cc 100644 --- a/drivers/media/platform/tegra/camera/Makefile +++ b/drivers/media/platform/tegra/camera/Makefile @@ -8,7 +8,7 @@ ccflags-y += -Werror obj-y += vi/ obj-y += csi/ obj-y += camera_common.o camera_gpio.o sensor_common.o camera_version_utils.o \ - tegracam_ctrls.o tegracam_core.o tegracam_v4l2.o + tegracam_ctrls.o tegracam_core.o tegracam_v4l2.o tegracam_utils.o obj-$(CONFIG_TEGRA_CAMERA_RTCPU) += capture_common.o obj-$(CONFIG_TEGRA_CAMERA_RTCPU) += isp/isp_channel.o obj-$(CONFIG_TEGRA_CAMERA_RTCPU) += isp/capture_isp.o diff --git a/drivers/media/platform/tegra/camera/tegracam_core.c b/drivers/media/platform/tegra/camera/tegracam_core.c index 5a17322ff..9df1c3ea4 100644 --- a/drivers/media/platform/tegra/camera/tegracam_core.c +++ b/drivers/media/platform/tegra/camera/tegracam_core.c @@ -22,7 +22,7 @@ /* use semantic versioning convention */ #define TEGRACAM_MAJOR_VERSION 2 #define TEGRACAM_MINOR_VERSION 0 -#define TEGRACAM_PATCH_VERSION 1 +#define TEGRACAM_PATCH_VERSION 2 u32 tegracam_version(u8 major, u8 minor, u8 patch) { @@ -133,6 +133,7 @@ int tegracam_device_register(struct tegracam_device *tc_dev) /* add version info to identify the right feature set */ tc_dev->version = tegracam_version(TEGRACAM_MAJOR_VERSION, TEGRACAM_MINOR_VERSION, TEGRACAM_PATCH_VERSION); + s_data->version = tc_dev->version; dev_info(dev, "tegracam sensor driver:%s_v%d.%d.%d\n", tc_dev->name, TEGRACAM_MAJOR_VERSION, TEGRACAM_MINOR_VERSION, TEGRACAM_PATCH_VERSION); diff --git a/drivers/media/platform/tegra/camera/tegracam_utils.c b/drivers/media/platform/tegra/camera/tegracam_utils.c new file mode 100644 index 000000000..1339addcc --- /dev/null +++ b/drivers/media/platform/tegra/camera/tegracam_utils.c @@ -0,0 +1,212 @@ +/* + * tegracam_utils - tegra camera framework utilities + * + * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include + +bool is_tvcf_supported(u32 version) +{ + /* 2.0.0 is the base tvcf version sensor driver*/ + return (version >= tegracam_version(2, 0, 0) ? true : false); +} +EXPORT_SYMBOL_GPL(is_tvcf_supported); + +void conv_u32_u8arr(u32 input, u8 *output) +{ + output[0] = (input >> 24) & 0xFF; + output[1] = (input >> 16) & 0xFF; + output[2] = (input >> 8) & 0xFF; + output[3] = input & 0xFF; +} +EXPORT_SYMBOL_GPL(conv_u32_u8arr); + +void conv_u16_u8arr(u16 input, u8 *output) +{ + output[0] = (input >> 8) & 0xFF; + output[1] = input & 0xFF; +} +EXPORT_SYMBOL_GPL(conv_u16_u8arr); + +static inline int is_valid_blob(struct sensor_blob *blob, u32 size) +{ + if (!blob) + return -EINVAL; + + if ((blob->num_cmds >= MAX_COMMANDS) || + ((blob->buf_size + size) >= MAX_BLOB_SIZE)) + return -ENOMEM; + + return 0; +} + +int prepare_write_cmd(struct sensor_blob *blob, + u32 size, u32 addr, u8 *buf) +{ + struct sensor_cmd *cmd = NULL; + int err = 0; + + err = is_valid_blob(blob, size); + if (err) + return err; + + cmd = &blob->cmds[blob->num_cmds++]; + cmd->opcode = ((SENSOR_OPCODE_WRITE << 24) | size); + cmd->addr = addr; + + memcpy(&blob->buf[blob->buf_size], buf, size); + + blob->buf_size += size; + + return 0; +} +EXPORT_SYMBOL_GPL(prepare_write_cmd); + +int prepare_read_cmd(struct sensor_blob *blob, + u32 size, u32 addr) +{ + struct sensor_cmd *cmd = NULL; + int err = 0; + + err = is_valid_blob(blob, size); + if (err) + return err; + + cmd = &blob->cmds[blob->num_cmds++]; + cmd->opcode = ((SENSOR_OPCODE_READ << 24) | size); + cmd->addr = addr; + + blob->buf_size += size; + + return 0; +} +EXPORT_SYMBOL_GPL(prepare_read_cmd); + +int prepare_sleep_cmd(struct sensor_blob *blob, u32 time_in_us) +{ + struct sensor_cmd *cmd = NULL; + int err = 0; + + err = is_valid_blob(blob, 0); + if (err) + return err; + + cmd = &blob->cmds[blob->num_cmds++]; + cmd->opcode = (SENSOR_OPCODE_SLEEP << 24) | time_in_us; + + return 0; +} +EXPORT_SYMBOL_GPL(prepare_sleep_cmd); + +int prepare_done_cmd(struct sensor_blob *blob) +{ + struct sensor_cmd *cmd = NULL; + int err = 0; + + err = is_valid_blob(blob, 0); + if (err) + return err; + + cmd = &blob->cmds[blob->num_cmds++]; + cmd->opcode = SENSOR_OPCODE_DONE; + + return 0; +} +EXPORT_SYMBOL_GPL(prepare_done_cmd); + +int convert_table_to_blob(struct sensor_blob *blob, + const struct reg_8 table[], + u16 wait_ms_addr, u16 end_addr) +{ + const struct reg_8 *next; + u16 addr; + u8 val; + int range_start = -1; + int range_count = 0; + u8 buf[16]; + + for (next = table;; next++) { + val = next->val; + addr = next->addr; + if (range_start == -1) + range_start = next->addr; + + if (range_count == 16 || + (addr != (range_start + range_count))) { + /* write opcode and size for store index*/ + prepare_write_cmd(blob, range_count, + range_start, &buf[0]); + range_start = addr; + range_count = 0; + } + + /* Done command must be added by client */ + if (addr == end_addr) + break; + + if (addr == wait_ms_addr) { + prepare_sleep_cmd(blob, (next->val * 1000)); + range_start = -1; + continue; + } + + buf[range_count++] = val; + } + + return 0; +} +EXPORT_SYMBOL_GPL(convert_table_to_blob); + +int write_sensor_blob(struct regmap *regmap, struct sensor_blob *blob) +{ + int err = 0; + int cmd_idx = 0; + int buf_index = 0; + + while (cmd_idx < blob->num_cmds) { + struct sensor_cmd *cmd = &blob->cmds[cmd_idx++]; + u32 val; + + val = cmd->opcode; + if ((val >> 24) == SENSOR_OPCODE_DONE) + break; + + if ((val >> 24) == SENSOR_OPCODE_SLEEP) { + val = val & 0x00FFFFFF; + usleep_range(val, val + 10); + continue; + } + + if ((val >> 24) == SENSOR_OPCODE_WRITE) { + int size = val & 0x00FFFFFF; + + err = regmap_bulk_write(regmap, cmd->addr, + &blob->buf[buf_index], size); + if (err) + return err; + buf_index += size; + } else { + pr_err("blob has been packaged with errors\n"); + return -EINVAL; + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(write_sensor_blob); diff --git a/include/media/camera_common.h b/include/media/camera_common.h index cf065aac6..be8f41b15 100644 --- a/include/media/camera_common.h +++ b/include/media/camera_common.h @@ -233,6 +233,7 @@ struct camera_common_data { int sensor_mode_id; bool use_sensor_mode_id; bool override_enable; + u32 version; }; struct camera_common_focuser_data; diff --git a/include/media/tegracam_utils.h b/include/media/tegracam_utils.h new file mode 100644 index 000000000..fe13a448e --- /dev/null +++ b/include/media/tegracam_utils.h @@ -0,0 +1,48 @@ +/** + * tegracam_utils.h - tegra camera framework core utilities + * + * Copyright (c) 2019, NVIDIA Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TEGRACAM_UTILS_H__ +#define __TEGRACAM_UTILS_H__ + +#include + +enum sensor_opcode { + SENSOR_OPCODE_DONE = 0, + SENSOR_OPCODE_READ = 1, + SENSOR_OPCODE_WRITE = 2, + SENSOR_OPCODE_SLEEP = 3, +}; + +int convert_table_to_blob(struct sensor_blob *pkt, + const struct reg_8 table[], + u16 wait_ms_addr, u16 end_addr); +int write_sensor_blob(struct regmap *regmap, struct sensor_blob *blob); + +bool is_tvcf_supported(u32 version); + +void conv_u32_u8arr(u32 val, u8 *buf); +void conv_u16_u8arr(u16 val, u8 *buf); + +int prepare_write_cmd(struct sensor_blob *pkt, + u32 size, u32 addr, u8 *buf); +int prepare_read_cmd(struct sensor_blob *pkt, + u32 size, u32 addr); +int prepare_sleep_cmd(struct sensor_blob *pkt, u32 time_in_us); +int prepare_done_cmd(struct sensor_blob *pkt); + +#endif -- cgit v1.2.2