天天看點

mx53 camera s5k5bbgx驅動分析

一: linux驅動層

1.  通訊方式I2C驅動注冊:

a: arch/arm/mach-mx5/mx53_xx.c

[cpp]  view plain copy

  1. <span style="font-size:16px;">static int mxc_camera2_pwdn(int pwdn)  
  2. {  
  3.     if (pwdn)  
  4.         gpio_direction_output(MX53_HMS_CAMERA2_PWN, 1);  
  5.     else  
  6.         gpio_direction_output(MX53_HMS_CAMERA2_PWN, 0);  
  7.     return 0;  
  8. }      
  9. static struct mxc_camera_platform_data camera2_data = {  
  10.     .mclk = 24000000,  
  11.     .csi = 0,  
  12.     .pwdn = mxc_camera2_pwdn,  
  13. };   
  14. static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {  
  15.    {  
  16.     .type = "s5k5bbgx",  
  17.     .addr = 0x2d,   
  18.       // IIC 位址為7位,最後一位是讀寫位,mx53的驅動内部會把位址左移一位,是以這裡要右移一位  
  19.       .platform_data = (void *)&camera2_data,  
  20.      },  
  21. }  
  22. </span>  

[cpp]  view plain copy

  1. <span style="font-size:16px;">  
  2. static void __init mxc_board_init(void)  
  3. {  
  4. i2c_register_board_info(0, mxc_i2c0_board_info,  
  5.                 ARRAY_SIZE(mxc_i2c0_board_info));  
  6. }</span>  

b: driver/media/video/capture/xx_cam_2M.c

[cpp]  view plain copy

  1. <span style="font-size:16px;">static struct i2c_client *s5k5bbgx_i2c_client = NULL;  
  2. static const struct i2c_device_id s5k5bbgx_id[] = {  
  3.     {"s5k5bbgx", 0},  
  4.     {},  
  5. };  
  6. MODULE_DEVICE_TABLE(i2c, s5k5bbgx_id);  
  7. static struct 2055_i2c_drvier {  
  8.      .driver = {  
  9.           .owner = THIS_MODULE,  
  10.           .name  = "s5k5bbgx",  
  11.           },  
  12.     .probe  = s5k5bbgx_probe,  
  13.     .remove = s5k5bbgx_remove,  
  14.     .id_table = s5k5bbgx_id,  
  15. };  
  16. static __init int s5k5bbgx_init(void)  
  17. {  
  18.     U8 err;  
  19.     err = i2c_add_driver(s5k5bbgx_i2c_driver);  
  20.     return err;  
  21. }  
  22. static int s5k5bbgx_probe(struct i2c_client *client,  
  23.             const struct i2c_device_id *id)  
  24. {  
  25.     s5k5bbgx_i2c_client = client;  
  26.     return 0;  
  27. }  
  28. static s32 s5k5bbgx_read_reg(u16 reg, u16 *val)  
  29. {  
  30.         u8 au8RegBuf[2] = {0};  
  31.     u8 data[2] = {0};  
  32.         au8RegBuf[0] = reg >> 8;  
  33.         au8RegBuf[1] = reg & 0xff;  
  34.     if (2 != i2c_master_send(s5k5bbgx_i2c_client, au8RegBuf, 2)) {  
  35.                 pr_err("%s:write reg error:reg=%x\n",  
  36.                                 __func__, reg);  
  37.                 return -1;  
  38.         }  
  39.     if (2 != i2c_master_recv(s5k5bbgx_i2c_client, data, 2)) {  
  40.                 pr_err("%s:read reg error:reg=0x%04x\n",  
  41.                                 __func__, reg);  
  42.                 return -2;  
  43.         }  
  44.         *val = (data[0] << 8) | data[1];  
  45.         return 0;  
  46. }  
  47. static s32 s5k5bbgx_write_reg(u16 cammand, u16 val)  
  48. {  
  49.         u8 au8Buf[4] = {0};  
  50.     au8Buf[0] = cammand >> 8;  
  51.         au8Buf[1] = cammand & 0xff;  
  52.         au8Buf[2] = val >> 8;  
  53.         au8Buf[3] = val & 0xff;  
  54.     if (4 != i2c_master_send(s5k5bbgx_i2c_client, au8Buf, 4)) {  
  55.         pr_err("%s:write cammand error:cammand=0x%04x,val=0x%04x\n",  
  56.                 __func__, cammand, val);  
  57.         return -1;  
  58.     }  
  59.     return 0;  
  60. }  
  61. <strong>  
  62. </strong></span>  

