Files
vi-kernel/vvcam/native/video/subdev.c
2022-11-22 15:44:44 +08:00

300 lines
8.4 KiB
C
Executable File

/*
* Copyright (c) 2021 Alibaba Group. All rights reserved.
* License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <linux/string.h>
#include "video.h"
#include "video_ioctl.h"
#include "subdev.h"
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(arr) ( sizeof(arr) / sizeof((arr)[0]) )
#endif
static void dump_dts_frame_cfg(subdev_dts_frame_cfg_t *frame_cfg)
{
video_info(">>>> dump_dts_frame_cfg begin >>>>\n");
video_info("\t idx = %u\n", frame_cfg->idx);
video_info("\t name = %s\n", frame_cfg->output_name);
video_info("\t max_width = %u\n", frame_cfg->max_width);
video_info("\t max_height = %u\n", frame_cfg->max_height);
video_info("\t bit_per_pixel = %d\n", frame_cfg->bit_per_pixel);
video_info("\t frame_count = %u\n", frame_cfg->frame_count);
video_info("<<<< dump_dts_frame_cfg end <<<<\n");
}
static void init_dts_frame_cfg(subdev_dts_frame_cfg_t *frame_cfg)
{
if (frame_cfg == NULL) {
video_err("frame_cfg is NULL\n");
return;
}
frame_cfg->idx = -1;
frame_cfg->max_width = 0;
frame_cfg->max_height = 0;
frame_cfg->bit_per_pixel = 12;
frame_cfg->frame_count = 2;
strcpy(frame_cfg->output_name, "unknown");
}
static int subdev_get_dts_frame_cfg(struct fwnode_handle *node, subdev_dts_frame_cfg_t *frame_cfg)
{
if (frame_cfg == NULL) {
video_err("frame_cfg is NULL\n");
return -1;
}
fwnode_property_read_u32_array(node, "max_width", &frame_cfg->max_width, 1);
fwnode_property_read_u32_array(node, "max_height", &frame_cfg->max_height, 1);
fwnode_property_read_u32_array(node, "bit_per_pixel", &frame_cfg->bit_per_pixel, 1);
fwnode_property_read_u32_array(node, "frame_count", &frame_cfg->frame_count, 1);
return 0;
}
static int sensor_press_dts(struct fwnode_handle *node, sub_dev_info_t *subdev)
{
//int ret = 0;
//const char *path;
/*
ret = fwnode_property_read_string(node, "path_type", &path);
if (ret != 0) {
video_err("sensor dts press error!!!!!, %s, %d\n", __func__, __LINE__);
goto error;
}
*/
int ret = 0;
uint32_t csi_idx, flash_led_idx, mode_idx;
ret = fwnode_property_read_u32_array(node, "csi_idx", &csi_idx, 1);
if(ret != 0) {
return -1;
}
ret = fwnode_property_read_u32_array(node, "flash_led_idx", &flash_led_idx, 1);
if(ret != 0) {
flash_led_idx = -1;
}
ret = fwnode_property_read_u32_array(node, "mode_idx", &mode_idx, 1);
if(ret != 0) {
mode_idx = -1;
}
video_info("flash_led idx is %u\n", flash_led_idx);
subdev->param[0] = (char)csi_idx;
subdev->param[1] = fwnode_property_read_bool(node, "skip_init");
subdev->param[2] = (char)flash_led_idx;
subdev->param[3] = (char)mode_idx;
video_info("subdev->param[0] is %d\n", subdev->param[0]);
video_info("subdev->param[2] is %d\n", subdev->param[2]);
video_info("subdev->param[3] is %d\n", subdev->param[3]);
subdev->param_size = 3;
return 0;
}
static int vipre_press_dts(struct fwnode_handle *node, sub_dev_info_t *subdev)
{
//int ret = 0;
//const char *path;
vipre_ipi_dts_arg_t param;
param.dma_mode = 111;
/*
ret = fwnode_property_read_string(node, "path_type", &path);
if (ret != 0) {
video_err("sensor dts press error!!!!!, %s, %d\n", __func__, __LINE__);
goto error;
}
*/
memcpy(subdev->param, &param, sizeof(vipre_ipi_dts_arg_t));
subdev->param_size = sizeof(vipre_ipi_dts_arg_t);
return 0;
}
static int isp_press_dts(struct fwnode_handle *node, sub_dev_info_t *subdev)
{
int ret = 0;
int idx;
const char *path;
isp_dts_arg_t param;
struct fwnode_handle *child;
subdev_dts_frame_cfg_t *dts_frame_cfg = &(param.dts_path_frame_cfg);
init_dts_frame_cfg(dts_frame_cfg);
child = fwnode_get_named_child_node(node, "output");
if (child == NULL) {
subdev->param_size = 0;
return 0; // return with all default values
}
ret = subdev_get_dts_frame_cfg(child, dts_frame_cfg);
if (ret == 0) {
fwnode_property_read_u32_array(node, "idx", &idx, 1);
dts_frame_cfg->idx = idx;
fwnode_property_read_string(node, "path_type", &path);
snprintf(dts_frame_cfg->output_name, sizeof(dts_frame_cfg->output_name), "isp%d:%s", idx, path);
dump_dts_frame_cfg(dts_frame_cfg);
}
else {
video_err("%s, subdev_get_dts_frame_cfg() failed, ret=%d\n", __func__, ret);
subdev->param_size = 0;
return -1;
}
memcpy(subdev->param, &param, sizeof(subdev_dts_frame_cfg_t));
subdev->param_size = sizeof(isp_dts_arg_t);
return 0;
}
static int ry_press_dts(struct fwnode_handle *node, sub_dev_info_t *subdev)
{
int ret = 0;
int idx;
const char *path;
ry_dts_arg_t param;
struct fwnode_handle *child;
subdev_dts_frame_cfg_t *dts_frame_cfg = &(param.dts_path_frame_cfg);
init_dts_frame_cfg(dts_frame_cfg);
child = fwnode_get_named_child_node(node, "output");
if (child == NULL) {
subdev->param_size = 0;
return 0; // return with all default values
}
ret = subdev_get_dts_frame_cfg(child, dts_frame_cfg);
if (ret == 0) {
fwnode_property_read_u32_array(node, "idx", &idx, 1);
dts_frame_cfg->idx = idx;
fwnode_property_read_string(node, "path_type", &path);
snprintf(dts_frame_cfg->output_name, sizeof(dts_frame_cfg->output_name), "ry%d:%s", idx, path);
dump_dts_frame_cfg(dts_frame_cfg);
}
else {
video_err("%s, subdev_get_dts_frame_cfg() failed, ret=%d\n", __func__, ret);
subdev->param_size = 0;
return -1;
}
memcpy(subdev->param, &param, sizeof(subdev_dts_frame_cfg_t));
subdev->param_size = sizeof(ry_dts_arg_t);
return 0;
}
static int dw_parse_dts(struct fwnode_handle *node, sub_dev_info_t *subdev)
{
int idx;
const char *path;
int dw_dst_depth;
dw_dts_arg_t param;
dw_dst_depth = 2; // init
fwnode_property_read_u32_array(node, "idx", &idx, 1);
fwnode_property_read_string(node, "path_type", &path);
fwnode_property_read_u32_array(node, "dw_dst_depth", &dw_dst_depth, 1);
param.dw_dst_depth = dw_dst_depth;
video_info(">>>> dump dw_dts_arg_t begin >>>>\n");
video_info("\t idx = %d\n", idx);
video_info("\t path_type = %s\n", path);
video_info("\t dw_dst_depth = %d\n", dw_dst_depth);
video_info("<<<< dump dw_dts_arg_t end <<<<\n");
memcpy(subdev->param, &param, sizeof(dw_dts_arg_t));
subdev->param_size = sizeof(dw_dts_arg_t);
return 0;
}
static int dsp_press_dts(struct fwnode_handle *node, sub_dev_info_t *subdev)
{
int ret = 0;
int idx;
const char *path;
dsp_dts_arg_t param;
struct fwnode_handle *child;
subdev_dts_frame_cfg_t *dts_frame_cfg = &(param.dts_path_frame_cfg);
init_dts_frame_cfg(dts_frame_cfg);
child = fwnode_get_named_child_node(node, "output");
if (child == NULL) {
subdev->param_size = 0;
return 0; // return with all default values
}
ret = subdev_get_dts_frame_cfg(child, dts_frame_cfg);
if (ret == 0) {
fwnode_property_read_u32_array(node, "idx", &idx, 1);
dts_frame_cfg->idx = idx;
fwnode_property_read_string(node, "path_type", &path);
snprintf(dts_frame_cfg->output_name, sizeof(dts_frame_cfg->output_name), "dsp%d:%s", idx, path);
dump_dts_frame_cfg(dts_frame_cfg);
}
else {
video_err("%s, subdev_get_dts_frame_cfg() failed, ret=%d\n", __func__, ret);
subdev->param_size = 0;
return -1;
}
memcpy(subdev->param, &param, sizeof(dsp_dts_arg_t));
subdev->param_size = sizeof(dsp_dts_arg_t);
return 0;
}
static subdev_dts_press_t subdev_dts_press[] = {
{.subdev_name = "vivcam", .press = sensor_press_dts},
{.subdev_name = "vipre", .press = vipre_press_dts},
{.subdev_name = "isp", .press = isp_press_dts},
{.subdev_name = "ry", .press = ry_press_dts},
{.subdev_name = "dw", .press = dw_parse_dts},
{.subdev_name = "dsp", .press = dsp_press_dts},
};
int video_subdev_press_dts(struct fwnode_handle *node, sub_dev_info_t *subdev)
{
int i = 0;
for (i = 0; i < sizeof(subdev_dts_press) / sizeof(subdev_dts_press[0]); i++) {
if (strcmp(subdev_dts_press[i].subdev_name, subdev->name) == 0) {
return subdev_dts_press[i].press(node, subdev);
}
}
return -1;
}