mirror of
https://github.com/thead-yocto-mirror/vi-kernel
synced 2026-06-21 17:02:34 +02:00
300 lines
8.4 KiB
C
Executable File
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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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, ¶m, 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;
|
|
}
|