至此IIC注冊完畢

b: 注冊 v4l2 slave device:

[cpp]  view plain copy

  1. <span style="font-size:16px;">  
  2. struct sensor {  
  3.     const struct mxc_camera_platform_data *platform_data;  
  4.     struct v4l2_int_device *v4l2_int_device;  
  5.     struct i2c_client *i2c_client;  
  6.     struct v4l2_pix_format pix;  
  7.     struct v4l2_captureparm streamcap;  
  8.     bool on;  
  9.     int brightness;  
  10.     int hue;  
  11.     int contrast;  
  12.     int saturation;  
  13.     int red;  
  14.     int green;  
  15.     int blue;  
  16.     int ae_mode;  
  17.     u32 mclk;  
  18.     int csi;  
  19. }s5k5bbgx_data;  
  20. static struct v4l2_int_ioctl_desc s5k5bbgx_ioctl_desc[] = {  
  21.     {vidioc_int_s_parm_num, (v4l2_int_ioctl_func*)ioctl_s_parm},  
  22.     {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func*)ioctl_s_ctrl},  
  23. };  
  24. static struct v4l2_int_slave s5k5bbgx_slave = {  
  25.     .ioctls = s5k5bbgx_ioctl_desc,  
  26.     .num_ioctls = ARRAY_SIZE(s5k5bbgx_ioctl_desc),  
  27. };  
  28. static struct v4l2_int_device s5k5bbgx_int_device = {  
  29.     .module = THIS_MODULE,  
  30.     .name = "s5k5bbgx",  
  31.     .type = v4l2_int_type_slave,  
  32.     .u = {  
  33.         .slave = &s5k5bbgx_slave,  
  34.     },  
  35. };  
  36. static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)  
  37. {  
  38.     struct sensor *sensor = s->priv;  
  39.     struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;  
  40.     u32 tgt_fps;      
  41.     enum s5k5bbgx_frame_rate frame_rate;  
  42.     int ret = 0;  
  43.     if (camera_plat->pwdn)  
  44.         camera_plat->pwdn(0);  
  45.     switch (a->type) {  
  46.     case V4L2_BUF_TYPE_VIDEO_CAPTURE:  
  47.     case V4L2_BUF_TYPE_VIDEO_OUTPUT:  
  48.     case V4L2_BUF_TYPE_VIDEO_OVERLAY:  
  49.     case V4L2_BUF_TYPE_VBI_CAPTURE:  
  50.     case V4L2_BUF_TYPE_VBI_OUTPUT:  
  51.     case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:  
  52.     case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:  
  53.         pr_debug("   type is not " \  
  54.             "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",  
  55.             a->type);  
  56.         ret = -EINVAL;  
  57.         break;  
  58.     default:  
  59.         pr_debug("   type is unknown - %d\n", a->type);  
  60.         ret = -EINVAL;  
  61.         break;  
  62.     }  
  63.     return ret;  
  64. }  
  65. static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)  
  66. {  
  67.     int retval = 0;  
  68.     pr_debug("In s5k5bbgx:ioctl_s_ctrl %d\n",  
  69.          vc->id);  
  70.     switch (vc->id) {  
  71.     case V4L2_CID_BRIGHTNESS:  
  72.         break;  
  73.     case V4L2_CID_CONTRAST:  
  74.         break;  
  75.     case V4L2_CID_SATURATION:  
  76.         break;  
  77.     case V4L2_CID_HUE:  
  78.         break;  
  79.     case V4L2_CID_AUTO_WHITE_BALANCE:  
  80.         break;  
  81.     case V4L2_CID_DO_WHITE_BALANCE:  
  82.         break;  
  83.   default:  
  84.         retval = -EPERM;  
  85.         break;  
  86.     }  
  87.     return retval;  
  88. }  
  89. static int s5k5bbgx_probe(strct i2c_client *client, const struct i2c_device_id *id)  
  90. {  
  91.     s5k5bbgx_int_device.priv = &s5k5bbgx_data;  
  92.     retval = v4l2_int_device_register(&s5k5bbgx_int_device);  
  93. }  
  94. </span>  

v4l2 slave device 注冊完畢

c: s5k5bbgx 初始化和操作

