Ov9650 camera driver-Linux kernel v4l2 Architecture Analysis 2

Source: Internet
Author: User

No. 2 camera decoder and Controller

 

1. According to the description of the camera controller, there are two DMA channels for image transmission. We use the C channel, so we first initialize the DMA memory, because there areConvert the data cache allocated in vidioc_reqbufs to a physical address

Therefore, DMA should be initialized before use, including calculation of the actual physical address.

Init_image_buffer (camera_dev); // Initialization

 

 

 

Static int _ inline _ init_image_buffer (struct s5pc100_camera_device * cam) {unsigned long size; unsigned int order; cam-> frame = img_buff; size = max_width * max_height * formats [3]. depth/8; // sizeof image buffer is 600 Kbytes printk ("each image buffer is % dkbytes. \ n ", (INT) (size/1024); Order = get_order (size); // system function, size should be the N power of 2, memory is allocated by PAGE img_buff [0]. order = order; img_buff [0]. pai_base = _ get_free_pa GES (gfp_kernel | gfp_dma, img_buff [0]. order); // request the DMA space. This function can allocate multiple pages and return the first address of the allocated memory. The number of allocated pages is the order power of 2, the allocated page is not cleared. The maximum value allowed by order is 10 (1024 pages) or 11 (2048 pages), depending on the hardware platform. Img_buff [0]. img_size = size; img_buff [0]. phy_base = img_buff [0]. pai_base-page_offset + phys_offset; // The DMA address. how is the physical address of the applied DMA calculated? First remove page_offsetwhy? In Linux, 4G space of a process is divided into two parts: user space and kernel space. The address distribution of user space is generally 0-3G (that is, rage_offset ), in this way, the remaining 3-4G is the kernel space, and + phys_offset is added (this is determined by the specific CPU, the physical start address of RAM ), in this case, phy_base corresponds to the real physical address printk ("Get pages for img_buff [0 .. 3] Done. \ n "); Return 0; error0: Return-enomem ;}

 

 

 

 

2. initialization of the camera Controller

 

  • Image Source format settings
  • Window cut settings
  • Target Image format settings
  • Image Scaling and rotation settings
  • (Optional, if the local LCD is used for display) the output buffer address is located in the framebuffer memory address (that is, the memory overlaps, so that the LCD can be directly displayed ), this is omitted because LCD is not used here.

 

Code:

 

Init_camif_config (camera_dev); static void init_camif_config (struct failed * c) {struct s5pc100_camera_device * cam = C; cam-> Format = 3; // fixme, C-path default format, see formats [] for detail. select C-channel cam-> srchsize = 640; // fixme, The ov9650's horizontal output pixels. set cam-> srcvsize = 480; // fixme, The ov9650's verical output pixels. set cam-> wndhsize = 640; cam-> wndvsize = 480; // set cam-> targethsize = cam-> wndhsize for window cut; // set the target image format, overlapping the window image, covering all the cam-> targetvsize = cam-> wndvsize; the rotation is not set so far, but only the cam data is filled, however, the source and destination address registers of the camera controller are not configured. The configuration of these two registers depends on the initialized parameter update_camera_config (cam, (u32)-1 ); // This function is integrated into a function, which is to configure the operation of two registers} static void update_camera_config (struct s5pc100_camera_device * C, u32 encode code) {struct s5pc100_camera_device * cam = C; update_camera_regs (CAM); // config the regs directly. encapsulated the following two functions, but it is not necessary to} static void _ inline _ update_camera_regs (struct s5pc100_camera_device * cam) {update_source_fmt_regs (CAM); update_target_fmt_regs (CAM );}

 

 

 

Initialize source register

Static void _ inline _ update_source_fmt_regs (struct s5pc100_camera_device * c) {struct s5pc100_camera_device * cam = C; u32 CFG; CFG = (1 <31) // ITU-R bt.601 YCbCr 8-Bit mode | (0 <30) // CB, Cr value offset cntrol for YCbCr | (640 <16) // target image width | (0 <14) // input order is ycbycr | (640 <0); // source image heightwritel (CFG, cam-> reg_base + s5pc100_cisrcfmt); // 0xee20_0000 + cost _0000 image source address printk ("cost = % x \ n", readl (cam-> reg_base + s5pc100_cisrcfmt )); CFG = (1 <15) | (1 <14) | (1 <30) | (1 <29); writel (CFG, cam-> reg_base + s5pc100_ciwdofst); // 0xee20_0000 + pai_0004 clear cache export ocfg = (1 <26) | (1 <29) | (1 <16) | (1 <7) | (0 <0); writel (CFG, Cam-> reg_base + s5pc100_cigctrl); // 0xee20_0000 + 1__0008 global variable control register, includes printk ("s5pc100_cigctrl = % x \ n", readl (cam-> reg_base + s5pc100_cigctrl); writel (0, cam-> reg_base + s5pc100_ciwdofst2); // 0xee20_0000 + rj_0014 window offset register printk ("ov9650_vga mode \ n ");}

 


Initialize destination register

Static void _ inline _ partition (struct into * cam) {u32 CFG; u32 h_shift; u32 v_shift; u32 prescaler_v_ratio; u32 prescaler_h_ratio; u32 main_v_ratio; u32 main_h_ratio; switch (formats [cam-> Format]. pixelformat) {case when: Case v4l2_pix_fmt_rgb24: case when: Case v4l2_pix_fmt_yuyv:/* YCbCr 1 plane */printk ("format when"); writel (img_buff [0]. phy_base, Cam-> reg_base + s5pc100_cioysa1); // 0xee20_0000 + prepare _0018 dmay1 output start address register assign the configured physical start address of the DMA to the above register/* ciprtrgfmt. */CFG = (2 <29) | (cam-> targethsize <16) | (cam-> targetvsize <0) | (1 <13) | (1 <14) | (1 <15); shift the size information initialized in the cam and write it to the corresponding position writel (CFG, cam-> reg_base + s5pc100_citrgfmt); // 0xee20_0000 + Destination format register * ciscpreratio. */calculate_prescaler_ratio_shift (cam-> srchsize, Cam-> targethsize, & prescaler_h_ratio, & h_shift); // compress the abscissa of the source, returns the compression ratio and shift count calculate_prescaler_ratio_shift (cam-> srcvsize, Cam-> targetvsize, & prescaler_v_ratio, & v_shift ); // compress the source ordinate value main_h_ratio = (cam-> srchsize <8)/(cam-> targethsize 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.