解决 gst-launch-1.0 指令死机的问题

This commit is contained in:
hehaoyang 2024-01-08 06:52:00 +00:00
parent c2fbbc1566
commit 52cb12348b
2 changed files with 110 additions and 58 deletions

168
kernel/drivers/media/i2c/chipup/xs9922.c Normal file → Executable file
View File

@ -1,12 +1,3 @@
// SPDX-License-Identifier: GPL-2.0
/*
* xs9922 driver
*
* Copyright (C) 2021 Rockchip Electronics Co., Ltd.
*
* V0.0X01.0X00 first version.
*/
#define DEBUG #define DEBUG
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/device.h> #include <linux/device.h>
@ -67,6 +58,15 @@
#define XS9922_SET_FMT \ #define XS9922_SET_FMT \
_IOR('V', BASE_VIDIOC_PRIVATE + 32, struct v4l2_subdev_format ) _IOR('V', BASE_VIDIOC_PRIVATE + 32, struct v4l2_subdev_format )
#define XS9922_SET_FMT_A \
_IOR('V', BASE_VIDIOC_PRIVATE + 31, struct v4l2_subdev_format )
#define XS9922_SET_FMT_B \
_IOR('V', BASE_VIDIOC_PRIVATE + 30, struct v4l2_subdev_format )
#define XS9922_SET_FMT_END \
_IOR('V', 0, struct v4l2_subdev_format )
enum xs9922_chip_stage { enum xs9922_chip_stage {
STAGE_MIDDLE, STAGE_MIDDLE,
STAGE_LAST, STAGE_LAST,
@ -136,6 +136,10 @@ struct xs9922 {
struct v4l2_ctrl *link_freq; struct v4l2_ctrl *link_freq;
struct mutex mutex; struct mutex mutex;
bool power_on; bool power_on;
bool power_on_first;
bool power_on_sec;
bool power_on_third;
bool power_on_four;
struct xs9922_mode cur_mode; struct xs9922_mode cur_mode;
u32 module_index; u32 module_index;
@ -149,6 +153,11 @@ struct xs9922 {
bool lost_video_status; bool lost_video_status;
#if (!__CLOSE_SENSOR__) #if (!__CLOSE_SENSOR__)
struct delayed_work delay_init; struct delayed_work delay_init;
struct delayed_work delay_init_first;
struct delayed_work delay_init_sec;
struct delayed_work delay_init_third;
struct delayed_work delay_init_four;
int delayed_time;
#endif #endif
int chip_stage; int chip_stage;
@ -386,23 +395,26 @@ void switch_mode(struct xs9922 *xs9922)
int ret = 0; int ret = 0;
struct i2c_client *client = xs9922->client; struct i2c_client *client = xs9922->client;
dev_dbg(&client->dev, "%s IN --->>>\n", __func__); dev_err(&client->dev, "%s IN --->>>\n", __func__);
xs9922_write_array(client, xs9922->cur_mode.global_reg_list); xs9922_write_array(client, xs9922->cur_mode.global_reg_list);
ret = xs9922_write_array(client, xs9922->cur_mode.reg_list); ret = xs9922_write_array(client, xs9922->cur_mode.reg_list);
if (ret) if (ret)
{ {
dev_dbg(&client->dev, "%s write xs9922 register array error!\n", __func__); dev_err(&client->dev, "%s write xs9922 register array error!\n", __func__);
} }
} }
#if (!__CLOSE_SENSOR__) #if (!__CLOSE_SENSOR__)
static void __maybe_unused __xs9922_init(struct work_struct *work) static void __maybe_unused __xs9922_init(struct work_struct *work)
{ {
struct xs9922 *xs9922 = container_of(work, struct xs9922, delay_init.work); struct delayed_work *dwork = to_delayed_work(work);
struct xs9922 *xs9922 = container_of(dwork, struct xs9922,
delay_init);
switch_mode(xs9922); switch_mode(xs9922);
} }
#endif #endif
static int xs9922_get_reso_dist(const struct xs9922_mode *mode, static int xs9922_get_reso_dist(const struct xs9922_mode *mode,
@ -573,6 +585,19 @@ static int xs9922_enum_frame_interval(struct v4l2_subdev *sd,
return 0; return 0;
} }
static int xs9922_g_frame_interval(struct v4l2_subdev *sd,
struct v4l2_subdev_frame_interval *fi)
{
struct xs9922 *xs9922 = to_xs9922(sd);
const struct xs9922_mode *mode = &xs9922->cur_mode;
mutex_lock(&xs9922->mutex);
fi->interval = mode->max_fps;
mutex_unlock(&xs9922->mutex);
return 0;
}
static int xs9922_g_mbus_config(struct v4l2_subdev *sd, static int xs9922_g_mbus_config(struct v4l2_subdev *sd,
struct v4l2_mbus_config *cfg) struct v4l2_mbus_config *cfg)
{ {
@ -580,7 +605,7 @@ static int xs9922_g_mbus_config(struct v4l2_subdev *sd,
struct i2c_client *client = xs9922->client; struct i2c_client *client = xs9922->client;
const struct xs9922_mode *mode = &xs9922->cur_mode; const struct xs9922_mode *mode = &xs9922->cur_mode;
dev_dbg(&client->dev, "mode->lanes = %d\n", mode->lanes); dev_dbg(&client->dev, "chapin mode->lanes = %d\n", mode->lanes);
cfg->flags = V4L2_MBUS_CSI2_4_LANE | cfg->flags = V4L2_MBUS_CSI2_4_LANE |
V4L2_MBUS_CSI2_CONTINUOUS_CLOCK | V4L2_MBUS_CSI2_CONTINUOUS_CLOCK |
@ -625,21 +650,11 @@ static __maybe_unused int xs9922_auto_detect_hotplug(struct xs9922 *xs9922)
xs9922_read_reg(client, 0x0e10, XS9922_REG_VALUE_08BIT, &tmp9); xs9922_read_reg(client, 0x0e10, XS9922_REG_VALUE_08BIT, &tmp9);
xs9922_read_reg(client, 0x0e08, XS9922_REG_VALUE_08BIT, &tmp10); xs9922_read_reg(client, 0x0e08, XS9922_REG_VALUE_08BIT, &tmp10);
dev_dbg(&xs9922->client->dev, "%s: auto detect: %d\n", __func__,
dev_err(&xs9922->client->dev, "%s: auto detect: %d\n", __func__,
(val0 & 0x01) | (val1 & 0x01) << 1 | (val2 & 0x01) << 2 | (val3 & 0x01) << 3); (val0 & 0x01) | (val1 & 0x01) << 1 | (val2 & 0x01) << 2 | (val3 & 0x01) << 3);
dev_err(&xs9922->client->dev, "%s: ch0: %x , ch1: %x , ch2: %x ch3: %x\n", __func__, // /dev_dbg(&xs9922->client->dev, "Ch0 is %s\n", (val0 & 0x01) ? "Online ": "Offline");
val0, val1, val2,val3 ); // /dev_dbg(&xs9922->client->dev, "Ch1 is %s\n", (val1 & 0x01) ? "Online ": "Offline");
dev_err(&xs9922->client->dev, "%s: 0x0803: %x , 0x1803: %x , 0x2803: %x 0x0805: %x, 0x1805:%x, 0x2805:%x, 0x4200:%x 0x4210:%x 0x4220:%x\n", __func__,
tmp0, tmp1, tmp2,tmp3, tmp4, tmp5, tmp6,tmp7,tmp8 );
dev_err(&xs9922->client->dev, "%s: 0x0e10:%x 0x0e08:%x", __func__, tmp9, tmp10);
//dev_err(&xs9922->client->dev, "Ch0 is %s\n", (val0 & 0x01) ? "Online ": "Offline");
//dev_err(&xs9922->client->dev, "Ch1 is %s\n", (val1 & 0x01) ? "Online ": "Offline");
// /dev_dbg(&xs9922->client->dev, "Ch2 is %s\n", (val2 & 0x01) ? "Online ": "Offline"); // /dev_dbg(&xs9922->client->dev, "Ch2 is %s\n", (val2 & 0x01) ? "Online ": "Offline");
// /dev_dbg(&xs9922->client->dev, "Ch3 is %s\n", (val3 & 0x01) ? "Online ": "Offline"); // /dev_dbg(&xs9922->client->dev, "Ch3 is %s\n", (val3 & 0x01) ? "Online ": "Offline");
@ -691,26 +706,38 @@ static long xs9922_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
struct xs9922 *xs9922 = to_xs9922(sd); struct xs9922 *xs9922 = to_xs9922(sd);
long ret = 0; long ret = 0;
u32 stream = 0; u32 stream = 0;
dev_err(&xs9922->client->dev, "%s IN --->>> cmd:0x%x\n", __func__, cmd); //dev_err(&xs9922->client->dev, "%s IN --->>> cmd:0x%x set_fmt = 0x%x quick_stream = 0x%x\n", __func__, cmd, (int) XS9922_SET_FMT, (int) RKMODULE_SET_QUICK_STREAM);
//xs9922_auto_detect_hotplug(xs9922); //dev_err(&xs9922->client->dev, "%s IN --->>> cmd:0x%x set_fmt = 0x%x quick_stream = 0x%x A = 0x%x B = 0x%x E = 0x%x format size = 0x%x\n", __func__, cmd, (int) XS9922_SET_FMT, (int) RKMODULE_SET_QUICK_STREAM, (int) XS9922_SET_FMT_A,(int) XS9922_SET_FMT_B, (int) XS9922_SET_FMT_END, (int) sizeof(struct v4l2_subdev_format));
if(cmd == 0xc00456e1) { if(cmd == 0xc00456e1) {
xs9922->power_on = 0; xs9922->power_on = 0;
dev_err(&xs9922->client->dev, "zwt ene\n"); if ((*(int *)arg) == 0)
xs9922->power_on_first = 0;
else if ((*(int *)arg) == 1)
xs9922->power_on_sec = 0;
else if ((*(int *)arg) == 2)
xs9922->power_on_third = 0;
else if ((*(int *)arg) == 3)
xs9922->power_on_four = 0;
dev_err(&xs9922->client->dev, "zwt ene %d\n", (*(int *)arg));
} }
switch (cmd) { switch (cmd) {
case RKMODULE_GET_MODULE_INFO: case RKMODULE_GET_MODULE_INFO:
dev_err(&xs9922->client->dev, "get module info");
xs9922_get_module_inf(xs9922, (struct rkmodule_inf *)arg); xs9922_get_module_inf(xs9922, (struct rkmodule_inf *)arg);
dev_err(&xs9922->client->dev, "module info\n"); dev_err(&xs9922->client->dev, "module info\n");
break; break;
case RKMODULE_GET_VC_HOTPLUG_INFO: case RKMODULE_GET_VC_HOTPLUG_INFO:
dev_err(&xs9922->client->dev, "vc hotplug info");
xs9922_get_vc_hotplug_inf(xs9922, (struct rkmodule_vc_hotplug_info *)arg); xs9922_get_vc_hotplug_inf(xs9922, (struct rkmodule_vc_hotplug_info *)arg);
dev_err(&xs9922->client->dev, "[chad]Get VC Hotplug info --->>> detect status: %d\n",xs9922->detect_status); dev_err(&xs9922->client->dev, "[chad]Get VC Hotplug info --->>> detect status: %d\n",xs9922->detect_status);
break; break;
case RKMODULE_GET_VICAP_RST_INFO: case RKMODULE_GET_VICAP_RST_INFO:
dev_err(&xs9922->client->dev, "vicap rst info");
xs9922_get_vicap_rst_inf(xs9922, (struct rkmodule_vicap_reset_info *)arg); xs9922_get_vicap_rst_inf(xs9922, (struct rkmodule_vicap_reset_info *)arg);
dev_err(&xs9922->client->dev, "[chad] Get vicap reset info --->>> is_reset : %d\n", xs9922->is_reset); dev_err(&xs9922->client->dev, "[chad] Get vicap reset info --->>> is_reset : %d\n", xs9922->is_reset);
break; break;
@ -721,18 +748,19 @@ static long xs9922_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
break; break;
case RKMODULE_GET_START_STREAM_SEQ: case RKMODULE_GET_START_STREAM_SEQ:
dev_err(&xs9922->client->dev, "stream seq");
*(int *)arg = RKMODULE_START_STREAM_FRONT; *(int *)arg = RKMODULE_START_STREAM_FRONT;
break; break;
case XS9922_SET_FMT: case XS9922_SET_FMT:
{ {
const struct xs9922_mode *mode; const struct xs9922_mode *mode;
mode = xs9922_find_best_fit(xs9922, (struct v4l2_subdev_format *) arg); mode = xs9922_find_best_fit(xs9922, (struct v4l2_subdev_format *) arg);
memcpy(&xs9922->cur_mode, mode, sizeof(struct xs9922_mode)); memcpy(&xs9922->cur_mode, mode, sizeof(struct xs9922_mode));
dev_err(&xs9922->client->dev, "xs9922_ioctl!\n"); dev_err(&xs9922->client->dev, "xs9922_ioctl!\n");
#if (!__CLOSE_SENSOR__) #if (!__CLOSE_SENSOR__)
switch_mode(xs9922); switch_mode(xs9922);
#endif #endif
} }
break; break;
#if 1 #if 1
@ -787,6 +815,7 @@ static long xs9922_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
#endif #endif
default: default:
//dev_err(&xs9922->client->dev, "chapin defalut cmd");
ret = -ENOTTY; ret = -ENOTTY;
break; break;
} }
@ -1049,6 +1078,8 @@ static int xs9922_stream(struct v4l2_subdev *sd, int on)
if (xs9922->streaming == on) if (xs9922->streaming == on)
goto unlock; goto unlock;
dev_dbg(&client->dev, "chapin xs9922_stream call");
if (on) { if (on) {
__xs9922_start_stream(xs9922); __xs9922_start_stream(xs9922);
} else { } else {
@ -1079,25 +1110,41 @@ static int xs9922_power(struct v4l2_subdev *sd, int on)
if (xs9922->power_on == !!on) if (xs9922->power_on == !!on)
goto exit; goto exit;
dev_dbg(&client->dev, "%s: on %d\n", __func__, on);
if (on) { if (on) {
ret = pm_runtime_get_sync(&client->dev); ret = pm_runtime_get_sync(&client->dev);
if (ret < 0) { if (ret < 0) {
pm_runtime_put_noidle(&client->dev); pm_runtime_put_noidle(&client->dev);
goto exit; goto exit;
} }
#if (!__CLOSE_SENSOR__) #if (!__CLOSE_SENSOR__)
dev_dbg(&client->dev, "%s: >>>>>> global reg list and module reg list download...\n", __func__); if (xs9922->power_on_first == 0) {
INIT_DELAYED_WORK(&xs9922->delay_init, __xs9922_init); dev_err(&client->dev, "%s: >>>>>> global reg list and module reg list download...\n", __func__);
schedule_delayed_work(&xs9922->delay_init, msecs_to_jiffies(0)); INIT_DELAYED_WORK(&xs9922->delay_init, __xs9922_init);
schedule_delayed_work(&xs9922->delay_init, msecs_to_jiffies(0));
xs9922->power_on_first = 1;
dev_err(&client->dev, "%s: >>>>>> global reg list and module reg list download OK!\n", __func__);
}else if (xs9922->power_on_sec == 0) {
//dev_err(&client->dev, "%s: >>>>>> global reg list and module reg list download...\n", __func__);
//INIT_DELAYED_WORK(&xs9922->delay_init_sec, __xs9922_init_sec);
//schedule_delayed_work(&xs9922->delay_init_sec, msecs_to_jiffies(0));
//dev_err(&client->dev, "%s: >>>>>> global reg list and module reg list download OK!\n", __func__);
}else if (xs9922->power_on_third == 0) {
//dev_err(&client->dev, "%s: >>>>>> global reg list and module reg list download...\n", __func__);
//INIT_DELAYED_WORK(&xs9922->delay_init_sec, __xs9922_init_sec);
//schedule_delayed_work(&xs9922->delay_init_sec, msecs_to_jiffies(1));
//INIT_DELAYED_WORK(&xs9922->delay_init_third, __xs9922_init_third);
//schedule_delayed_work(&xs9922->delay_init_third, msecs_to_jiffies(0));
//dev_err(&client->dev, "%s: >>>>>> global reg list and module reg list download OK!\n", __func__);
}else if (xs9922->power_on_four == 0) {
//dev_err(&client->dev, "%s: >>>>>> global reg list and module reg list download...\n", __func__);
//INIT_DELAYED_WORK(&xs9922->delay_init_four, __xs9922_init_four);
//schedule_delayed_work(&xs9922->delay_init_four, msecs_to_jiffies(1));
//dev_err(&client->dev, "%s: >>>>>> global reg list and module reg list download OK!\n", __func__);
}
dev_dbg(&client->dev, "%s: >>>>>> global reg list and module reg list download OK!\n", __func__); if (!xs9922_reg_config) {
xs9922_reg_config = true;
if (!xs9922_reg_config) { }
xs9922_reg_config = true;
}
#endif #endif
xs9922->power_on = true; xs9922->power_on = true;
} else { } else {
@ -1120,7 +1167,7 @@ static int __xs9922_power_on(struct xs9922 *xs9922)
struct device *dev = &xs9922->client->dev; struct device *dev = &xs9922->client->dev;
dev_dbg(dev, "%s\n", __func__); dev_dbg(dev, "%s\n", __func__);
printk("__xs9922_power_on\n"); printk("__xs9922_power_on xs9922->power_on = %d\n", xs9922->power_on);
#if (!__CLOSE_SENSOR__) #if (!__CLOSE_SENSOR__)
if (xs9922->power_on ) return 0; if (xs9922->power_on ) return 0;
#endif #endif
@ -1178,9 +1225,9 @@ err_clk:
static void __xs9922_power_off(struct xs9922 *xs9922) static void __xs9922_power_off(struct xs9922 *xs9922)
{ {
struct device *dev = &xs9922->client->dev; struct device *dev = &xs9922->client->dev;
printk("__xs9922_power_off\n"); pr_err("__xs9922_power_off called");
#if __CLOSE_SENSOR__ #if __CLOSE_SENSOR__ //modify by chapin
int ret; int ret;
if (!IS_ERR(xs9922->reset_gpio)) if (!IS_ERR(xs9922->reset_gpio))
@ -1329,7 +1376,7 @@ static int xs9922_runtime_suspend(struct device *dev)
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
struct v4l2_subdev *sd = i2c_get_clientdata(client); struct v4l2_subdev *sd = i2c_get_clientdata(client);
struct xs9922 *xs9922 = to_xs9922(sd); struct xs9922 *xs9922 = to_xs9922(sd);
dev_dbg(&client->dev, "%s \n",__func__); dev_err(&client->dev, "%s \n",__func__);
__xs9922_power_off(xs9922); __xs9922_power_off(xs9922);
@ -1355,7 +1402,9 @@ static int xs9922_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
try_fmt->code = def_mode->bus_fmt; try_fmt->code = def_mode->bus_fmt;
try_fmt->field = V4L2_FIELD_NONE; try_fmt->field = V4L2_FIELD_NONE;
printk("[ma] %s:%d width:%d height = %d\n", __func__, __LINE__, def_mode->width,def_mode->height); xs9922->delayed_time = 0;
xs9922->power_on = 0;
pr_err("[ma] %s:%d width:%d height = %d xs9922->delayed_time = %d\n", __func__, __LINE__, def_mode->width,def_mode->height, xs9922->delayed_time);
mutex_unlock(&xs9922->mutex); mutex_unlock(&xs9922->mutex);
/* No crop or compose */ /* No crop or compose */
@ -1372,7 +1421,8 @@ static const struct v4l2_subdev_internal_ops xs9922_internal_ops = {
static const struct v4l2_subdev_video_ops xs9922_video_ops = { static const struct v4l2_subdev_video_ops xs9922_video_ops = {
.s_stream = xs9922_stream, .s_stream = xs9922_stream,
.g_mbus_config = xs9922_g_mbus_config, .g_frame_interval = xs9922_g_frame_interval,
.g_mbus_config = xs9922_g_mbus_config,
}; };
static const struct v4l2_subdev_pad_ops xs9922_subdev_pad_ops = { static const struct v4l2_subdev_pad_ops xs9922_subdev_pad_ops = {
@ -1994,6 +2044,8 @@ static int xs9922_remove(struct i2c_client *client)
#if defined(CONFIG_MEDIA_CONTROLLER) #if defined(CONFIG_MEDIA_CONTROLLER)
media_entity_cleanup(&sd->entity); media_entity_cleanup(&sd->entity);
#endif #endif
pr_err("xs9922_remove called");
cancel_delayed_work(&xs9922->delay_init);
v4l2_ctrl_handler_free(&xs9922->ctrl_handler); v4l2_ctrl_handler_free(&xs9922->ctrl_handler);
mutex_destroy(&xs9922->mutex); mutex_destroy(&xs9922->mutex);
@ -2028,8 +2080,8 @@ static const struct i2c_device_id xs9922_match_id[] = {
static struct i2c_driver xs9922_i2c_driver = { static struct i2c_driver xs9922_i2c_driver = {
.driver = { .driver = {
.name = XS9922_NAME, .name = XS9922_NAME,
#if __CLOSE_SENSOR__ #if __CLOSE_SENSOR__
.pm = &xs9922_pm_ops, .pm = &xs9922_pm_ops,
#endif #endif
.of_match_table = of_match_ptr(xs9922_of_match), .of_match_table = of_match_ptr(xs9922_of_match),
}, },

0
kernel/drivers/media/i2c/chipup/xs9922_reg_cfg.h Normal file → Executable file
View File