[cpp]  view plain copy

  1. <span style="font-size:16px;">static int s5k5bbgx_probe(struct i2c_client *client,  
  2.             const struct i2c_device_id *id)  
  3. {  
  4.     s5k5bbgx_data.pix.pixelformat = V4L2_PIX_FMT_YUYV;  
  5.     s5k5bbgx_data.pix.width = 800;  
  6.     s5k5bbgx_data.pix.height = 600;  
  7.     s5k5bbgx_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |  
  8.                        V4L2_CAP_TIMEPERFRAME;  
  9.     s5k5bbgx.streamcap.capturemode = 0;  
  10.     s5k5bbgx_data.streamcap.timeperframe.denominator = DEFAULT_FPS;  
  11.     s5k5bbgx_data.streamcap.timeperframe.numerator = 1;  
  12. }  
  13. static int s5k5bbgx_init_mode(enum s5k5bbgx_frame_rate frame_rate,  
  14.                 enum s5k5bbgx_mode mode)  
  15. {  
  16.   struct reg_value *pModeSetting = NULL;  
  17.     s32 i = 0;  
  18.     s32 iModeSettingArySize = 0;  
  19.     register u32 Delay_ms = 0;  
  20.     register u16 RegAddr = 0;  
  21.     register u8 Mask = 0;  
  22.     register u16 Val = 0;  
  23.     register u8 u8Val = 0;  
  24.     u8 RegVal = 0;  
  25.     int retval = 0;  
  26.      pModeSetting = s5k5bbgx_mode_info_data[frame_rate][mode].init_data_ptr;  
  27.      iModeSettingArySize = s5k5bbgx_mode_info_data[frame_rate][mode].init_data_size;                  
  28.      s5k5bbgx_data.pix.width = s5k5bbgx_mode_info_data[frame_rate][mode].width;  
  29.      s5k5bbgx_data.pix.height = s5k5bbgx_mode_info_data[frame_rate][mode].height;  
  30.     for (i = 0; i < iModeSettingArySize; ++i, ++pModeSetting) {  
  31.         Delay_ms = pModeSetting->u32Delay_ms;  
  32.         RegAddr = pModeSetting->u16RegAddr;  
  33.         Val = pModeSetting->u16Val;  
  34.         Mask = pModeSetting->u8Mask;  
  35.         if (Mask) {  
  36.             RegVal &= ~(u8)Mask;  
  37.             Val &= Mask;  
  38.             Val |= RegVal;  
  39.         }  
  40.         retval = s5k5bbgx_write_reg(RegAddr, Val);  
  41.         if (retval < 0)  
  42.             goto err;  
  43.         if (Delay_ms)  
  44.             msleep(Delay_ms);  
  45.     }  
  46. }  
  47. struct s5k5ggbx_set s5k5ggbx_set_data[12] = {  
  48.     {preview, ARRAY_SIZE(preview)}, //screen mode: auto  
  49.     {record, ARRAY_SIZE(record)},  
  50.     {night, ARRAY_SIZE(night)},  
  51.     {capture, ARRAY_SIZE(capture)}, //capture  
  52.     {normal, ARRAY_SIZE(normal)},   //color effect  
  53.     {mono, ARRAY_SIZE(mono)},  
  54.     {negative, ARRAY_SIZE(negative)},  
  55.     {sepia, ARRAY_SIZE(sepia)},  
  56.     {Auto, ARRAY_SIZE(Auto)},   //white balance  
  57.     {incandescent, ARRAY_SIZE(incandescent)},  
  58.     {daylight, ARRAY_SIZE(daylight)},  
  59.     {flourescent, ARRAY_SIZE(flourescent)}  
  60. };  
  61. static int s5k5ggbx_set_code(int index)  
  62. {  
  63.         struct reg_value *p = NULL;  
  64.         s32 i = 0;  
  65.         s32 size = 0;  
  66.         int retval;  
  67.         register u32 Delay_ms = 0;  
  68.         register u16 RegAddr = 0;  
  69.         register u16 Val = 0;  
  70.     p = s5k5ggbx_set_data[index].init_data_ptr;  
  71.     size = s5k5ggbx_set_data[index].init_data_size;  
  72.     for (i = 0; i < size; ++i, ++p) {  
  73.                 Delay_ms = p->u32Delay_ms;  
  74.                 RegAddr = p->u16RegAddr;  
  75.                 Val = p->u16Val;  
  76.                 retval = s5k5bbgx_write_reg(RegAddr, Val);  
  77.                 if (retval < 0)  
  78.                     return retval;  
  79.                 if (Delay_ms)  
  80.                         msleep(Delay_ms);  
  81.         }  
  82.         return 0;  
  83. }  
  84. static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)  
  85. {  
  86.  switch (a->type) {  
  87.     case V4L2_BUF_TYPE_VIDEO_CAPTURE:  
  88.         if ((timeperframe->numerator == 0) ||  
  89.             (timeperframe->denominator == 0)) {  
  90.             timeperframe->denominator = DEFAULT_FPS;  
  91.             timeperframe->numerator = 1;  
  92.         }  
  93.         tgt_fps = timeperframe->denominator /  
  94.               timeperframe->numerator;  
  95.         if (tgt_fps > MAX_FPS) {  
  96.             timeperframe->denominator = MAX_FPS;  
  97.             timeperframe->numerator = 1;  
  98.         } else if (tgt_fps < MIN_FPS) {  
  99.             timeperframe->denominator = MIN_FPS;  
  100.             timeperframe->numerator = 1;  
  101.         }  
  102.         tgt_fps = timeperframe->denominator /  
  103.               timeperframe->numerator;  
  104.         tgt_fps = timeperframe->denominator /  
  105.               timeperframe->numerator;  
  106.         if (tgt_fps == 15)  
  107.             frame_rate = ov2655_15_fps;  
  108.         else if (tgt_fps == 30)  
  109.             frame_rate = ov2655_30_fps;  
  110.         else if (tgt_fps == 7)  
  111.             frame_rate = ov2655_7p5_fps;  
  112.         else {  
  113.             pr_err(" The camera frame rate is not supported!\n");  
  114.             return -EINVAL;  
  115.         }  
  116.  sensor->streamcap.timeperframe = *timeperframe;  
  117.         sensor->streamcap.capturemode = (u32)a->parm.capture.capturemode;  
  118. printk("\n%s, frame_rate = %d, sensor->streamcap.capturemode = %d\n", __func__, frame_rate, sensor->streamcap.capturemode);  
  119.         if (sensor->streamcap.capturemode == 2) //preview: normal  
  120.          {  
  121.                s5k5ggbx_init_mode(frame_rate, sensor->streamcap.capturemode);  
  122.                s5k5ggbx_set_code(0);  
  123.          }  
  124.          else if (sensor->streamcap.capturemode == 4)    //capture  
  125.          {  
  126.                  s5k5ggbx_init_mode(frame_rate, sensor->streamcap.capturemode);  
  127.                 s5k5ggbx_set_code(3);  
  128.          }  
  129.          else if (sensor->streamcap.capturemode == 1)    //preview: recording  
  130.          {  
  131.                 s5k5ggbx_init_mode(frame_rate, sensor->streamcap.capturemode);  
  132.                 s5k5ggbx_set_code(1);  
  133.          }  
  134.         break;  
  135.    }  
  136. }  
  137. </span>  

