^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Zoran 364xx based USB webcam module version 0.73
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Allows you to use your USB webcam with V4L2 applications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This is still in heavy development !
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2004 Antoine Jacquet <royale@zerezo.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * http://royale.zerezo.com/zr364xx/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Heavily inspired by usb-skeleton.c, vicam.c, cpia.c and spca50x.c drivers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * V4L2 version inspired by meye.c driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Some video buffer code by Lamarque based on s2255drv.c and vivi.c drivers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/highmem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <media/v4l2-common.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <media/v4l2-ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <media/v4l2-device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <media/v4l2-ctrls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <media/v4l2-fh.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <media/v4l2-event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <media/videobuf-vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /* Version Information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define DRIVER_VERSION "0.7.4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define DRIVER_AUTHOR "Antoine Jacquet, http://royale.zerezo.com/"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define DRIVER_DESC "Zoran 364xx"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* Camera */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define FRAMES 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define MAX_FRAME_SIZE 200000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define BUFFER_SIZE 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define CTRL_TIMEOUT 500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define ZR364XX_DEF_BUFS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define ZR364XX_READ_IDLE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define ZR364XX_READ_FRAME 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* Debug macro */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define DBG(fmt, args...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (debug) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) printk(KERN_INFO KBUILD_MODNAME " " fmt, ##args); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /*#define FULL_DEBUG 1*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #ifdef FULL_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define _DBG DBG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define _DBG(fmt, args...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* Init methods, need to find nicer names for these
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * the exact names of the chipsets would be the best if someone finds it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define METHOD0 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define METHOD1 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define METHOD2 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define METHOD3 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* Module parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static int debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static int mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* Module parameters interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) module_param(debug, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) MODULE_PARM_DESC(debug, "Debug level");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) module_param(mode, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) MODULE_PARM_DESC(mode, "0 = 320x240, 1 = 160x120, 2 = 640x480");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* Devices supported by this driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * .driver_info contains the init method used by the camera */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static const struct usb_device_id device_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {USB_DEVICE(0x08ca, 0x0109), .driver_info = METHOD0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {USB_DEVICE(0x041e, 0x4024), .driver_info = METHOD0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {USB_DEVICE(0x0d64, 0x0108), .driver_info = METHOD0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {USB_DEVICE(0x0546, 0x3187), .driver_info = METHOD0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {USB_DEVICE(0x0d64, 0x3108), .driver_info = METHOD0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {USB_DEVICE(0x0595, 0x4343), .driver_info = METHOD0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {USB_DEVICE(0x0bb0, 0x500d), .driver_info = METHOD0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {USB_DEVICE(0x0feb, 0x2004), .driver_info = METHOD0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {USB_DEVICE(0x055f, 0xb500), .driver_info = METHOD0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {USB_DEVICE(0x08ca, 0x2062), .driver_info = METHOD2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {USB_DEVICE(0x052b, 0x1a18), .driver_info = METHOD1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {USB_DEVICE(0x04c8, 0x0729), .driver_info = METHOD0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {USB_DEVICE(0x04f2, 0xa208), .driver_info = METHOD0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {USB_DEVICE(0x0784, 0x0040), .driver_info = METHOD1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {USB_DEVICE(0x06d6, 0x0034), .driver_info = METHOD0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {USB_DEVICE(0x0a17, 0x0062), .driver_info = METHOD2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {USB_DEVICE(0x08ca, 0x2102), .driver_info = METHOD3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {USB_DEVICE(0x06d6, 0x003d), .driver_info = METHOD0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {} /* Terminating entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) MODULE_DEVICE_TABLE(usb, device_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* frame structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct zr364xx_framei {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) unsigned long ulState; /* ulState:ZR364XX_READ_IDLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) ZR364XX_READ_FRAME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) void *lpvbits; /* image data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) unsigned long cur_size; /* current data copied to it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /* image buffer structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct zr364xx_bufferi {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) unsigned long dwFrames; /* number of frames in buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct zr364xx_framei frame[FRAMES]; /* array of FRAME structures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct zr364xx_dmaqueue {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct list_head active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct zr364xx_camera *cam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct zr364xx_pipeinfo {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) u32 transfer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u8 *transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) u32 state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) void *stream_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) void *cam; /* back pointer to zr364xx_camera struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) u32 err_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct zr364xx_fmt {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) u32 fourcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) int depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /* image formats. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static const struct zr364xx_fmt formats[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .fourcc = V4L2_PIX_FMT_JPEG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .depth = 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* Camera stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct zr364xx_camera {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct usb_device *udev; /* save off the usb device pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct usb_interface *interface;/* the interface for this device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct v4l2_device v4l2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct v4l2_ctrl_handler ctrl_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct video_device vdev; /* v4l video device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct v4l2_fh *owner; /* owns the streaming */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct zr364xx_bufferi buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) int skip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) int width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) int height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) int method;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) spinlock_t slock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct zr364xx_dmaqueue vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) int last_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) int cur_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) unsigned long frame_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) int b_acquire;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct zr364xx_pipeinfo pipe[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) u8 read_endpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) const struct zr364xx_fmt *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct videobuf_queue vb_vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) bool was_streaming;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /* buffer for one video frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct zr364xx_buffer {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* common v4l buffer stuff -- must be first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct videobuf_buffer vb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) const struct zr364xx_fmt *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* function used to send initialisation commands to the camera */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static int send_control_msg(struct usb_device *udev, u8 request, u16 value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) u16 index, unsigned char *cp, u16 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) unsigned char *transfer_buffer = kmemdup(cp, size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (!transfer_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) status = usb_control_msg(udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) usb_sndctrlpipe(udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) USB_DIR_OUT | USB_TYPE_VENDOR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) USB_RECIP_DEVICE, value, index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) transfer_buffer, size, CTRL_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) kfree(transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* Control messages sent to the camera to initialize it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * and launch the capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) typedef struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) unsigned int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) unsigned int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) unsigned char *bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) } message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /* method 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static unsigned char m0d1[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static unsigned char m0d2[] = { 0, 0, 0, 0, 0, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static unsigned char m0d3[] = { 0, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static message m0[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {0x1f30, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {0xd000, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {0x3370, sizeof(m0d1), m0d1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {0x2000, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {0x2f0f, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {0x2610, sizeof(m0d2), m0d2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {0xe107, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {0x2502, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {0x1f70, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {0xd000, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {0x9a01, sizeof(m0d3), m0d3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {-1, -1, NULL}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* method 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static unsigned char m1d1[] = { 0xff, 0xff };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static unsigned char m1d2[] = { 0x00, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static message m1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {0x1f30, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {0xd000, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {0xf000, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {0x2000, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {0x2f0f, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {0x2650, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {0xe107, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {0x2502, sizeof(m1d1), m1d1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {0x1f70, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {0xd000, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {0xd000, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {0xd000, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {0x9a01, sizeof(m1d2), m1d2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {-1, -1, NULL}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* method 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static unsigned char m2d1[] = { 0xff, 0xff };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static message m2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {0x1f30, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {0xf000, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {0x2000, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {0x2f0f, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {0x2650, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {0xe107, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {0x2502, sizeof(m2d1), m2d1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {0x1f70, 0, NULL},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {-1, -1, NULL}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /* init table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static message *init[4] = { m0, m1, m2, m2 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /* JPEG static data in header (Huffman table, etc) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static unsigned char header1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 0xFF, 0xD8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 0xFF, 0xE0, 0x00, 0x10, 'J', 'F', 'I', 'F',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 0x00, 0x01, 0x01, 0x00, 0x33, 0x8A, 0x00, 0x00, 0x33, 0x88,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 0xFF, 0xDB, 0x00, 0x84
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static unsigned char header2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 0xFF, 0xC4, 0x00, 0x1F, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 0xFF, 0xC4, 0x00, 0xB5, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xA1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 0x08, 0x23, 0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24, 0x33,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x25,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 0x26, 0x27, 0x28, 0x29, 0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 0x3A, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0xC4, 0x00, 0x1F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0xFF, 0xC4, 0x00, 0xB5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 0x09, 0x23, 0x33, 0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95, 0x96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 0xF8, 0xF9, 0xFA, 0xFF, 0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 0x40, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 0x00, 0x3F, 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static unsigned char header3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /* ------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) Videobuf operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) ------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) unsigned int *size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) struct zr364xx_camera *cam = vq->priv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) *size = cam->width * cam->height * (cam->fmt->depth >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (*count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) *count = ZR364XX_DEF_BUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (*size * *count > ZR364XX_DEF_BUFS * 1024 * 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) *count = (ZR364XX_DEF_BUFS * 1024 * 1024) / *size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static void free_buffer(struct videobuf_queue *vq, struct zr364xx_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) _DBG("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) BUG_ON(in_interrupt());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) videobuf_vmalloc_free(&buf->vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) buf->vb.state = VIDEOBUF_NEEDS_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) enum v4l2_field field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct zr364xx_camera *cam = vq->priv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) struct zr364xx_buffer *buf = container_of(vb, struct zr364xx_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) DBG("%s, field=%d\n", __func__, field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (!cam->fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) buf->vb.size = cam->width * cam->height * (cam->fmt->depth >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (buf->vb.baddr != 0 && buf->vb.bsize < buf->vb.size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) DBG("invalid buffer prepare\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) buf->fmt = cam->fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) buf->vb.width = cam->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) buf->vb.height = cam->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) buf->vb.field = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (buf->vb.state == VIDEOBUF_NEEDS_INIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) rc = videobuf_iolock(vq, &buf->vb, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) buf->vb.state = VIDEOBUF_PREPARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) free_buffer(vq, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct zr364xx_buffer *buf = container_of(vb, struct zr364xx_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct zr364xx_camera *cam = vq->priv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) _DBG("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) buf->vb.state = VIDEOBUF_QUEUED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) list_add_tail(&buf->vb.queue, &cam->vidq.active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static void buffer_release(struct videobuf_queue *vq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) struct videobuf_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) struct zr364xx_buffer *buf = container_of(vb, struct zr364xx_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) _DBG("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) free_buffer(vq, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) static const struct videobuf_queue_ops zr364xx_video_qops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) .buf_setup = buffer_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) .buf_prepare = buffer_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) .buf_queue = buffer_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) .buf_release = buffer_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /********************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /* V4L2 integration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /********************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static int zr364xx_vidioc_streamon(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) enum v4l2_buf_type type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) loff_t * ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct zr364xx_camera *cam = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) _DBG("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (!count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (mutex_lock_interruptible(&cam->lock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) err = zr364xx_vidioc_streamon(file, file->private_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) V4L2_BUF_TYPE_VIDEO_CAPTURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) DBG("%s: reading %d bytes at pos %d.\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) (int) count, (int) *ppos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) /* NoMan Sux ! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) err = videobuf_read_one(&cam->vb_vidq, buf, count, ppos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) file->f_flags & O_NONBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) mutex_unlock(&cam->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) /* video buffer vmalloc implementation based partly on VIVI driver which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * Copyright (c) 2006 by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * Ted Walther <ted--a.t--enumera.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * John Sokol <sokol--a.t--videotechnology.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * http://v4l.videotechnology.com/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) static void zr364xx_fillbuff(struct zr364xx_camera *cam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) struct zr364xx_buffer *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) int jpgsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) int pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) const char *tmpbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) char *vbuf = videobuf_to_vmalloc(&buf->vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) unsigned long last_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (!vbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) last_frame = cam->last_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (last_frame != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) tmpbuf = (const char *)cam->buffer.frame[last_frame].lpvbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) switch (buf->fmt->fourcc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) case V4L2_PIX_FMT_JPEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) buf->vb.size = jpgsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) memcpy(vbuf, tmpbuf, buf->vb.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) printk(KERN_DEBUG KBUILD_MODNAME ": unknown format?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) cam->last_frame = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) printk(KERN_ERR KBUILD_MODNAME ": =======no frame\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) DBG("%s: Buffer %p size= %d\n", __func__, vbuf, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /* tell v4l buffer was filled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) buf->vb.field_count = cam->frame_count * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) buf->vb.ts = ktime_get_ns();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) buf->vb.state = VIDEOBUF_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) static int zr364xx_got_frame(struct zr364xx_camera *cam, int jpgsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) struct zr364xx_dmaqueue *dma_q = &cam->vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) struct zr364xx_buffer *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) DBG("wakeup: %p\n", &dma_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) spin_lock_irqsave(&cam->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (list_empty(&dma_q->active)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) DBG("No active queue to serve\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) rc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) buf = list_entry(dma_q->active.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) struct zr364xx_buffer, vb.queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (!waitqueue_active(&buf->vb.done)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) /* no one active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) rc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) list_del(&buf->vb.queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) buf->vb.ts = ktime_get_ns();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) DBG("[%p/%d] wakeup\n", buf, buf->vb.i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) zr364xx_fillbuff(cam, buf, jpgsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) wake_up(&buf->vb.done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) DBG("wakeup [buf/i] [%p/%d]\n", buf, buf->vb.i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) spin_unlock_irqrestore(&cam->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) /* this function moves the usb stream read pipe data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * into the system buffers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * returns 0 on success, EAGAIN if more data to process (call this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * function again).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static int zr364xx_read_video_callback(struct zr364xx_camera *cam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) struct zr364xx_pipeinfo *pipe_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) struct urb *purb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) unsigned char *pdest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) unsigned char *psrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) s32 idx = cam->cur_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) struct zr364xx_framei *frm = &cam->buffer.frame[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) unsigned char *ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) _DBG("buffer to user\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /* swap bytes if camera needs it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (cam->method == METHOD0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) u16 *buf = (u16 *)pipe_info->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) for (i = 0; i < purb->actual_length/2; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) swab16s(buf + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) /* search done. now find out if should be acquiring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (!cam->b_acquire) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) /* we found a frame, but this channel is turned off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) frm->ulState = ZR364XX_READ_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) psrc = (u8 *)pipe_info->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) ptr = pdest = frm->lpvbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (frm->ulState == ZR364XX_READ_IDLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (purb->actual_length < 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) /* header incomplete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) dev_info(&cam->udev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) "%s: buffer (%d bytes) too small to hold jpeg header. Discarding.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) __func__, purb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) frm->ulState = ZR364XX_READ_FRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) frm->cur_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) _DBG("jpeg header, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) memcpy(ptr, header1, sizeof(header1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) ptr += sizeof(header1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) header3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) memcpy(ptr, &header3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) memcpy(ptr, psrc, 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) ptr += 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) header3 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) memcpy(ptr, &header3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) memcpy(ptr, psrc + 64, 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) ptr += 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) memcpy(ptr, header2, sizeof(header2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) ptr += sizeof(header2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) memcpy(ptr, psrc + 128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) purb->actual_length - 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) ptr += purb->actual_length - 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) _DBG("header : %d %d %d %d %d %d %d %d %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) psrc[0], psrc[1], psrc[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) psrc[3], psrc[4], psrc[5],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) psrc[6], psrc[7], psrc[8]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) frm->cur_size = ptr - pdest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (frm->cur_size + purb->actual_length > MAX_FRAME_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) dev_info(&cam->udev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) "%s: buffer (%d bytes) too small to hold frame data. Discarding frame data.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) __func__, MAX_FRAME_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) pdest += frm->cur_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) memcpy(pdest, psrc, purb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) frm->cur_size += purb->actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) /*_DBG("cur_size %lu urb size %d\n", frm->cur_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) purb->actual_length);*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (purb->actual_length < pipe_info->transfer_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) _DBG("****************Buffer[%d]full*************\n", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) cam->last_frame = cam->cur_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) cam->cur_frame++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) /* end of system frame ring buffer, start at zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (cam->cur_frame == cam->buffer.dwFrames)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) cam->cur_frame = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) /* frame ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /* go back to find the JPEG EOI marker */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) ptr = pdest = frm->lpvbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) ptr += frm->cur_size - 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) while (ptr > pdest) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (*ptr == 0xFF && *(ptr + 1) == 0xD9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) && *(ptr + 2) == 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) ptr--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (ptr == pdest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) DBG("No EOI marker\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) /* Sometimes there is junk data in the middle of the picture,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * we want to skip this bogus frames */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) while (ptr > pdest) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (*ptr == 0xFF && *(ptr + 1) == 0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) && *(ptr + 2) == 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) ptr--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) if (ptr != pdest) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) DBG("Bogus frame ? %d\n", ++(cam->nb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) } else if (cam->b_acquire) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) /* we skip the 2 first frames which are usually buggy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (cam->skip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) cam->skip--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) _DBG("jpeg(%lu): %d %d %d %d %d %d %d %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) frm->cur_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) pdest[0], pdest[1], pdest[2], pdest[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) pdest[4], pdest[5], pdest[6], pdest[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) zr364xx_got_frame(cam, frm->cur_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) cam->frame_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) frm->ulState = ZR364XX_READ_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) frm->cur_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) /* done successfully */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) static int zr364xx_vidioc_querycap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) struct v4l2_capability *cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) struct zr364xx_camera *cam = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) strscpy(cap->driver, DRIVER_DESC, sizeof(cap->driver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (cam->udev->product)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) strscpy(cap->card, cam->udev->product, sizeof(cap->card));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) strscpy(cap->bus_info, dev_name(&cam->udev->dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) sizeof(cap->bus_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) static int zr364xx_vidioc_enum_input(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) struct v4l2_input *i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (i->index != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) strscpy(i->name, DRIVER_DESC " Camera", sizeof(i->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) i->type = V4L2_INPUT_TYPE_CAMERA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) static int zr364xx_vidioc_g_input(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) unsigned int *i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) *i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static int zr364xx_vidioc_s_input(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) unsigned int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (i != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) static int zr364xx_s_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) struct zr364xx_camera *cam =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) container_of(ctrl->handler, struct zr364xx_camera, ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) int temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) case V4L2_CID_BRIGHTNESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) /* hardware brightness */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) send_control_msg(cam->udev, 1, 0x2001, 0, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) temp = (0x60 << 8) + 127 - ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) send_control_msg(cam->udev, 1, temp, 0, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) static int zr364xx_vidioc_enum_fmt_vid_cap(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) void *priv, struct v4l2_fmtdesc *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (f->index > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) f->pixelformat = formats[0].fourcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) static char *decode_fourcc(__u32 pixelformat, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) buf[0] = pixelformat & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) buf[1] = (pixelformat >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) buf[2] = (pixelformat >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) buf[3] = (pixelformat >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) buf[4] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) static int zr364xx_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) struct zr364xx_camera *cam = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) char pixelformat_name[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (!cam)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) DBG("%s: unsupported pixelformat V4L2_PIX_FMT_%s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) decode_fourcc(f->fmt.pix.pixelformat, pixelformat_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (!(f->fmt.pix.width == 160 && f->fmt.pix.height == 120) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) !(f->fmt.pix.width == 640 && f->fmt.pix.height == 480)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) f->fmt.pix.width = 320;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) f->fmt.pix.height = 240;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) f->fmt.pix.field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) DBG("%s: V4L2_PIX_FMT_%s (%d) ok!\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) decode_fourcc(f->fmt.pix.pixelformat, pixelformat_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) f->fmt.pix.field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct zr364xx_camera *cam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (!file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) cam = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) f->fmt.pix.pixelformat = formats[0].fourcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) f->fmt.pix.field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) f->fmt.pix.width = cam->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) f->fmt.pix.height = cam->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) struct zr364xx_camera *cam = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) struct videobuf_queue *q = &cam->vb_vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) char pixelformat_name[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) int ret = zr364xx_vidioc_try_fmt_vid_cap(file, cam, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) mutex_lock(&q->vb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (videobuf_queue_is_busy(&cam->vb_vidq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) DBG("%s queue busy\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (cam->owner) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) DBG("%s can't change format after started\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) cam->width = f->fmt.pix.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) cam->height = f->fmt.pix.height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) DBG("%s: %dx%d mode selected\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) cam->width, cam->height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) cam->vb_vidq.field = f->fmt.pix.field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (f->fmt.pix.width == 160 && f->fmt.pix.height == 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) mode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) else if (f->fmt.pix.width == 640 && f->fmt.pix.height == 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) mode = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) m0d1[0] = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) m1[2].value = 0xf000 + mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) m2[1].value = 0xf000 + mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) /* special case for METHOD3, the modes are different */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (cam->method == METHOD3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) m2[1].value = 0xf000 + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) m2[1].value = 0xf000 + 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) m2[1].value = 0xf000 + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) header2[437] = cam->height / 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) header2[438] = cam->height % 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) header2[439] = cam->width / 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) header2[440] = cam->width % 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) for (i = 0; init[cam->method][i].size != -1; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) send_control_msg(cam->udev, 1, init[cam->method][i].value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 0, init[cam->method][i].bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) init[cam->method][i].size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) dev_err(&cam->udev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) "error during resolution change sequence: %d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) /* Added some delay here, since opening/closing the camera quickly,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * like Ekiga does during its startup, can crash the webcam
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) mdelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) cam->skip = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) mutex_unlock(&q->vb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) DBG("%s: V4L2_PIX_FMT_%s (%d) ok!\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) decode_fourcc(f->fmt.pix.pixelformat, pixelformat_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) f->fmt.pix.field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) static int zr364xx_vidioc_reqbufs(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) struct v4l2_requestbuffers *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) struct zr364xx_camera *cam = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) if (cam->owner && cam->owner != priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) return videobuf_reqbufs(&cam->vb_vidq, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) static int zr364xx_vidioc_querybuf(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) struct v4l2_buffer *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) struct zr364xx_camera *cam = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) rc = videobuf_querybuf(&cam->vb_vidq, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) static int zr364xx_vidioc_qbuf(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) struct v4l2_buffer *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) struct zr364xx_camera *cam = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) _DBG("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (cam->owner && cam->owner != priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) rc = videobuf_qbuf(&cam->vb_vidq, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) static int zr364xx_vidioc_dqbuf(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) struct v4l2_buffer *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) struct zr364xx_camera *cam = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) _DBG("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (cam->owner && cam->owner != priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) rc = videobuf_dqbuf(&cam->vb_vidq, p, file->f_flags & O_NONBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) static void read_pipe_completion(struct urb *purb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) struct zr364xx_pipeinfo *pipe_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) struct zr364xx_camera *cam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) int pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) pipe_info = purb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) _DBG("%s %p, status %d\n", __func__, purb, purb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if (!pipe_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) printk(KERN_ERR KBUILD_MODNAME ": no context!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) cam = pipe_info->cam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (!cam) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) printk(KERN_ERR KBUILD_MODNAME ": no context!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) /* if shutting down, do not resubmit, exit immediately */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) if (purb->status == -ESHUTDOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) DBG("%s, err shutdown\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) pipe_info->err_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (pipe_info->state == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) DBG("exiting USB pipe\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) if (purb->actual_length > pipe_info->transfer_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) dev_err(&cam->udev->dev, "wrong number of bytes\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) if (purb->status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) zr364xx_read_video_callback(cam, pipe_info, purb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) pipe_info->err_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) DBG("%s: failed URB %d\n", __func__, purb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) pipe = usb_rcvbulkpipe(cam->udev, cam->read_endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) /* reuse urb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) usb_fill_bulk_urb(pipe_info->stream_urb, cam->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) pipe_info->transfer_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) pipe_info->transfer_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) read_pipe_completion, pipe_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) if (pipe_info->state != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) purb->status = usb_submit_urb(pipe_info->stream_urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (purb->status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) dev_err(&cam->udev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) "error submitting urb (error=%i)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) purb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) DBG("read pipe complete state 0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) static int zr364xx_start_readpipe(struct zr364xx_camera *cam)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) int pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) struct zr364xx_pipeinfo *pipe_info = cam->pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) pipe = usb_rcvbulkpipe(cam->udev, cam->read_endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) DBG("%s: start pipe IN x%x\n", __func__, cam->read_endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) pipe_info->state = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) pipe_info->err_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) if (!pipe_info->stream_urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) /* transfer buffer allocated in board_init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) usb_fill_bulk_urb(pipe_info->stream_urb, cam->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) pipe_info->transfer_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) pipe_info->transfer_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) read_pipe_completion, pipe_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) DBG("submitting URB %p\n", pipe_info->stream_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) usb_free_urb(pipe_info->stream_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) printk(KERN_ERR KBUILD_MODNAME ": start read pipe failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) static void zr364xx_stop_readpipe(struct zr364xx_camera *cam)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) struct zr364xx_pipeinfo *pipe_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (!cam) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) printk(KERN_ERR KBUILD_MODNAME ": invalid device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) DBG("stop read pipe\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) pipe_info = cam->pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (pipe_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (pipe_info->state != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) pipe_info->state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) if (pipe_info->stream_urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) /* cancel urb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) usb_kill_urb(pipe_info->stream_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) usb_free_urb(pipe_info->stream_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) pipe_info->stream_urb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) /* starts acquisition process */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) static int zr364xx_start_acquire(struct zr364xx_camera *cam)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) DBG("start acquire\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) cam->last_frame = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) cam->cur_frame = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) for (j = 0; j < FRAMES; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) cam->buffer.frame[j].ulState = ZR364XX_READ_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) cam->buffer.frame[j].cur_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) cam->b_acquire = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) static inline int zr364xx_stop_acquire(struct zr364xx_camera *cam)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) cam->b_acquire = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) static int zr364xx_prepare(struct zr364xx_camera *cam)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) for (i = 0; init[cam->method][i].size != -1; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) res = send_control_msg(cam->udev, 1, init[cam->method][i].value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 0, init[cam->method][i].bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) init[cam->method][i].size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (res < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) dev_err(&cam->udev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) "error during open sequence: %d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) cam->skip = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) cam->last_frame = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) cam->cur_frame = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) cam->frame_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) for (j = 0; j < FRAMES; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) cam->buffer.frame[j].ulState = ZR364XX_READ_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) cam->buffer.frame[j].cur_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) v4l2_ctrl_handler_setup(&cam->ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) static int zr364xx_vidioc_streamon(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) enum v4l2_buf_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) struct zr364xx_camera *cam = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) DBG("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) if (cam->owner && cam->owner != priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) res = zr364xx_prepare(cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) res = videobuf_streamon(&cam->vb_vidq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if (res == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) zr364xx_start_acquire(cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) cam->owner = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) static int zr364xx_vidioc_streamoff(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) enum v4l2_buf_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) struct zr364xx_camera *cam = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) DBG("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) if (cam->owner && cam->owner != priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) zr364xx_stop_acquire(cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) return videobuf_streamoff(&cam->vb_vidq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) /* open the camera */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) static int zr364xx_open(struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) struct zr364xx_camera *cam = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) DBG("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) if (mutex_lock_interruptible(&cam->lock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) err = v4l2_fh_open(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) /* Added some delay here, since opening/closing the camera quickly,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) * like Ekiga does during its startup, can crash the webcam
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) mdelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) mutex_unlock(&cam->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) DBG("%s: %d\n", __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) static void zr364xx_board_uninit(struct zr364xx_camera *cam)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) unsigned long i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) zr364xx_stop_readpipe(cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) /* release sys buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) for (i = 0; i < FRAMES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) if (cam->buffer.frame[i].lpvbits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) DBG("vfree %p\n", cam->buffer.frame[i].lpvbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) vfree(cam->buffer.frame[i].lpvbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) cam->buffer.frame[i].lpvbits = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) /* release transfer buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) kfree(cam->pipe->transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) static void zr364xx_release(struct v4l2_device *v4l2_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) struct zr364xx_camera *cam =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) container_of(v4l2_dev, struct zr364xx_camera, v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) videobuf_mmap_free(&cam->vb_vidq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) v4l2_ctrl_handler_free(&cam->ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) zr364xx_board_uninit(cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) v4l2_device_unregister(&cam->v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) kfree(cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) /* release the camera */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) static int zr364xx_close(struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) struct zr364xx_camera *cam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) struct usb_device *udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) DBG("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) cam = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) mutex_lock(&cam->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) udev = cam->udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) if (file->private_data == cam->owner) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) /* turn off stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) if (cam->b_acquire)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) zr364xx_stop_acquire(cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) videobuf_streamoff(&cam->vb_vidq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) send_control_msg(udev, 1, init[cam->method][i].value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 0, init[cam->method][i].bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) init[cam->method][i].size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) cam->owner = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) /* Added some delay here, since opening/closing the camera quickly,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) * like Ekiga does during its startup, can crash the webcam
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) mdelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) mutex_unlock(&cam->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) return v4l2_fh_release(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) static int zr364xx_mmap(struct file *file, struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) struct zr364xx_camera *cam = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) if (!cam) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) DBG("%s: cam == NULL\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) DBG("mmap called, vma=%p\n", vma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) ret = videobuf_mmap_mapper(&cam->vb_vidq, vma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) DBG("vma start=0x%08lx, size=%ld, ret=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) (unsigned long)vma->vm_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) static __poll_t zr364xx_poll(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) struct poll_table_struct *wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) struct zr364xx_camera *cam = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) struct videobuf_queue *q = &cam->vb_vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) __poll_t res = v4l2_ctrl_poll(file, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) _DBG("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) return res | videobuf_poll_stream(file, q, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) static const struct v4l2_ctrl_ops zr364xx_ctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) .s_ctrl = zr364xx_s_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) static const struct v4l2_file_operations zr364xx_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) .open = zr364xx_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) .release = zr364xx_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) .read = zr364xx_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) .mmap = zr364xx_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) .unlocked_ioctl = video_ioctl2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) .poll = zr364xx_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) .vidioc_querycap = zr364xx_vidioc_querycap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) .vidioc_enum_fmt_vid_cap = zr364xx_vidioc_enum_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) .vidioc_try_fmt_vid_cap = zr364xx_vidioc_try_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) .vidioc_s_fmt_vid_cap = zr364xx_vidioc_s_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) .vidioc_g_fmt_vid_cap = zr364xx_vidioc_g_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) .vidioc_enum_input = zr364xx_vidioc_enum_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) .vidioc_g_input = zr364xx_vidioc_g_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) .vidioc_s_input = zr364xx_vidioc_s_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) .vidioc_streamon = zr364xx_vidioc_streamon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) .vidioc_streamoff = zr364xx_vidioc_streamoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) .vidioc_reqbufs = zr364xx_vidioc_reqbufs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) .vidioc_querybuf = zr364xx_vidioc_querybuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) .vidioc_qbuf = zr364xx_vidioc_qbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) .vidioc_dqbuf = zr364xx_vidioc_dqbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) .vidioc_log_status = v4l2_ctrl_log_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) static const struct video_device zr364xx_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) .name = DRIVER_DESC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) .fops = &zr364xx_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) .ioctl_ops = &zr364xx_ioctl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) .release = video_device_release_empty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) .device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) V4L2_CAP_STREAMING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) /*******************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) /* USB integration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) /*******************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) static int zr364xx_board_init(struct zr364xx_camera *cam)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) struct zr364xx_pipeinfo *pipe = cam->pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) unsigned long i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) DBG("board init: %p\n", cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) memset(pipe, 0, sizeof(*pipe));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) pipe->cam = cam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) pipe->transfer_size = BUFFER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) pipe->transfer_buffer = kzalloc(pipe->transfer_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) if (!pipe->transfer_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) DBG("out of memory!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) cam->b_acquire = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) cam->frame_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) /*** start create system buffers ***/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) for (i = 0; i < FRAMES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) /* always allocate maximum size for system buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) cam->buffer.frame[i].lpvbits = vmalloc(MAX_FRAME_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) DBG("valloc %p, idx %lu, pdata %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) &cam->buffer.frame[i], i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) cam->buffer.frame[i].lpvbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) if (!cam->buffer.frame[i].lpvbits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) printk(KERN_INFO KBUILD_MODNAME ": out of memory. Using less frames\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) if (i == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) printk(KERN_INFO KBUILD_MODNAME ": out of memory. Aborting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) cam->buffer.dwFrames = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) /* make sure internal states are set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) for (i = 0; i < FRAMES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) cam->buffer.frame[i].ulState = ZR364XX_READ_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) cam->buffer.frame[i].cur_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) cam->cur_frame = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) cam->last_frame = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) /*** end create system buffers ***/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) /* start read pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) err = zr364xx_start_readpipe(cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) goto err_free_frames;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) DBG(": board initialized\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) err_free_frames:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) for (i = 0; i < FRAMES; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) vfree(cam->buffer.frame[i].lpvbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) err_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) kfree(cam->pipe->transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) cam->pipe->transfer_buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) static int zr364xx_probe(struct usb_interface *intf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) struct usb_device *udev = interface_to_usbdev(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) struct zr364xx_camera *cam = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) struct usb_host_interface *iface_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) struct usb_endpoint_descriptor *endpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) struct v4l2_ctrl_handler *hdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) DBG("probing...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) dev_info(&intf->dev, DRIVER_DESC " compatible webcam plugged\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) dev_info(&intf->dev, "model %04x:%04x detected\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) le16_to_cpu(udev->descriptor.idVendor),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) le16_to_cpu(udev->descriptor.idProduct));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) cam = kzalloc(sizeof(*cam), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) if (!cam)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) err = v4l2_device_register(&intf->dev, &cam->v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) dev_err(&udev->dev, "couldn't register v4l2_device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) goto free_cam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) hdl = &cam->ctrl_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) v4l2_ctrl_handler_init(hdl, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) v4l2_ctrl_new_std(hdl, &zr364xx_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) V4L2_CID_BRIGHTNESS, 0, 127, 1, 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) if (hdl->error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) err = hdl->error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) dev_err(&udev->dev, "couldn't register control\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) goto free_hdlr_and_unreg_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) /* save the init method used by this camera */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) cam->method = id->driver_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) mutex_init(&cam->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) cam->vdev = zr364xx_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) cam->vdev.lock = &cam->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) cam->vdev.v4l2_dev = &cam->v4l2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) cam->vdev.ctrl_handler = &cam->ctrl_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) video_set_drvdata(&cam->vdev, cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) cam->udev = udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) dev_info(&udev->dev, "160x120 mode selected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) cam->width = 160;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) cam->height = 120;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) dev_info(&udev->dev, "640x480 mode selected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) cam->width = 640;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) cam->height = 480;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) dev_info(&udev->dev, "320x240 mode selected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) cam->width = 320;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) cam->height = 240;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) m0d1[0] = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) m1[2].value = 0xf000 + mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) m2[1].value = 0xf000 + mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) /* special case for METHOD3, the modes are different */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) if (cam->method == METHOD3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) m2[1].value = 0xf000 + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) m2[1].value = 0xf000 + 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) m2[1].value = 0xf000 + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) header2[437] = cam->height / 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) header2[438] = cam->height % 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) header2[439] = cam->width / 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) header2[440] = cam->width % 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) cam->nb = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) DBG("dev: %p, udev %p interface %p\n", cam, cam->udev, intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) /* set up the endpoint information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) iface_desc = intf->cur_altsetting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) DBG("num endpoints %d\n", iface_desc->desc.bNumEndpoints);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) endpoint = &iface_desc->endpoint[i].desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) if (!cam->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) /* we found the bulk in endpoint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) cam->read_endpoint = endpoint->bEndpointAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) if (!cam->read_endpoint) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) dev_err(&intf->dev, "Could not find bulk-in endpoint\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) goto free_hdlr_and_unreg_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) /* v4l */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) INIT_LIST_HEAD(&cam->vidq.active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) cam->vidq.cam = cam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) usb_set_intfdata(intf, cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) /* load zr364xx board specific */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) err = zr364xx_board_init(cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) goto free_hdlr_and_unreg_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) err = v4l2_ctrl_handler_setup(hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) goto board_uninit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) spin_lock_init(&cam->slock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) cam->fmt = formats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) videobuf_queue_vmalloc_init(&cam->vb_vidq, &zr364xx_video_qops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) NULL, &cam->slock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) V4L2_BUF_TYPE_VIDEO_CAPTURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) V4L2_FIELD_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) sizeof(struct zr364xx_buffer), cam, &cam->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) err = video_register_device(&cam->vdev, VFL_TYPE_VIDEO, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) dev_err(&udev->dev, "video_register_device failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) goto board_uninit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) cam->v4l2_dev.release = zr364xx_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) dev_info(&udev->dev, DRIVER_DESC " controlling device %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) video_device_node_name(&cam->vdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) board_uninit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) zr364xx_board_uninit(cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) free_hdlr_and_unreg_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) v4l2_ctrl_handler_free(hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) v4l2_device_unregister(&cam->v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) free_cam:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) kfree(cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) static void zr364xx_disconnect(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) struct zr364xx_camera *cam = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) mutex_lock(&cam->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) usb_set_intfdata(intf, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) dev_info(&intf->dev, DRIVER_DESC " webcam unplugged\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) video_unregister_device(&cam->vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) v4l2_device_disconnect(&cam->v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) /* stops the read pipe if it is running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) if (cam->b_acquire)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) zr364xx_stop_acquire(cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) zr364xx_stop_readpipe(cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) mutex_unlock(&cam->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) v4l2_device_put(&cam->v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) static int zr364xx_suspend(struct usb_interface *intf, pm_message_t message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) struct zr364xx_camera *cam = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) cam->was_streaming = cam->b_acquire;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) if (!cam->was_streaming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) zr364xx_stop_acquire(cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) zr364xx_stop_readpipe(cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) static int zr364xx_resume(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) struct zr364xx_camera *cam = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) if (!cam->was_streaming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) res = zr364xx_start_readpipe(cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) res = zr364xx_prepare(cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) goto err_prepare;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) zr364xx_start_acquire(cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) err_prepare:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) zr364xx_stop_readpipe(cam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) /**********************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) /* Module integration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) /**********************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) static struct usb_driver zr364xx_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) .name = "zr364xx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) .probe = zr364xx_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) .disconnect = zr364xx_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) .suspend = zr364xx_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) .resume = zr364xx_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) .reset_resume = zr364xx_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) .id_table = device_table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) module_usb_driver(zr364xx_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) MODULE_AUTHOR(DRIVER_AUTHOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) MODULE_DESCRIPTION(DRIVER_DESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) MODULE_VERSION(DRIVER_VERSION);