解决 gst-launch-1.0 指令死机的问题
This commit is contained in:
parent
c2fbbc1566
commit
52cb12348b
132
kernel/drivers/media/i2c/chipup/xs9922.c
Normal file → Executable file
132
kernel/drivers/media/i2c/chipup/xs9922.c
Normal file → Executable 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
|
||||
#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
|
@ -67,6 +58,15 @@
|
|||
#define XS9922_SET_FMT \
|
||||
_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 {
|
||||
STAGE_MIDDLE,
|
||||
STAGE_LAST,
|
||||
|
@ -136,6 +136,10 @@ struct xs9922 {
|
|||
struct v4l2_ctrl *link_freq;
|
||||
struct mutex mutex;
|
||||
bool power_on;
|
||||
bool power_on_first;
|
||||
bool power_on_sec;
|
||||
bool power_on_third;
|
||||
bool power_on_four;
|
||||
struct xs9922_mode cur_mode;
|
||||
|
||||
u32 module_index;
|
||||
|
@ -149,6 +153,11 @@ struct xs9922 {
|
|||
bool lost_video_status;
|
||||
#if (!__CLOSE_SENSOR__)
|
||||
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
|
||||
|
||||
int chip_stage;
|
||||
|
@ -386,23 +395,26 @@ void switch_mode(struct xs9922 *xs9922)
|
|||
int ret = 0;
|
||||
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);
|
||||
|
||||
ret = xs9922_write_array(client, xs9922->cur_mode.reg_list);
|
||||
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__)
|
||||
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);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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,
|
||||
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;
|
||||
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 |
|
||||
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, 0x0e08, XS9922_REG_VALUE_08BIT, &tmp10);
|
||||
|
||||
dev_err(&xs9922->client->dev, "%s: auto detect: %d\n", __func__,
|
||||
dev_dbg(&xs9922->client->dev, "%s: auto detect: %d\n", __func__,
|
||||
(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__,
|
||||
val0, val1, val2,val3 );
|
||||
|
||||
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, "Ch0 is %s\n", (val0 & 0x01) ? "Online ": "Offline");
|
||||
// /dev_dbg(&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, "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);
|
||||
long ret = 0;
|
||||
u32 stream = 0;
|
||||
dev_err(&xs9922->client->dev, "%s IN --->>> cmd:0x%x\n", __func__, cmd);
|
||||
//xs9922_auto_detect_hotplug(xs9922);
|
||||
//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);
|
||||
//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) {
|
||||
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) {
|
||||
case RKMODULE_GET_MODULE_INFO:
|
||||
dev_err(&xs9922->client->dev, "get module info");
|
||||
xs9922_get_module_inf(xs9922, (struct rkmodule_inf *)arg);
|
||||
dev_err(&xs9922->client->dev, "module info\n");
|
||||
break;
|
||||
|
||||
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);
|
||||
dev_err(&xs9922->client->dev, "[chad]Get VC Hotplug info --->>> detect status: %d\n",xs9922->detect_status);
|
||||
break;
|
||||
|
||||
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);
|
||||
dev_err(&xs9922->client->dev, "[chad] Get vicap reset info --->>> is_reset : %d\n", xs9922->is_reset);
|
||||
break;
|
||||
|
@ -721,6 +748,7 @@ static long xs9922_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
|||
break;
|
||||
|
||||
case RKMODULE_GET_START_STREAM_SEQ:
|
||||
dev_err(&xs9922->client->dev, "stream seq");
|
||||
*(int *)arg = RKMODULE_START_STREAM_FRONT;
|
||||
break;
|
||||
|
||||
|
@ -787,6 +815,7 @@ static long xs9922_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
|||
#endif
|
||||
|
||||
default:
|
||||
//dev_err(&xs9922->client->dev, "chapin defalut cmd");
|
||||
ret = -ENOTTY;
|
||||
break;
|
||||
}
|
||||
|
@ -1049,6 +1078,8 @@ static int xs9922_stream(struct v4l2_subdev *sd, int on)
|
|||
if (xs9922->streaming == on)
|
||||
goto unlock;
|
||||
|
||||
dev_dbg(&client->dev, "chapin xs9922_stream call");
|
||||
|
||||
if (on) {
|
||||
__xs9922_start_stream(xs9922);
|
||||
} else {
|
||||
|
@ -1079,21 +1110,37 @@ static int xs9922_power(struct v4l2_subdev *sd, int on)
|
|||
if (xs9922->power_on == !!on)
|
||||
goto exit;
|
||||
|
||||
dev_dbg(&client->dev, "%s: on %d\n", __func__, on);
|
||||
|
||||
if (on) {
|
||||
ret = pm_runtime_get_sync(&client->dev);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_noidle(&client->dev);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
#if (!__CLOSE_SENSOR__)
|
||||
dev_dbg(&client->dev, "%s: >>>>>> global reg list and module reg list download...\n", __func__);
|
||||
if (xs9922->power_on_first == 0) {
|
||||
dev_err(&client->dev, "%s: >>>>>> global reg list and module reg list download...\n", __func__);
|
||||
INIT_DELAYED_WORK(&xs9922->delay_init, __xs9922_init);
|
||||
schedule_delayed_work(&xs9922->delay_init, msecs_to_jiffies(0));
|
||||
|
||||
dev_dbg(&client->dev, "%s: >>>>>> global reg list and module reg list download OK!\n", __func__);
|
||||
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__);
|
||||
}
|
||||
|
||||
if (!xs9922_reg_config) {
|
||||
xs9922_reg_config = true;
|
||||
|
@ -1120,7 +1167,7 @@ static int __xs9922_power_on(struct xs9922 *xs9922)
|
|||
struct device *dev = &xs9922->client->dev;
|
||||
|
||||
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 (xs9922->power_on ) return 0;
|
||||
#endif
|
||||
|
@ -1178,9 +1225,9 @@ err_clk:
|
|||
static void __xs9922_power_off(struct xs9922 *xs9922)
|
||||
{
|
||||
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;
|
||||
|
||||
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 v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct xs9922 *xs9922 = to_xs9922(sd);
|
||||
dev_dbg(&client->dev, "%s \n",__func__);
|
||||
dev_err(&client->dev, "%s \n",__func__);
|
||||
|
||||
__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->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);
|
||||
/* No crop or compose */
|
||||
|
@ -1372,6 +1421,7 @@ static const struct v4l2_subdev_internal_ops xs9922_internal_ops = {
|
|||
|
||||
static const struct v4l2_subdev_video_ops xs9922_video_ops = {
|
||||
.s_stream = xs9922_stream,
|
||||
.g_frame_interval = xs9922_g_frame_interval,
|
||||
.g_mbus_config = xs9922_g_mbus_config,
|
||||
};
|
||||
|
||||
|
@ -1994,6 +2044,8 @@ static int xs9922_remove(struct i2c_client *client)
|
|||
#if defined(CONFIG_MEDIA_CONTROLLER)
|
||||
media_entity_cleanup(&sd->entity);
|
||||
#endif
|
||||
pr_err("xs9922_remove called");
|
||||
cancel_delayed_work(&xs9922->delay_init);
|
||||
v4l2_ctrl_handler_free(&xs9922->ctrl_handler);
|
||||
mutex_destroy(&xs9922->mutex);
|
||||
|
||||
|
|
0
kernel/drivers/media/i2c/chipup/xs9922_reg_cfg.h
Normal file → Executable file
0
kernel/drivers/media/i2c/chipup/xs9922_reg_cfg.h
Normal file → Executable file
Loading…
Reference in New Issue
Block a user