二,V4L2 capture應用

1.接口

[cpp]  view plain copy

  1. <span style="font-size:16px;">namespace android{  
  2.     class V4l2CapDeviceBase : public CaptureDeviceInterface{  
  3.     public:  
  4.         virtual CAPTURE_DEVICE_ERR_RET SetDevName(char * deviceName);  
  5.         virtual CAPTURE_DEVICE_ERR_RET GetDevName(char * deviceName);  
  6.         virtual CAPTURE_DEVICE_ERR_RET DevOpen();  
  7.         virtual CAPTURE_DEVICE_ERR_RET EnumDevParam(DevParamType devParamType, void *retParam);  
  8.         virtual CAPTURE_DEVICE_ERR_RET DevSetCtrl(int id,int value);  
  9.         virtual CAPTURE_DEVICE_ERR_RET DevSetConfig(struct capture_config_t *pCapcfg);  
  10.         virtual CAPTURE_DEVICE_ERR_RET DevAllocateBuf(DMA_BUFFER *DevBufQue, unsigned int *pBufQueNum);  
  11.         virtual CAPTURE_DEVICE_ERR_RET DevPrepare();  
  12.         virtual CAPTURE_DEVICE_ERR_RET DevStart();  
  13.         virtual CAPTURE_DEVICE_ERR_RET DevDequeue(unsigned int *pBufQueIdx);  
  14.  virtual CAPTURE_DEVICE_ERR_RET DevStop();  
  15.         virtual CAPTURE_DEVICE_ERR_RET DevDeAllocate();  
  16.         virtual CAPTURE_DEVICE_ERR_RET DevClose();  
  17.     protected:  
  18.         V4l2CapDeviceBase();  
  19.         virtual ~V4l2CapDeviceBase();  
  20.         virtual CAPTURE_DEVICE_ERR_RET V4l2Open();  
  21.         virtual CAPTURE_DEVICE_ERR_RET V4l2EnumParam(DevParamType devParamType, void *retParam);  
  22.         virtual CAPTURE_DEVICE_ERR_RET V4l2EnumFmt(void *retParam);  
  23.         virtual CAPTURE_DEVICE_ERR_RET V4l2EnumSizeFps(void *retParam);  
  24.         virtual CAPTURE_DEVICE_ERR_RET V4l2SetConfig(struct capture_config_t *pCapcfg);  
  25.         virtual CAPTURE_DEVICE_ERR_RET V4l2AllocateBuf(DMA_BUFFER *DevBufQue, unsigned int *pBufQueNum);  
  26. virtual CAPTURE_DEVICE_ERR_RET V4l2Prepare();  
  27.         virtual CAPTURE_DEVICE_ERR_RET V4l2Start();  
  28.         virtual CAPTURE_DEVICE_ERR_RET V4l2Dequeue(unsigned int *pBufQueIdx);  
  29.         virtual CAPTURE_DEVICE_ERR_RET V4l2Queue(unsigned int BufQueIdx);  
  30.         virtual CAPTURE_DEVICE_ERR_RET V4l2Stop();  
  31.         virtual CAPTURE_DEVICE_ERR_RET V4l2DeAlloc();  
  32.         virtual CAPTURE_DEVICE_ERR_RET V4l2Close();  
  33.         virtual CAPTURE_DEVICE_ERR_RET V4l2ConfigInput(struct capture_config_t *pCapcfg);  
  34.         virtual CAPTURE_DEVICE_ERR_RET V4l2GetCaptureMode(struct capture_config_t *pCapcfg, unsigned int *pMode);  
  35.         virtual CAPTURE_DEVICE_ERR_RET V4l2SetRot(struct capture_config_t *pCapcfg);  
  36.         char         mCaptureDeviceName[CAMAERA_FILENAME_LENGTH];  
  37.         char         mInitalDeviceName[CAMAERA_SENSOR_LENGTH];  
  38.         int          mCameraDevice;  
  39. unsigned int mFmtParamIdx;  
  40.         unsigned int mSizeFPSParamIdx;  
  41.         unsigned int mRequiredFmt;  
  42.         unsigned int mBufQueNum;  
  43.         int          mQueuedBufNum;  
  44.         DMA_BUFFER mCaptureBuffers[MAX_CAPTURE_BUF_QUE_NUM];  
  45.         struct   capture_config_t mCapCfg;  
  46.     };  
  47. };  
  48. </span>  

