国际域名注册网站,wordpress分类页打不开,外贸营销型网页设计公司,哈尔滨网站建设排行采用fpga输入#xff0c;3568采集并显示至hdmi RKVICAP 驱动框架说明 RKVICAP驱动主要是基于 v4l2 / media 框架实现硬件的配置、中断处理、控制 buffer 轮转#xff0c;以及控制 subdevice(如 mipi dphy 及 sensor) 的上下电等功能。 对于RK356X 芯片而言#xff0c; VICAP…采用fpga输入3568采集并显示至hdmi RKVICAP 驱动框架说明 RKVICAP驱动主要是基于 v4l2 / media 框架实现硬件的配置、中断处理、控制  buffer 轮转以及控制 subdevice(如  mipi dphy 及 sensor) 的上下电等功能。  对于RK356X 芯片而言 VICAP 只有单核同时拥有 dvp/mipi 两种接口 dvp 接口对应一个 rkvicap_dvp 节点mipi 接口对应一个 rkvicap_mipi_lvds 节点与 RV1126/RV1109 的 VICAP FULL 同名各节点可独立采集。            为了将VICAP 采集数据信息同步给 isp 驱动需要将 VICAP 驱动生成的逻辑 sditf 节点链接到 isp 所生成的虚拟节点设备。DVP 接口对应 rkvicap_dvp_sditf 节点 VICAP FULL 的 mipi/lvds 接口对应 rkvicap_mipi_lvds_sditf节点 VICAP LITE 对应 rkvicap_lite_sditf 。   1.DVP camera 
RK3568有一个DVP接口支持BT601/BT656/BT1120等同样的如果是RAW的sensor需要配置到ISP如果是YUV的则不需经过ISP关键配置如下 1在sensor驱动的g_mbus_config接口中通过flag指明当前sensor的hsync-acitve/vsyncactive/pclk-ative的有效极性否则会导致无法收到数据 
static int avafpga_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,struct v4l2_mbus_config *config)
{config-type  V4L2_MBUS_BT656;config-flags  V4L2_MBUS_HSYNC_ACTIVE_HIGH |V4L2_MBUS_VSYNC_ACTIVE_HIGH |V4L2_MBUS_PCLK_SAMPLE_RISING;return 0;
} 2设备树的节点中hsync-active/vsync-active 不要配置否则 v4l2 框架异步注册时会识别为 BT601; 3pclk-sample/bus-width 可选 bus-width  16;
pclk-sample  1; 4必须实现v4l2_subdev_video_ops中的querystd接口指明当前接口为ATSC接口,否则会导致无法收到数据 static int avafpga_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
{*std  V4L2_STD_ATSC;return 0;
} 5必须实现RKMODULE_GET_BT656_MBUS_INFOBT656/BT1120都是调用这个ioctl接口兼容实现参考drivers/media/i2c/nvp6158_drv/nvp6158_v4l2.c static __maybe_unused void
avafpga_get_bt656_module_inf(struct avafpga *avafpga,struct rkmodule_bt656_mbus_info *inf)
{memset(inf, 0, sizeof(*inf));inf-flags  RKMODULE_CAMERA_BT656_PARSE_ID_LSB;switch (avafpga-ch_nums) {case 1:inf-flags | RKMODULE_CAMERA_BT656_CHANNEL_0;break;case 2:inf-flags | RKMODULE_CAMERA_BT656_CHANNEL_0 |RKMODULE_CAMERA_BT656_CHANNEL_1;break;case 4:inf-flags | RKMODULE_CAMERA_BT656_CHANNELS;break;default:inf-flags | RKMODULE_CAMERA_BT656_CHANNELS;}
}static long avafpga_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{long ret  0;switch (cmd) {default:ret  -ENOTTY;break;}return ret;
}#ifdef CONFIG_COMPAT
static long avafpga_compat_ioctl32(struct v4l2_subdev *sd,unsigned int cmd, unsigned long arg)
{long ret  0;//struct rkmodule_bt656_mbus_info *bt565_inf;switch (cmd) {default:ret  -ENOIOCTLCMD;break;}return ret;
}
#endif#define DST_XPOS 0
#define DST_YPOS 0
#define DST_WIDTH 1536 //1920
#define DST_HEIGHT 576 //1080static int avafpga_get_selection(struct v4l2_subdev *sd,struct v4l2_subdev_pad_config *cfg,struct v4l2_subdev_selection *sel)
{if (sel-target  V4L2_SEL_TGT_CROP_BOUNDS) {sel-r.left  DST_XPOS;sel-r.top  DST_YPOS;sel-r.width  DST_WIDTH;sel-r.height  DST_HEIGHT;return 0;}return -EINVAL;
}static int avafpga_initialize_controls(struct avafpga *avafpga)
{int ret;struct v4l2_ctrl_handler *handler;const struct avafpga_mode *mode;u32 h_blank, v_blank;handler  avafpga-ctrl_handler;mode  avafpga-cur_mode;ret  v4l2_ctrl_handler_init(handler, 2);if (ret)return ret;handler-lock  avafpga-mutex;h_blank  mode-hts_def - mode-width;avafpga-hblank_ctrl  v4l2_ctrl_new_std(handler, NULL,V4L2_CID_HBLANK, h_blank, h_blank, 1, h_blank);v_blank  mode-vts_def - mode-height;avafpga-vblank_ctrl  v4l2_ctrl_new_std(handler, NULL,V4L2_CID_VBLANK, v_blank, v_blank, 1, v_blank);if (handler-error) {ret  handler-error;dev_err(avafpga-client-dev,Failed to init controls(%d)\n, ret);goto err_free_handler;}avafpga-subdev.ctrl_handler  handler;return 0;err_free_handler:v4l2_ctrl_handler_free(handler);return ret;
}static const struct v4l2_subdev_core_ops avafpga_core_ops  {.s_power  avafpga_s_power,.ioctl  avafpga_ioctl,
#ifdef CONFIG_COMPAT.compat_ioctl32  avafpga_compat_ioctl32,
#endif
}; 6pinctrl需要引用对以对bt656/bt1120相关gpio做相应iomux否则会导致无法收到数据。  dts 配置如下   i2c0 {status   okay;sensor3c{status   okay;compatible  firefly,pc9202;reg  0x3c;wd-en-gpio  gpio3 23 GPIO_ACTIVE_HIGH;};avafpga: avafpga32 {status  okay;compatible  ava,fpga;reg  0x32;clocks  cru CLK_CIF_OUT;clock-names  xvclk;power-domains  power RK3568_PD_VI;pwdn-gpios  gpio4 RK_PB4 GPIO_ACTIVE_HIGH;reset-gpios  gpio3 RK_PB6 GPIO_ACTIVE_HIGH;rockchip,grf  grf;pinctrl-names  default;pinctrl-0  cif_clkcif_dvp_clkcif_dvp_bus16cif_dvp_bus8;rockchip,camera-module-index  0;rockchip,camera-module-facing  back;rockchip,camera-module-name  default;rockchip,camera-module-lens-name  default;rockchip,dvp_mode  BT1120; //BT656 or BT1120 or BT656_TESTport {cam_para_out2: endpoint {remote-endpoint  dvp_in_bcam;bus-width  16;pclk-sample  1;};};};
};rkcif {status  okay;
};rkcif_mmu {status  okay;
};rkcif_dvp {status  okay;port {dvp_in_bcam: endpoint {remote-endpoint  cam_para_out2;bus-width  16;};};
}; 7/rk356x_sdk-linux5.10/kernel/drivers/media/i2c目录下增加fpga.c并在kconfig和makefile中增加相关模块的设置 config VIDEO_FPGAtristate AVA FPGA sensor supportdepends on I2C  VIDEO_V4L2  VIDEO_V4L2_SUBDEV_APIdepends on MEDIA_CAMERA_SUPPORThelpThis is a Video4Linux2 sensor driver for the AVAFPGA camera.To compile this driver as a module, choose M here: themodule will be called fpga. obj-y  fpga.o 完整的fpga的c代码如下亦可见附件开始未设置ioctl上电v4l2抓图时打印_avafpga_start_stream enter然后崩掉后经查阅资料以及参考rv1126的内容加入对应的部分可以成功获取数据且不会崩掉 #include linux/clk.h
#include linux/device.h
#include linux/delay.h
#include linux/gpio/consumer.h
#include linux/i2c.h
#include linux/module.h
#include linux/pm_runtime.h
#include linux/regulator/consumer.h
#include linux/sysfs.h
#include linux/slab.h
#include linux/version.h
#include linux/rk-camera-module.h
#include media/media-entity.h
#include media/v4l2-async.h
#include media/v4l2-ctrls.h
#include media/v4l2-subdev.h
#include linux/pinctrl/consumer.h
#include linux/rk-preisp.h#include media/v4l2-fwnode.h
#include linux/of.h
#include linux/of_device.h
#include linux/of_graph.h
#include linux/of_platform.h
#include linux/of_gpio.h
#include linux/mfd/syscon.h
#include linux/version.h#define DRIVER_VERSION			KERNEL_VERSION(0, 0x0, 0x01)
//#define PIX_FORMAT			MEDIA_BUS_FMT_UYVY8_2X8
#define PIX_FORMAT                    MEDIA_BUS_FMT_YUYV8_2X8
#define AVAFPGA_NAME			avafpgastruct regval {u16 addr;u8 val;
};struct avafpga_mode {u32 width;u32 height;struct v4l2_fract max_fps;u32 hts_def;u32 vts_def;u32 exp_def;const struct regval *reg_list;
};struct avafpga {struct i2c_client	*client;struct clk		*xvclk;struct gpio_desc	*reset_gpio;struct gpio_desc	*pwdn_gpio;struct v4l2_subdev	subdev;struct media_pad	pad;struct v4l2_ctrl_handler ctrl_handler;struct v4l2_ctrl	*exposure;struct v4l2_ctrl	*anal_gain;struct v4l2_ctrl	*digi_gain;struct v4l2_ctrl	*hblank;struct v4l2_ctrl	*vblank;struct v4l2_ctrl	*test_pattern;struct mutex		mutex;bool			streaming;bool			power_on;const struct avafpga_mode *cur_mode;u32			module_index;const char		*module_facing;const char		*module_name;const char		*len_name;u32			ch_nums;//hjkstruct v4l2_ctrl	*vblank_ctrl;struct v4l2_ctrl	*hblank_ctrl;u8 is_reset;
};#define to_avafpga(sd) container_of(sd, struct avafpga, subdev)static const struct avafpga_mode supported_modes[]  {{//.width  1920,//.height  1080,.width  1536,.height  576,		.max_fps  {.numerator  10000,.denominator  600000,},.exp_def  0x0100,.hts_def  0x044c * 2,.vts_def  0x0465,}
};static int __avafpga_start_stream(struct avafpga *avafpga)
{printk(KERN_ERR %s enter\n, __func__);avafpga-is_reset  1;//hjk1126printk(KERN_ERR %s exit\n, __func__);//hjk1126return 0;
}static int __avafpga_stop_stream(struct avafpga *avafpga)
{printk(KERN_ERR %s enter\n, __func__);return 0;
}static int avafpga_s_stream(struct v4l2_subdev *sd, int on)
{struct avafpga *avafpga  to_avafpga(sd);struct i2c_client *client  avafpga-client;int ret  0;mutex_lock(avafpga-mutex);on  !!on;if (on  avafpga-streaming)goto unlock_and_return;if (on) {ret  pm_runtime_get_sync(client-dev);if (ret  0) {pm_runtime_put_noidle(client-dev);goto unlock_and_return;}ret  __avafpga_start_stream(avafpga);if (ret) {v4l2_err(sd, start stream failed while write regs\n);pm_runtime_put(client-dev);goto unlock_and_return;}} else {__avafpga_stop_stream(avafpga);pm_runtime_put(client-dev);}avafpga-streaming  on;
unlock_and_return:mutex_unlock(avafpga-mutex);return ret;
}#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
static int avafpga_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{struct avafpga *avafpga  to_avafpga(sd);struct v4l2_mbus_framefmt *try_fmt v4l2_subdev_get_try_format(sd, fh-pad, 0);const struct avafpga_mode *def_mode  supported_modes[0];mutex_lock(avafpga-mutex);/* Initialize try_fmt */try_fmt-width  def_mode-width;try_fmt-height  def_mode-height;try_fmt-code  PIX_FORMAT;try_fmt-field  V4L2_FIELD_NONE;mutex_unlock(avafpga-mutex);/* No crop or compose */return 0;
}
#endifstatic int avafpga_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,struct v4l2_mbus_config *config)
{//config-type  V4L2_MBUS_BT656;//config-flags  V4L2_MBUS_PCLK_SAMPLE_RISING;config-type  V4L2_MBUS_BT656;config-flags  V4L2_MBUS_PCLK_SAMPLE_RISING;//config-flags  V4L2_MBUS_HSYNC_ACTIVE_LOW |//V4L2_MBUS_VSYNC_ACTIVE_LOW |//V4L2_MBUS_PCLK_SAMPLE_FALLING;//config-type  V4L2_MBUS_BT656;//config-flags  RKMODULE_CAMERA_BT656_CHANNELS |//V4L2_MBUS_PCLK_SAMPLE_RISING;//config-type  V4L2_MBUS_BT656;config-flags  V4L2_MBUS_HSYNC_ACTIVE_HIGH |V4L2_MBUS_VSYNC_ACTIVE_HIGH |V4L2_MBUS_PCLK_SAMPLE_RISING;return 0;}static int avafpga_g_frame_interval(struct v4l2_subdev *sd,struct v4l2_subdev_frame_interval *fi)
{struct avafpga *avafpga  to_avafpga(sd);const struct avafpga_mode *mode  avafpga-cur_mode;mutex_lock(avafpga-mutex);fi-interval  mode-max_fps;mutex_unlock(avafpga-mutex);return 0;
}static int avafpga_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
{*std  V4L2_STD_ATSC;return 0;
}static int avafpga_enum_frame_interval(struct v4l2_subdev *sd,struct v4l2_subdev_pad_config *cfg,struct v4l2_subdev_frame_interval_enum *fie)
{if (fie-index  ARRAY_SIZE(supported_modes))return -EINVAL;//if (fie-code ! PIX_FORMAT)//return -EINVAL;fie-width  supported_modes[fie-index].width;fie-height  supported_modes[fie-index].height;fie-interval  supported_modes[fie-index].max_fps;return 0;
}static int avafpga_enum_mbus_code(struct v4l2_subdev *sd,struct v4l2_subdev_pad_config *cfg,struct v4l2_subdev_mbus_code_enum *code)
{if (code-index ! 0)return -EINVAL;code-code  PIX_FORMAT;return 0;
}static int avafpga_enum_frame_sizes(struct v4l2_subdev *sd,struct v4l2_subdev_pad_config *cfg,struct v4l2_subdev_frame_size_enum *fse)
{if (fse-index  ARRAY_SIZE(supported_modes))return -EINVAL;//if (fse-code ! PIX_FORMAT)//hjk1126中没有这个//return -EINVAL;//hjk1126中没有这个fse-min_width   supported_modes[fse-index].width;fse-max_width   supported_modes[fse-index].width;fse-max_height  supported_modes[fse-index].height;fse-min_height  supported_modes[fse-index].height;return 0;
}static int avafpga_set_fmt(struct v4l2_subdev *sd,struct v4l2_subdev_pad_config *cfg,struct v4l2_subdev_format *fmt)
{struct avafpga *avafpga  to_avafpga(sd);const struct avafpga_mode *mode;mutex_lock(avafpga-mutex);mode  avafpga-cur_mode;fmt-format.code  PIX_FORMAT;fmt-format.width  mode-width;fmt-format.height  mode-height;fmt-format.field  V4L2_FIELD_NONE;//fmt-format.field  V4L2_FIELD_INTERLACEDif (fmt-which  V4L2_SUBDEV_FORMAT_TRY) {
#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API*v4l2_subdev_get_try_format(sd, cfg, fmt-pad)  fmt-format;
#elsemutex_unlock(avafpga-mutex);return -ENOTTY;
#endif} else {avafpga-cur_mode  mode;}mutex_unlock(avafpga-mutex);return 0;
}static int avafpga_get_fmt(struct v4l2_subdev *sd,struct v4l2_subdev_pad_config *cfg,struct v4l2_subdev_format *fmt)
{struct avafpga *avafpga  to_avafpga(sd);const struct avafpga_mode *mode  avafpga-cur_mode;mutex_lock(avafpga-mutex);if (fmt-which  V4L2_SUBDEV_FORMAT_TRY) {
#ifdef CONFIG_VIDEO_V4L2_SUBDEV_APIfmt-format  *v4l2_subdev_get_try_format(sd, cfg, fmt-pad);
#elsemutex_unlock(avafpga-mutex);return -ENOTTY;
#endif} else {fmt-format.width  mode-width;fmt-format.height  mode-height;fmt-format.code  PIX_FORMAT;fmt-format.field  V4L2_FIELD_NONE;}mutex_unlock(avafpga-mutex);return 0;
}static int avafpga_s_power(struct v4l2_subdev *sd, int on)
{struct avafpga *avafpga  to_avafpga(sd);struct i2c_client *client  avafpga-client;int ret  0;mutex_lock(avafpga-mutex);/* If the power state is not modified - no work to do. */if (avafpga-power_on  !!on)goto unlock_and_return;if (on) {ret  pm_runtime_get_sync(client-dev);if (ret  0) {pm_runtime_put_noidle(client-dev);goto unlock_and_return;}avafpga-power_on  true;} else {pm_runtime_put(client-dev);avafpga-power_on  false;}unlock_and_return:mutex_unlock(avafpga-mutex);return ret;
}static int __avafpga_power_on(struct avafpga *avafpga)
{return 0;
}static void __avafpga_power_off(struct avafpga *avafpga)
{return;
}static int avafpga_runtime_resume(struct device *dev)
{struct i2c_client *client  to_i2c_client(dev);struct v4l2_subdev *sd  i2c_get_clientdata(client);struct avafpga *avafpga  to_avafpga(sd);return __avafpga_power_on(avafpga);
}static int avafpga_runtime_suspend(struct device *dev)
{struct i2c_client *client  to_i2c_client(dev);struct v4l2_subdev *sd  i2c_get_clientdata(client);struct avafpga *avafpga  to_avafpga(sd);__avafpga_power_off(avafpga);return 0;
}hjk///
static __maybe_unused void
avafpga_get_bt656_module_inf(struct avafpga *avafpga,struct rkmodule_bt656_mbus_info *inf)
{memset(inf, 0, sizeof(*inf));inf-flags  RKMODULE_CAMERA_BT656_PARSE_ID_LSB;switch (avafpga-ch_nums) {case 1:inf-flags | RKMODULE_CAMERA_BT656_CHANNEL_0;break;case 2:inf-flags | RKMODULE_CAMERA_BT656_CHANNEL_0 |RKMODULE_CAMERA_BT656_CHANNEL_1;break;case 4:inf-flags | RKMODULE_CAMERA_BT656_CHANNELS;break;default:inf-flags | RKMODULE_CAMERA_BT656_CHANNELS;}
}static long avafpga_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{long ret  0;//struct avafpga *avafpga  to_avafpga(sd);switch (cmd) {/*case RKMODULE_GET_BT656_MBUS_INFO:avafpga_get_bt656_module_inf(avafpga,(struct rkmodule_bt656_mbus_info*)arg);break;*/default:ret  -ENOTTY;break;}return ret;
}#ifdef CONFIG_COMPAT
static long avafpga_compat_ioctl32(struct v4l2_subdev *sd,unsigned int cmd, unsigned long arg)
{//void __user *up  compat_ptr(arg);//struct rkmodule_inf *inf;//struct rkmodule_awb_cfg *cfg;//int *seq;long ret  0;//struct rkmodule_bt656_mbus_info *bt565_inf;switch (cmd) {/*case RKMODULE_GET_BT656_MBUS_INFO:bt565_inf  kzalloc(sizeof(*bt565_inf), GFP_KERNEL);if (!bt565_inf) {ret  -ENOMEM;return ret;}ret  avafpga_ioctl(sd, cmd, bt565_inf);if (!ret) {ret  copy_to_user(up, bt565_inf, sizeof(*bt565_inf));if (ret)ret  -EFAULT;}kfree(bt565_inf);break;*/default:ret  -ENOIOCTLCMD;break;}return ret;
}
#endif#define DST_XPOS 0
#define DST_YPOS 0
#define DST_WIDTH 1536 //1920
#define DST_HEIGHT 576 //1080static int avafpga_get_selection(struct v4l2_subdev *sd,struct v4l2_subdev_pad_config *cfg,struct v4l2_subdev_selection *sel)
{if (sel-target  V4L2_SEL_TGT_CROP_BOUNDS) {sel-r.left  DST_XPOS;sel-r.top  DST_YPOS;sel-r.width  DST_WIDTH;sel-r.height  DST_HEIGHT;return 0;}return -EINVAL;
}static int avafpga_initialize_controls(struct avafpga *avafpga)
{int ret;struct v4l2_ctrl_handler *handler;const struct avafpga_mode *mode;u32 h_blank, v_blank;handler  avafpga-ctrl_handler;mode  avafpga-cur_mode;ret  v4l2_ctrl_handler_init(handler, 2);if (ret)return ret;handler-lock  avafpga-mutex;h_blank  mode-hts_def - mode-width;avafpga-hblank_ctrl  v4l2_ctrl_new_std(handler, NULL,V4L2_CID_HBLANK, h_blank, h_blank, 1, h_blank);v_blank  mode-vts_def - mode-height;avafpga-vblank_ctrl  v4l2_ctrl_new_std(handler, NULL,V4L2_CID_VBLANK, v_blank, v_blank, 1, v_blank);if (handler-error) {ret  handler-error;dev_err(avafpga-client-dev,Failed to init controls(%d)\n, ret);goto err_free_handler;}avafpga-subdev.ctrl_handler  handler;return 0;err_free_handler:v4l2_ctrl_handler_free(handler);return ret;
}
hjk//static const struct dev_pm_ops avafpga_pm_ops  {SET_RUNTIME_PM_OPS(avafpga_runtime_suspend,avafpga_runtime_resume, NULL)
};#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
static const struct v4l2_subdev_internal_ops avafpga_internal_ops  {.open  avafpga_open,
};
#endifstatic const struct v4l2_subdev_core_ops avafpga_core_ops  {.s_power  avafpga_s_power,//hjk.ioctl  avafpga_ioctl,
#ifdef CONFIG_COMPAT.compat_ioctl32  avafpga_compat_ioctl32,
#endif//hjk
};static const struct v4l2_subdev_video_ops avafpga_video_ops  {.s_stream  avafpga_s_stream,.g_frame_interval  avafpga_g_frame_interval,.querystd  avafpga_querystd,
};static const struct v4l2_subdev_pad_ops avafpga_pad_ops  {.enum_mbus_code  avafpga_enum_mbus_code,.enum_frame_size  avafpga_enum_frame_sizes,.enum_frame_interval  avafpga_enum_frame_interval,.get_fmt  avafpga_get_fmt,.set_fmt  avafpga_set_fmt,.get_selection  avafpga_get_selection,.get_mbus_config  avafpga_g_mbus_config,
};static const struct v4l2_subdev_ops avafpga_subdev_ops  {.core	 avafpga_core_ops,.video	 avafpga_video_ops,.pad	 avafpga_pad_ops,
};static int avafpga_probe(struct i2c_client *client,const struct i2c_device_id *id)
{struct device *dev  client-dev;struct avafpga *avafpga;struct v4l2_subdev *sd;char facing[2];int ret;dev_info(dev, driver version: %02x.%02x.%02x,DRIVER_VERSION  16,(DRIVER_VERSION  0xff00)  8,DRIVER_VERSION  0x00ff);avafpga  devm_kzalloc(dev, sizeof(*avafpga), GFP_KERNEL);if (!avafpga)return -ENOMEM;avafpga-client  client;avafpga-cur_mode  supported_modes[0];avafpga-xvclk  devm_clk_get(dev, xvclk);if (IS_ERR(avafpga-xvclk)) {dev_err(dev, Failed to get xvclk\n);return -EINVAL;}//avafpga-reset_gpio  devm_gpiod_get(dev, reset, GPIOD_OUT_LOW);//if (IS_ERR(avafpga-reset_gpio))//dev_warn(dev, Failed to get reset-gpios\n);//avafpga-pwdn_gpio  devm_gpiod_get(dev, pwdn, GPIOD_OUT_LOW);//if (IS_ERR(avafpga-pwdn_gpio))//dev_warn(dev, Failed to get pwdn-gpios\n);mutex_init(avafpga-mutex);sd  avafpga-subdev;v4l2_i2c_subdev_init(sd, client, avafpga_subdev_ops);//hjkret  avafpga_initialize_controls(avafpga);if (ret) {dev_err(dev, Failed to initialize controls fpga\n);goto err_free_handler;}//hjkret  __avafpga_power_on(avafpga);if (ret)goto err_free_handler;#ifdef CONFIG_VIDEO_V4L2_SUBDEV_APIsd-internal_ops  avafpga_internal_ops;sd-flags | V4L2_SUBDEV_FL_HAS_DEVNODE |V4L2_SUBDEV_FL_HAS_EVENTS;
#endif#if defined(CONFIG_MEDIA_CONTROLLER)avafpga-pad.flags  MEDIA_PAD_FL_SOURCE;sd-entity.function  MEDIA_ENT_F_CAM_SENSOR;ret  media_entity_pads_init(sd-entity, 1, avafpga-pad);if (ret  0)goto err_power_off;
#endifmemset(facing, 0, sizeof(facing));if (!sd-dev)dev_err(dev, sd dev is null\n);snprintf(sd-name, sizeof(sd-name), m%02d_%s_%s %s,avafpga-module_index, facing,AVAFPGA_NAME, dev_name(sd-dev));ret  v4l2_async_register_subdev_sensor_common(sd);if (ret) {dev_err(dev, v4l2 async register subdev failed\n);goto err_clean_entity;}pm_runtime_set_active(dev);pm_runtime_enable(dev);pm_runtime_idle(dev);dev_err(dev, v4l2 async register subdev sucessfully\n);return 0;err_clean_entity:
#if defined(CONFIG_MEDIA_CONTROLLER)media_entity_cleanup(sd-entity);
#endif
err_power_off:__avafpga_power_off(avafpga);
err_free_handler:v4l2_ctrl_handler_free(avafpga-ctrl_handler);mutex_destroy(avafpga-mutex);return ret;
}static int avafpga_remove(struct i2c_client *client)
{struct v4l2_subdev *sd  i2c_get_clientdata(client);struct avafpga *avafpga  to_avafpga(sd);v4l2_async_unregister_subdev(sd);
#if defined(CONFIG_MEDIA_CONTROLLER)media_entity_cleanup(sd-entity);
#endifv4l2_ctrl_handler_free(avafpga-ctrl_handler);mutex_destroy(avafpga-mutex);pm_runtime_disable(client-dev);if (!pm_runtime_status_suspended(client-dev))__avafpga_power_off(avafpga);pm_runtime_set_suspended(client-dev);return 0;
}#if IS_ENABLED(CONFIG_OF)
static const struct of_device_id avafpga_of_match[]  {{ .compatible  ava,fpga },{},
};
MODULE_DEVICE_TABLE(of, avafpga_of_match);
#endifstatic const struct i2c_device_id avafpga_match_id[]  {{ava,fpga, 0 },{},
};static struct i2c_driver avafpga_i2c_driver  {.driver  {.name  AVAFPGA_NAME,.of_match_table  of_match_ptr(avafpga_of_match),},.probe		 avafpga_probe,.remove		 avafpga_remove,.id_table	 avafpga_match_id,
};static int __init sensor_mod_init(void)
{return i2c_add_driver(avafpga_i2c_driver);
}static void __exit sensor_mod_exit(void)
{i2c_del_driver(avafpga_i2c_driver);
}device_initcall_sync(sensor_mod_init);
module_exit(sensor_mod_exit);MODULE_DESCRIPTION(AVA FPGA sensor driver);
MODULE_LICENSE(GPL v2); 编译后会在路径下生成fpga.o加载进内核模块  具体的调试结果如下    文章转载自: http://www.morning.bplqh.cn.gov.cn.bplqh.cn http://www.morning.rtmqy.cn.gov.cn.rtmqy.cn http://www.morning.dmtwz.cn.gov.cn.dmtwz.cn http://www.morning.zjcmr.cn.gov.cn.zjcmr.cn http://www.morning.tnjff.cn.gov.cn.tnjff.cn http://www.morning.wsjnr.cn.gov.cn.wsjnr.cn http://www.morning.kcdts.cn.gov.cn.kcdts.cn http://www.morning.sqfnx.cn.gov.cn.sqfnx.cn http://www.morning.xrwbc.cn.gov.cn.xrwbc.cn http://www.morning.jjzjn.cn.gov.cn.jjzjn.cn http://www.morning.dfltx.cn.gov.cn.dfltx.cn http://www.morning.wrtw.cn.gov.cn.wrtw.cn http://www.morning.bfcrp.cn.gov.cn.bfcrp.cn http://www.morning.zthln.cn.gov.cn.zthln.cn http://www.morning.ymrq.cn.gov.cn.ymrq.cn http://www.morning.ckrnq.cn.gov.cn.ckrnq.cn http://www.morning.czzpm.cn.gov.cn.czzpm.cn http://www.morning.rlbc.cn.gov.cn.rlbc.cn http://www.morning.lkbyj.cn.gov.cn.lkbyj.cn http://www.morning.qrwnj.cn.gov.cn.qrwnj.cn http://www.morning.hrkth.cn.gov.cn.hrkth.cn http://www.morning.gjqgz.cn.gov.cn.gjqgz.cn http://www.morning.krtcjc.cn.gov.cn.krtcjc.cn http://www.morning.ftrpvh.cn.gov.cn.ftrpvh.cn http://www.morning.sbkb.cn.gov.cn.sbkb.cn http://www.morning.qttft.cn.gov.cn.qttft.cn http://www.morning.yqfdl.cn.gov.cn.yqfdl.cn http://www.morning.ngcw.cn.gov.cn.ngcw.cn http://www.morning.krtcjc.cn.gov.cn.krtcjc.cn http://www.morning.rpstb.cn.gov.cn.rpstb.cn http://www.morning.nxfwf.cn.gov.cn.nxfwf.cn http://www.morning.ryxdr.cn.gov.cn.ryxdr.cn http://www.morning.wprxm.cn.gov.cn.wprxm.cn http://www.morning.gcjhh.cn.gov.cn.gcjhh.cn http://www.morning.yxshp.cn.gov.cn.yxshp.cn http://www.morning.zsthg.cn.gov.cn.zsthg.cn http://www.morning.wqcz.cn.gov.cn.wqcz.cn http://www.morning.qjxkx.cn.gov.cn.qjxkx.cn http://www.morning.bpmtz.cn.gov.cn.bpmtz.cn http://www.morning.cftkz.cn.gov.cn.cftkz.cn http://www.morning.lsjgh.cn.gov.cn.lsjgh.cn http://www.morning.stprd.cn.gov.cn.stprd.cn http://www.morning.qphcq.cn.gov.cn.qphcq.cn http://www.morning.clqpj.cn.gov.cn.clqpj.cn http://www.morning.tqqfj.cn.gov.cn.tqqfj.cn http://www.morning.kuaijili.cn.gov.cn.kuaijili.cn http://www.morning.sooong.com.gov.cn.sooong.com http://www.morning.lbpfl.cn.gov.cn.lbpfl.cn http://www.morning.kyhnl.cn.gov.cn.kyhnl.cn http://www.morning.pdmsj.cn.gov.cn.pdmsj.cn http://www.morning.nydtt.cn.gov.cn.nydtt.cn http://www.morning.ybgyz.cn.gov.cn.ybgyz.cn http://www.morning.kjgdm.cn.gov.cn.kjgdm.cn http://www.morning.dphmj.cn.gov.cn.dphmj.cn http://www.morning.nqrdx.cn.gov.cn.nqrdx.cn http://www.morning.zxybw.cn.gov.cn.zxybw.cn http://www.morning.mpbgy.cn.gov.cn.mpbgy.cn http://www.morning.jllnh.cn.gov.cn.jllnh.cn http://www.morning.mpscg.cn.gov.cn.mpscg.cn http://www.morning.rmmz.cn.gov.cn.rmmz.cn http://www.morning.pyxtn.cn.gov.cn.pyxtn.cn http://www.morning.ylxgw.cn.gov.cn.ylxgw.cn http://www.morning.hhxwr.cn.gov.cn.hhxwr.cn http://www.morning.nmwgd.cn.gov.cn.nmwgd.cn http://www.morning.mxnfh.cn.gov.cn.mxnfh.cn http://www.morning.jqmqf.cn.gov.cn.jqmqf.cn http://www.morning.rrrrsr.com.gov.cn.rrrrsr.com http://www.morning.gfprf.cn.gov.cn.gfprf.cn http://www.morning.sxtdh.com.gov.cn.sxtdh.com http://www.morning.monstercide.com.gov.cn.monstercide.com http://www.morning.slzkq.cn.gov.cn.slzkq.cn http://www.morning.wpcfm.cn.gov.cn.wpcfm.cn http://www.morning.npmcf.cn.gov.cn.npmcf.cn http://www.morning.htfnz.cn.gov.cn.htfnz.cn http://www.morning.zwmjq.cn.gov.cn.zwmjq.cn http://www.morning.bfkrf.cn.gov.cn.bfkrf.cn http://www.morning.fwqgy.cn.gov.cn.fwqgy.cn http://www.morning.ktnmg.cn.gov.cn.ktnmg.cn http://www.morning.fqqlq.cn.gov.cn.fqqlq.cn http://www.morning.xllrf.cn.gov.cn.xllrf.cn