2.  經典的調用流程。

具體解析可以看 http://www.linuxidc.com/Linux/2011-03/33022.htm

a. open device  /dev/video16

b . VIDIOC_ENUM_FMT : get video capture supported format

struct v4l2_fmtdesc fmt;

ioctl(dev, VIDIOC_ENUM_FMT, &fmt))

c. VIDIOC_QUERYCAP , get the capture ability

struct v4l2_capability cap; 

iret = ioctl(fd_usbcam, VIDIOC_QUERYCAP, &cap);

d. VIDIOC_S_FMT    , set parameter

   struct v4l2_format tv4l2_format; 

   tv4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 

   tv4l2_format.fmt.pix.width = img_width; 

   tv4l2_format.fmt.pix.height = img_height; 

   tv4l2_format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; 

   tv4l2_format.fmt.pix.field = V4L2_FIELD_INTERLACED; 

   iret = ioctl(fd_usbcam, VIDIOC_S_FMT, &tv4l2_format);

e. VIDIOC_REQBUFS  : get buffer

// Request buffers 

struct v4l2_requestbuffers reqbuf; 

reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 

reqbuf.memory = V4L2_MEMORY_MMAP; 

reqbuf.count = BUFFER_COUNT; 

ret = ioctl(fd , VIDIOC_REQBUFS, &reqbuf); 

if(ret < 0) { 

LOG("VIDIOC_REQBUFS failed (%d)\n", ret); 

return ret; 

}

f. VIDIOC_QUERYBUF

struct v4l2_buffer buf; 

for(i=0; i // Query buffer 

buf.index = i; 

buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 

buf.memory = V4L2_MEMORY_MMAP; 

ret = ioctl(fd , VIDIOC_QUERYBUF, &buf); 

if(ret < 0) { 

LOG("VIDIOC_QUERYBUF (%d) failed (%d)\n", i, ret); 

return ret; 

}

// mmap buffer 

framebuf[i].length = buf.length; 

framebuf[i].start = (char *) mmap(0, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, buf.m.offset); 

if (framebuf[i].start == MAP_FAILED) { 

LOG("mmap (%d) failed: %s\n", i, strerror(errno)); 

return -1; 

}

g. VIDIOC_QBUF

struct v4l2_buffer tV4L2buf; 

memset(&tV4L2buf, 0, sizeof(struct v4l2_buffer));

tV4L2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 

tV4L2buf.memory = V4L2_MEMORY_MMAP; 

tV4L2buf.index = i; //(指定)要投放到視訊輸入隊列中的核心空間視訊緩沖區的編号;

iret = ioctl(fd_usbcam, VIDIOC_QBUF, &tV4L2buf);

H. VIDIOC_STREAMON

enum v4l2_buf_type v4l2type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 

fd_set    fds ; 

struct timeval   tv; 

iret = ioctl(fd_usbcam, VIDIOC_STREAMON, &v4l2type);

i. VIDIOC_DQBUF 

struct v4l2_buffer tV4L2buf; 

memset(&tV4L2buf, 0, sizeof(struct v4l2_buffer));

tV4L2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 

tV4L2buf.memory = V4L2_MEMORY_MMAP; 

iret = ioctl(fd_usbcam, VIDIOC_DQBUF, &tV4L2buf);

j. VIDIOC_QBUF  VIDIOC_DQBUF  VIDIOC_QBUF ...... (read data)

k. VIDIOC_STREAMOFF

enum v4l2_buf_type  v4l2type; 

v4l2type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  

iret = ioctl(fd_usbcam, VIDIOC_STREAMOFF, &v4l2type);

3. android 上的實際實作:

與上面的大同小異,貼出兩個函數

[cpp]  view plain copy

  1. CAPTURE_DEVICE_ERR_RET V4l2CapDeviceBase :: V4l2Open(){  
  2.         CAMERA_HAL_LOG_FUNC;  
  3.         int fd = 0, i, j, is_found = 0;  
  4.         const char *flags[] = {"uncompressed", "compressed"};  
  5.         char   dev_node[CAMAERA_FILENAME_LENGTH];  
  6.         DIR *v4l_dir = NULL;  
  7.         struct dirent *dir_entry;  
  8.         struct v4l2_capability v4l2_cap;  
  9.         struct v4l2_fmtdesc vid_fmtdesc;  
  10.         struct v4l2_frmsizeenum vid_frmsize;  
  11.         CAPTURE_DEVICE_ERR_RET ret = CAPTURE_DEVICE_ERR_NONE;  
  12.         if(mCameraDevice > 0)  
  13.             return CAPTURE_DEVICE_ERR_ALRADY_OPENED;  
  14.         else if (mCaptureDeviceName[0] != '#'){  
  15.             CAMERA_HAL_LOG_RUNTIME("already get the device name %s", mCaptureDeviceName);  
  16.             mCameraDevice = open(mCaptureDeviceName, O_RDWR, O_NONBLOCK);  
  17.             if (mCameraDevice < 0)  
  18.                 return CAPTURE_DEVICE_ERR_OPEN;  
  19.         }  
  20.         else{  
  21.             CAMERA_HAL_LOG_RUNTIME("deviceName is %s", mInitalDeviceName);  
  22.             v4l_dir = opendir("/sys/class/video4linux");  
  23.             if (v4l_dir){  
  24.                 while((dir_entry = readdir(v4l_dir))) {  
  25.                     memset((void *)dev_node, 0, CAMAERA_FILENAME_LENGTH);  
  26.                     if(strncmp(dir_entry->d_name, "video", 5))  
  27.                         continue;  
  28.                     sprintf(dev_node, "/dev/%s", dir_entry->d_name);  
  29.                     if ((fd = open(dev_node, O_RDWR, O_NONBLOCK)) < 0)  
  30. continue;  
  31.                     CAMERA_HAL_LOG_RUNTIME("dev_node is %s", dev_node);  
  32.                     if(ioctl(fd, VIDIOC_QUERYCAP, &v4l2_cap) < 0 ) {  
  33.                         close(fd);  
  34.                         continue;  
  35.                     } else if ((strstr((char *)v4l2_cap.driver, mInitalDeviceName) != 0) &&  
  36.                             (v4l2_cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {  
  37.                         is_found = 1;  
  38.                         strcpy(mCaptureDeviceName, dev_node);  
  39.                         CAMERA_HAL_LOG_RUNTIME("device name is %s", mCaptureDeviceName);  
  40.                         break;  
  41.                     } else  
  42.                         close(fd);  
  43.                 }  
  44.             }  
  45.             if (fd > 0)  
  46.                 mCameraDevice = fd;  
  47.             else{  
  48.                 CAMERA_HAL_ERR("The device name is not correct or the device is error");  
  49.                 return CAPTURE_DEVICE_ERR_OPEN;  
  50.             }  
  51.         }  
  52.         return ret;  
  53.     }  

[cpp]  view plain copy

  1. CAPTURE_DEVICE_ERR_RET V4l2CapDeviceBase :: V4l2AllocateBuf(DMA_BUFFER *DevBufQue, unsigned int *pBufQueNum){  
  2.         unsigned int i;  
  3.         struct v4l2_buffer buf;  
  4.         enum v4l2_buf_type type;  
  5.         struct v4l2_requestbuffers req;  
  6.         int BufQueNum;  
  7.         CAMERA_HAL_LOG_FUNC;  
  8.         if (mCameraDevice <= 0 || DevBufQue == NULL || pBufQueNum == NULL || *pBufQueNum == 0){  
  9.             return CAPTURE_DEVICE_ERR_BAD_PARAM;  
  10.         }  
  11.         mBufQueNum = *pBufQueNum;  
  12.         memset(&req, 0, sizeof (req));  
  13.         req.count = mBufQueNum;  
  14.         req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  15.         req.memory = V4L2_MEMORY_MMAP;  
  16.         if (ioctl(mCameraDevice, VIDIOC_REQBUFS, &req) < 0) {  
  17.             CAMERA_HAL_ERR("v4l_capture_setup: VIDIOC_REQBUFS failed\n");  
  18.             return CAPTURE_DEVICE_ERR_SYS_CALL;  
  19.         }  
  20.         *pBufQueNum = mBufQueNum = req.count;  
  21.         for (i = 0; i < mBufQueNum; i++) {  
  22.             memset(&buf, 0, sizeof (buf));  
  23.             buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  
  24.             buf.index = i;  
  25.             if (ioctl(mCameraDevice, VIDIOC_QUERYBUF, &buf) < 0) {  
  26.                 CAMERA_HAL_ERR("VIDIOC_QUERYBUF error\n");  
  27.                 return CAPTURE_DEVICE_ERR_SYS_CALL;  
  28.             } else {  
  29.                 CAMERA_HAL_LOG_RUNTIME("VIDIOC_QUERYBUF ok\n");  
  30.             }  
  31.             mCaptureBuffers[i].length = DevBufQue[i].length= buf.length;  
  32.             mCaptureBuffers[i].phy_offset = DevBufQue[i].phy_offset = (size_t) buf.m.offset;  
  33.             mCaptureBuffers[i].virt_start = DevBufQue[i].virt_start = (unsigned char *)mmap (NULL, mCaptureBuffers[i].length,  
  34.                     PROT_READ | PROT_WRITE, MAP_SHARED, mCameraDevice, mCaptureBuffers[i].phy_offset);  
  35.             memset(mCaptureBuffers[i].virt_start, 0xFF, mCaptureBuffers[i].length);  
  36.             CAMERA_HAL_LOG_RUNTIME("capture buffers[%d].length = %d\n", i, mCaptureBuffers[i].length);  
  37.             CAMERA_HAL_LOG_RUNTIME("capture buffers[%d].phy_offset = 0x%x\n", i, mCaptureBuffers[i].phy_offset);  
  38.             CAMERA_HAL_LOG_RUNTIME("capture buffers[%d].virt_start = 0x%x\n", i, (unsigned int)(mCaptureBuffers[i].virt_start));  
  39.         }  
  40.         return CAPTURE_DEVICE_ERR_NONE;  
  41.     }