^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) * s2255drv.c - a driver for the Sensoray 2255 USB video capture device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2007-2014 by Sensoray Company Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Dean Anderson
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Some video buffer code based on vivi driver:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Sensoray 2255 device supports 4 simultaneous channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * The channels are not "crossbar" inputs, they are physically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * attached to separate video decoders.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Because of USB2.0 bandwidth limitations. There is only a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * certain amount of data which may be transferred at one time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Example maximum bandwidth utilization:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * -full size, color mode YUYV or YUV422P: 2 channels at once
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * -full or half size Grey scale: all 4 channels at once
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * -half size, color mode YUYV or YUV422P: all 4 channels at once
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * -full size, color mode YUYV or YUV422P 1/2 frame rate: all 4 channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * at once.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/videodev2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <media/videobuf2-v4l2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <media/videobuf2-vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <media/v4l2-common.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <media/v4l2-device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <media/v4l2-ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <media/v4l2-ctrls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <media/v4l2-event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define S2255_VERSION "1.25.1"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define FIRMWARE_FILE_NAME "f2255usb.bin"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* default JPEG quality */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define S2255_DEF_JPEG_QUAL 50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* vendor request in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define S2255_VR_IN 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* vendor request out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define S2255_VR_OUT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* firmware query */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define S2255_VR_FW 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /* USB endpoint number for configuring the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define S2255_CONFIG_EP 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* maximum time for DSP to start responding after last FW word loaded(ms) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define S2255_DSP_BOOTTIME 800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* maximum time to wait for firmware to load (ms) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define S2255_MIN_BUFS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define S2255_SETMODE_TIMEOUT 500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define S2255_VIDSTATUS_TIMEOUT 350
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define S2255_MARKER_FRAME cpu_to_le32(0x2255DA4AL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define S2255_MARKER_RESPONSE cpu_to_le32(0x2255ACACL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define S2255_RESPONSE_SETMODE cpu_to_le32(0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define S2255_RESPONSE_FW cpu_to_le32(0x10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define S2255_RESPONSE_STATUS cpu_to_le32(0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define S2255_USB_XFER_SIZE (16 * 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define MAX_CHANNELS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define SYS_FRAMES 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* maximum size is PAL full size plus room for the marker header(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define DEF_USB_BLOCK S2255_USB_XFER_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define LINE_SZ_4CIFS_NTSC 640
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define LINE_SZ_2CIFS_NTSC 640
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define LINE_SZ_1CIFS_NTSC 320
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define LINE_SZ_4CIFS_PAL 704
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define LINE_SZ_2CIFS_PAL 704
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define LINE_SZ_1CIFS_PAL 352
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define NUM_LINES_4CIFS_NTSC 240
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define NUM_LINES_2CIFS_NTSC 240
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define NUM_LINES_1CIFS_NTSC 240
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define NUM_LINES_4CIFS_PAL 288
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define NUM_LINES_2CIFS_PAL 288
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define NUM_LINES_1CIFS_PAL 288
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define LINE_SZ_DEF 640
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define NUM_LINES_DEF 240
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* predefined settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define FORMAT_NTSC 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define FORMAT_PAL 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /* SCALE_4CIFSI is the 2 fields interpolated into one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define COLOR_YUVPL 1 /* YUV planar */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define COLOR_YUVPK 2 /* YUV packed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define COLOR_Y8 4 /* monochrome */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define COLOR_JPG 5 /* JPEG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define MASK_COLOR 0x000000ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define MASK_JPG_QUALITY 0x0000ff00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define MASK_INPUT_TYPE 0x000f0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* frame decimation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define FDEC_1 1 /* capture every frame. default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define FDEC_2 2 /* capture every 2nd frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define FDEC_3 3 /* capture every 3rd frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define FDEC_5 5 /* capture every 5th frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*-------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * Default mode parameters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) *-------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define DEF_SCALE SCALE_4CIFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define DEF_COLOR COLOR_YUVPL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define DEF_FDEC FDEC_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define DEF_BRIGHT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define DEF_CONTRAST 0x5c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define DEF_SATURATION 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define DEF_HUE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* usb config commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define IN_DATA_TOKEN cpu_to_le32(0x2255c0de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define CMD_2255 0xc2255000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define CMD_SET_MODE cpu_to_le32((CMD_2255 | 0x10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define CMD_START cpu_to_le32((CMD_2255 | 0x20))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define CMD_STOP cpu_to_le32((CMD_2255 | 0x30))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define CMD_STATUS cpu_to_le32((CMD_2255 | 0x40))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct s2255_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u32 format; /* input video format (NTSC, PAL) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) u32 scale; /* output video scale */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) u32 color; /* output video color format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) u32 fdec; /* frame decimation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) u32 bright; /* brightness */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) u32 contrast; /* contrast */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) u32 saturation; /* saturation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) u32 hue; /* hue (NTSC only)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) u32 single; /* capture 1 frame at a time (!=0), continuously (==0)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) u32 usb_block; /* block size. should be 4096 of DEF_USB_BLOCK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) u32 restart; /* if DSP requires restart */
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define S2255_READ_IDLE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define S2255_READ_FRAME 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* frame structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct s2255_framei {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) unsigned long size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) unsigned long ulState; /* ulState:S2255_READ_IDLE, S2255_READ_FRAME*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) void *lpvbits; /* image data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) unsigned long cur_size; /* current data copied to it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* image buffer structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct s2255_bufferi {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) unsigned long dwFrames; /* number of frames in buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) DEF_HUE, 0, DEF_USB_BLOCK, 0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /* for firmware loading, fw_state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define S2255_FW_NOTLOADED 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define S2255_FW_LOADED_DSPWAIT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define S2255_FW_SUCCESS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define S2255_FW_FAILED 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define S2255_FW_DISCONNECTING 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define S2255_FW_MARKER cpu_to_le32(0x22552f2f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /* 2255 read states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define S2255_READ_IDLE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #define S2255_READ_FRAME 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct s2255_fw {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) int fw_loaded;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int fw_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct urb *fw_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) atomic_t fw_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) void *pfw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) wait_queue_head_t wait_fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) const struct firmware *fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct s2255_pipeinfo {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) u32 max_transfer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) u32 cur_transfer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) u8 *transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) u32 state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) void *stream_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) void *dev; /* back pointer to s2255_dev struct*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) u32 err_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct s2255_fmt; /*forward declaration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct s2255_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* 2255 video channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct s2255_vc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct s2255_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) struct video_device vdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct v4l2_ctrl_handler hdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct v4l2_ctrl *jpegqual_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) int resources;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct list_head buf_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct s2255_bufferi buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct s2255_mode mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) v4l2_std_id std;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* jpeg compression */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) unsigned jpegqual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /* capture parameters (for high quality mode full size) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct v4l2_captureparm cap_parm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) int cur_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) int last_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /* allocated image size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) unsigned long req_image_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* received packet size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) unsigned long pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) int bad_payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) unsigned long frame_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /* if JPEG image */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) int jpg_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) /* if channel configured to default state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) int configured;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) wait_queue_head_t wait_setmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) int setmode_ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /* video status items */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) int vidstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) wait_queue_head_t wait_vidstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) int vidstatus_ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) unsigned int width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) unsigned int height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) enum v4l2_field field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) const struct s2255_fmt *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int idx; /* channel number on device, 0-3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct vb2_queue vb_vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct mutex vb_lock; /* streaming lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) spinlock_t qlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct s2255_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct s2255_vc vc[MAX_CHANNELS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct v4l2_device v4l2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) atomic_t num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) int frames;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct mutex lock; /* channels[].vdev.lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct mutex cmdlock; /* protects cmdbuf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct usb_device *udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct usb_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) u8 read_endpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct timer_list timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct s2255_fw *fw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct s2255_pipeinfo pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) u32 cc; /* current channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) int frame_ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) int chn_ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /* dsp firmware version (f2255usb.bin) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) int dsp_fw_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) u16 pid; /* product id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) #define S2255_CMDBUF_SIZE 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) __le32 *cmdbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static inline struct s2255_dev *to_s2255_dev(struct v4l2_device *v4l2_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return container_of(v4l2_dev, struct s2255_dev, v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct s2255_fmt {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) u32 fourcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) int depth;
^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) /* buffer for one video frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct s2255_buffer {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /* common v4l buffer stuff -- must be first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct vb2_v4l2_buffer vb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /* current cypress EEPROM firmware version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) #define S2255_CUR_USB_FWVER ((3 << 8) | 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /* current DSP FW version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) #define S2255_CUR_DSP_FWVER 10104
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /* Need DSP version 5+ for video status feature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) #define S2255_MIN_DSP_STATUS 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) #define S2255_MIN_DSP_COLORFILTER 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) #define S2255_NORMS (V4L2_STD_ALL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) /* private V4L2 controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * The following chart displays how COLORFILTER should be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * =========================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * = fourcc = COLORFILTER =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * = ===============================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * = = 0 = 1 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * =========================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * = V4L2_PIX_FMT_GREY(Y8) = monochrome from = monochrome=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * = = s-video or = composite =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * = = B/W camera = input =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * =========================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * = other = color, svideo = color, =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * = = = composite =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * =========================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * channels 0-3 on 2255 are composite
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * channels 0-1 on 2257 are composite, 2-3 are s-video
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * If COLORFILTER is 0 with a composite color camera connected,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * the output will appear monochrome but hatching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * will occur.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * COLORFILTER is different from "color killer" and "color effects"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * for reasons above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) #define S2255_V4L2_YC_ON 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) #define S2255_V4L2_YC_OFF 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) #define V4L2_CID_S2255_COLORFILTER (V4L2_CID_USER_S2255_BASE + 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /* frame prefix size (sent once every frame) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) #define PREFIX_SIZE 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) /* Channels on box are in reverse order */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static int debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static int s2255_start_readpipe(struct s2255_dev *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) static void s2255_stop_readpipe(struct s2255_dev *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static int s2255_start_acquire(struct s2255_vc *vc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static int s2255_stop_acquire(struct s2255_vc *vc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static void s2255_fillbuff(struct s2255_vc *vc, struct s2255_buffer *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) int jpgsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static int s2255_set_mode(struct s2255_vc *vc, struct s2255_mode *mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static int s2255_board_shutdown(struct s2255_dev *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static void s2255_fwload_start(struct s2255_dev *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static void s2255_destroy(struct s2255_dev *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) u16 index, u16 value, void *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) s32 buf_len, int bOut);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /* dev_err macro with driver name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) #define S2255_DRIVER_NAME "s2255"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) #define s2255_dev_err(dev, fmt, arg...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) #define dprintk(dev, level, fmt, arg...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static struct usb_driver s2255_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /* start video number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* Enable jpeg capture. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static int jpeg_enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) module_param(debug, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) module_param(video_nr, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) module_param(jpeg_enable, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* USB device table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) #define USB_SENSORAY_VID 0x1943
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) static const struct usb_device_id s2255_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {USB_DEVICE(USB_SENSORAY_VID, 0x2255)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {USB_DEVICE(USB_SENSORAY_VID, 0x2257)}, /*same family as 2255*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) { } /* Terminating entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) MODULE_DEVICE_TABLE(usb, s2255_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) #define BUFFER_TIMEOUT msecs_to_jiffies(400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* image formats. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /* JPEG formats must be defined last to support jpeg_enable parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static const struct s2255_fmt formats[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) .fourcc = V4L2_PIX_FMT_YUYV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) .depth = 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) .fourcc = V4L2_PIX_FMT_UYVY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) .depth = 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) .fourcc = V4L2_PIX_FMT_YUV422P,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) .depth = 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) .fourcc = V4L2_PIX_FMT_GREY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) .depth = 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) .fourcc = V4L2_PIX_FMT_JPEG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) .depth = 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) .fourcc = V4L2_PIX_FMT_MJPEG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) .depth = 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) static int norm_maxw(struct s2255_vc *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return (vc->std & V4L2_STD_525_60) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL;
^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 int norm_maxh(struct s2255_vc *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return (vc->std & V4L2_STD_525_60) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static int norm_minw(struct s2255_vc *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return (vc->std & V4L2_STD_525_60) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) static int norm_minh(struct s2255_vc *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return (vc->std & V4L2_STD_525_60) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * TODO: fixme: move YUV reordering to hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * converts 2255 planar format to yuyv or uyvy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static void planar422p_to_yuv_packed(const unsigned char *in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) unsigned char *out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) int width, int height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) int fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) unsigned char *pY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) unsigned char *pCb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) unsigned char *pCr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) unsigned long size = height * width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) pY = (unsigned char *)in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) pCr = (unsigned char *)in + height * width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) pCb = (unsigned char *)in + height * width + (height * width / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) for (i = 0; i < size * 2; i += 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) static void s2255_reset_dsppower(struct s2255_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) s2255_vendor_req(dev, 0x40, 0x0000, 0x0001, NULL, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) msleep(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) msleep(600);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) /* kickstarts the firmware loading. from probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) static void s2255_timer(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) struct s2255_dev *dev = from_timer(dev, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) struct s2255_fw *data = dev->fw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) pr_err("s2255: can't submit urb\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) atomic_set(&data->fw_state, S2255_FW_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /* wake up anything waiting for the firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) wake_up(&data->wait_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* this loads the firmware asynchronously.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) Originally this was done synchronously in probe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) But it is better to load it asynchronously here than block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) inside the probe function. Blocking inside probe affects boot time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) FW loading is triggered by the timer in the probe function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) static void s2255_fwchunk_complete(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) struct s2255_fw *data = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) struct usb_device *udev = urb->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (urb->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) atomic_set(&data->fw_state, S2255_FW_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) /* wake up anything waiting for the firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) wake_up(&data->wait_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (data->fw_urb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) s2255_dev_err(&udev->dev, "disconnected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) atomic_set(&data->fw_state, S2255_FW_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /* wake up anything waiting for the firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) wake_up(&data->wait_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) #define CHUNK_SIZE 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) /* all USB transfers must be done with continuous kernel memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) can't allocate more than 128k in current linux kernel, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) upload the firmware in chunks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (data->fw_loaded < data->fw_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) data->fw_size % CHUNK_SIZE : CHUNK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (len < CHUNK_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) memset(data->pfw_data, 0, CHUNK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) memcpy(data->pfw_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) (char *) data->fw->data + data->fw_loaded, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) data->pfw_data, CHUNK_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) s2255_fwchunk_complete, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) dev_err(&udev->dev, "failed submit URB\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) atomic_set(&data->fw_state, S2255_FW_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) /* wake up anything waiting for the firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) wake_up(&data->wait_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) data->fw_loaded += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) static void s2255_got_frame(struct s2255_vc *vc, int jpgsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) struct s2255_buffer *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) spin_lock_irqsave(&vc->qlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (list_empty(&vc->buf_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) dprintk(dev, 1, "No active queue to serve\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) spin_unlock_irqrestore(&vc->qlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) buf = list_entry(vc->buf_list.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) struct s2255_buffer, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) list_del(&buf->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) buf->vb.vb2_buf.timestamp = ktime_get_ns();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) buf->vb.field = vc->field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) buf->vb.sequence = vc->frame_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) spin_unlock_irqrestore(&vc->qlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) s2255_fillbuff(vc, buf, jpgsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /* tell v4l buffer was filled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) dprintk(dev, 2, "%s: [buf] [%p]\n", __func__, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) static const struct s2255_fmt *format_by_fourcc(int fourcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) for (i = 0; i < ARRAY_SIZE(formats); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (-1 == formats[i].fourcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (formats[i].fourcc == fourcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return formats + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) /* video buffer vmalloc implementation based partly on VIVI driver which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) * Copyright (c) 2006 by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * Mauro Carvalho Chehab <mchehab--a.t--infradead.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) * Ted Walther <ted--a.t--enumera.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) * John Sokol <sokol--a.t--videotechnology.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) * http://v4l.videotechnology.com/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static void s2255_fillbuff(struct s2255_vc *vc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) struct s2255_buffer *buf, int jpgsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) int pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) const char *tmpbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) char *vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) unsigned long last_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) struct s2255_dev *dev = vc->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (!vbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) last_frame = vc->last_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (last_frame != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) tmpbuf =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) (const char *)vc->buffer.frame[last_frame].lpvbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) switch (vc->fmt->fourcc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) case V4L2_PIX_FMT_YUYV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) case V4L2_PIX_FMT_UYVY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) planar422p_to_yuv_packed((const unsigned char *)tmpbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) vbuf, vc->width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) vc->height,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) vc->fmt->fourcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) case V4L2_PIX_FMT_GREY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) memcpy(vbuf, tmpbuf, vc->width * vc->height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) case V4L2_PIX_FMT_JPEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) case V4L2_PIX_FMT_MJPEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) vb2_set_plane_payload(&buf->vb.vb2_buf, 0, jpgsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) memcpy(vbuf, tmpbuf, jpgsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) case V4L2_PIX_FMT_YUV422P:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) memcpy(vbuf, tmpbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) vc->width * vc->height * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) pr_info("s2255: unknown format?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) vc->last_frame = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) pr_err("s2255: =======no frame\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) dprintk(dev, 2, "s2255fill at : Buffer %p size= %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) vbuf, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /* ------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) Videobuf operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) ------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) static int queue_setup(struct vb2_queue *vq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) unsigned int *nbuffers, unsigned int *nplanes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) unsigned int sizes[], struct device *alloc_devs[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) struct s2255_vc *vc = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (*nbuffers < S2255_MIN_BUFS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) *nbuffers = S2255_MIN_BUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) *nplanes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) sizes[0] = vc->width * vc->height * (vc->fmt->depth >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) static int buffer_prepare(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) struct s2255_vc *vc = vb2_get_drv_priv(vb->vb2_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) struct s2255_buffer *buf = container_of(vbuf, struct s2255_buffer, vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) int w = vc->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) int h = vc->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) unsigned long size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) dprintk(vc->dev, 4, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (vc->fmt == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if ((w < norm_minw(vc)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) (w > norm_maxw(vc)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) (h < norm_minh(vc)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) (h > norm_maxh(vc))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) dprintk(vc->dev, 4, "invalid buffer prepare\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) size = w * h * (vc->fmt->depth >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (vb2_plane_size(vb, 0) < size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) dprintk(vc->dev, 4, "invalid buffer prepare\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) static void buffer_queue(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct s2255_buffer *buf = container_of(vbuf, struct s2255_buffer, vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) struct s2255_vc *vc = vb2_get_drv_priv(vb->vb2_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) dprintk(vc->dev, 1, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) spin_lock_irqsave(&vc->qlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) list_add_tail(&buf->list, &vc->buf_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) spin_unlock_irqrestore(&vc->qlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) static int start_streaming(struct vb2_queue *vq, unsigned int count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) static void stop_streaming(struct vb2_queue *vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) static const struct vb2_ops s2255_video_qops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) .queue_setup = queue_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) .buf_prepare = buffer_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) .buf_queue = buffer_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) .start_streaming = start_streaming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) .stop_streaming = stop_streaming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) .wait_prepare = vb2_ops_wait_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) .wait_finish = vb2_ops_wait_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) static int vidioc_querycap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) struct v4l2_capability *cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) struct s2255_vc *vc = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) struct s2255_dev *dev = vc->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) strscpy(cap->driver, "s2255", sizeof(cap->driver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) strscpy(cap->card, "s2255", sizeof(cap->card));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) struct v4l2_fmtdesc *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) int index = f->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (index >= ARRAY_SIZE(formats))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) f->pixelformat = formats[index].fourcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) struct s2255_vc *vc = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) int is_ntsc = vc->std & V4L2_STD_525_60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) f->fmt.pix.width = vc->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) f->fmt.pix.height = vc->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (f->fmt.pix.height >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) (is_ntsc ? NUM_LINES_1CIFS_NTSC : NUM_LINES_1CIFS_PAL) * 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) f->fmt.pix.field = V4L2_FIELD_INTERLACED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) f->fmt.pix.field = V4L2_FIELD_TOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) f->fmt.pix.pixelformat = vc->fmt->fourcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) f->fmt.pix.bytesperline = f->fmt.pix.width * (vc->fmt->depth >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) const struct s2255_fmt *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) enum v4l2_field field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) struct s2255_vc *vc = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) int is_ntsc = vc->std & V4L2_STD_525_60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) fmt = format_by_fourcc(f->fmt.pix.pixelformat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (fmt == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) field = f->fmt.pix.field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) dprintk(vc->dev, 50, "%s NTSC: %d suggested width: %d, height: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) __func__, is_ntsc, f->fmt.pix.width, f->fmt.pix.height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (is_ntsc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) /* NTSC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) field = V4L2_FIELD_INTERLACED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) f->fmt.pix.height = NUM_LINES_1CIFS_NTSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) field = V4L2_FIELD_TOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) f->fmt.pix.width = LINE_SZ_4CIFS_NTSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) f->fmt.pix.width = LINE_SZ_1CIFS_NTSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /* PAL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) field = V4L2_FIELD_INTERLACED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) f->fmt.pix.height = NUM_LINES_1CIFS_PAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) field = V4L2_FIELD_TOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) f->fmt.pix.width = LINE_SZ_4CIFS_PAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) f->fmt.pix.width = LINE_SZ_1CIFS_PAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) f->fmt.pix.field = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) dprintk(vc->dev, 50, "%s: set width %d height %d field %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
^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 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 s2255_vc *vc = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) const struct s2255_fmt *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) struct vb2_queue *q = &vc->vb_vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) struct s2255_mode mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) ret = vidioc_try_fmt_vid_cap(file, vc, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) fmt = format_by_fourcc(f->fmt.pix.pixelformat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (fmt == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (vb2_is_busy(q)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) dprintk(vc->dev, 1, "queue busy\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) mode = vc->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) vc->fmt = fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) vc->width = f->fmt.pix.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) vc->height = f->fmt.pix.height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) vc->field = f->fmt.pix.field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) if (vc->width > norm_minw(vc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (vc->height > norm_minh(vc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (vc->cap_parm.capturemode &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) V4L2_MODE_HIGHQUALITY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) mode.scale = SCALE_4CIFSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) mode.scale = SCALE_4CIFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) mode.scale = SCALE_2CIFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) mode.scale = SCALE_1CIFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) /* color mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) switch (vc->fmt->fourcc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) case V4L2_PIX_FMT_GREY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) mode.color &= ~MASK_COLOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) mode.color |= COLOR_Y8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) case V4L2_PIX_FMT_JPEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) case V4L2_PIX_FMT_MJPEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) mode.color &= ~MASK_COLOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) mode.color |= COLOR_JPG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) mode.color |= (vc->jpegqual << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) case V4L2_PIX_FMT_YUV422P:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) mode.color &= ~MASK_COLOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) mode.color |= COLOR_YUVPL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) case V4L2_PIX_FMT_YUYV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) case V4L2_PIX_FMT_UYVY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) mode.color &= ~MASK_COLOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) mode.color |= COLOR_YUVPK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if ((mode.color & MASK_COLOR) != (vc->mode.color & MASK_COLOR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) mode.restart = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) else if (mode.scale != vc->mode.scale)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) mode.restart = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) else if (mode.format != vc->mode.format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) mode.restart = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) vc->mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) (void) s2255_set_mode(vc, &mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^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) /* write to the configuration pipe, synchronously */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) int pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) int done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) long retval = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) if (udev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) static u32 get_transfer_size(struct s2255_mode *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) int linesPerFrame = LINE_SZ_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) int pixelsPerLine = NUM_LINES_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) u32 outImageSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) u32 usbInSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) unsigned int mask_mult;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) if (mode == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if (mode->format == FORMAT_NTSC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) switch (mode->scale) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) case SCALE_4CIFS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) case SCALE_4CIFSI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) pixelsPerLine = LINE_SZ_4CIFS_NTSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) case SCALE_2CIFS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) linesPerFrame = NUM_LINES_2CIFS_NTSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) pixelsPerLine = LINE_SZ_2CIFS_NTSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) case SCALE_1CIFS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) linesPerFrame = NUM_LINES_1CIFS_NTSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) pixelsPerLine = LINE_SZ_1CIFS_NTSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) } else if (mode->format == FORMAT_PAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) switch (mode->scale) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) case SCALE_4CIFS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) case SCALE_4CIFSI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) pixelsPerLine = LINE_SZ_4CIFS_PAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) case SCALE_2CIFS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) linesPerFrame = NUM_LINES_2CIFS_PAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) pixelsPerLine = LINE_SZ_2CIFS_PAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) case SCALE_1CIFS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) linesPerFrame = NUM_LINES_1CIFS_PAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) pixelsPerLine = LINE_SZ_1CIFS_PAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) outImageSize = linesPerFrame * pixelsPerLine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if ((mode->color & MASK_COLOR) != COLOR_Y8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) /* 2 bytes/pixel if not monochrome */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) outImageSize *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) /* total bytes to send including prefix and 4K padding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) must be a multiple of USB_READ_SIZE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) /* if size not a multiple of USB_READ_SIZE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (usbInSize & ~mask_mult)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) return usbInSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) struct device *dev = &sdev->udev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) dev_info(dev, "------------------------------------------------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) dev_info(dev, "format: %d\nscale %d\n", mode->format, mode->scale);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) dev_info(dev, "fdec: %d\ncolor %d\n", mode->fdec, mode->color);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) dev_info(dev, "bright: 0x%x\n", mode->bright);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) dev_info(dev, "------------------------------------------------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^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) * set mode is the function which controls the DSP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) * the restart parameter in struct s2255_mode should be set whenever
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) * the image size could change via color format, video system or image
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) * size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) * When the restart parameter is set, we sleep for ONE frame to allow the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) * DSP time to get the new frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) static int s2255_set_mode(struct s2255_vc *vc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) struct s2255_mode *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) unsigned long chn_rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) __le32 *buffer = dev->cmdbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) mutex_lock(&dev->cmdlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) chn_rev = G_chnmap[vc->idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) dprintk(dev, 3, "%s channel: %d\n", __func__, vc->idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) /* if JPEG, set the quality */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if ((mode->color & MASK_COLOR) == COLOR_JPG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) mode->color &= ~MASK_COLOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) mode->color |= COLOR_JPG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) mode->color &= ~MASK_JPG_QUALITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) mode->color |= (vc->jpegqual << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) /* save the mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) vc->mode = *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) vc->req_image_size = get_transfer_size(mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) dprintk(dev, 1, "%s: reqsize %ld\n", __func__, vc->req_image_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) /* set the mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) buffer[0] = IN_DATA_TOKEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) buffer[1] = (__le32) cpu_to_le32(chn_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) buffer[2] = CMD_SET_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) for (i = 0; i < sizeof(struct s2255_mode) / sizeof(u32); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) buffer[3 + i] = cpu_to_le32(((u32 *)&vc->mode)[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) vc->setmode_ready = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) s2255_print_cfg(dev, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) /* wait at least 3 frames before continuing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) if (mode->restart) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) wait_event_timeout(vc->wait_setmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) (vc->setmode_ready != 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) if (vc->setmode_ready != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) dprintk(dev, 0, "s2255: no set mode response\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) res = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) /* clear the restart flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) vc->mode.restart = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) dprintk(dev, 1, "%s chn %d, result: %d\n", __func__, vc->idx, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) mutex_unlock(&dev->cmdlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) static int s2255_cmd_status(struct s2255_vc *vc, u32 *pstatus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) u32 chn_rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) __le32 *buffer = dev->cmdbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) mutex_lock(&dev->cmdlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) chn_rev = G_chnmap[vc->idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) dprintk(dev, 4, "%s chan %d\n", __func__, vc->idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) /* form the get vid status command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) buffer[0] = IN_DATA_TOKEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) buffer[1] = (__le32) cpu_to_le32(chn_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) buffer[2] = CMD_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) *pstatus = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) vc->vidstatus_ready = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) wait_event_timeout(vc->wait_vidstatus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) (vc->vidstatus_ready != 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (vc->vidstatus_ready != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) dprintk(dev, 0, "s2255: no vidstatus response\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) res = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) *pstatus = vc->vidstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) dprintk(dev, 4, "%s, vid status %d\n", __func__, *pstatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) mutex_unlock(&dev->cmdlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) static int start_streaming(struct vb2_queue *vq, unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) struct s2255_vc *vc = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) vc->last_frame = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) vc->bad_payload = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) vc->cur_frame = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) vc->frame_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) for (j = 0; j < SYS_FRAMES; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) vc->buffer.frame[j].ulState = S2255_READ_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) vc->buffer.frame[j].cur_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) return s2255_start_acquire(vc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) /* abort streaming and wait for last buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) static void stop_streaming(struct vb2_queue *vq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) struct s2255_vc *vc = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) struct s2255_buffer *buf, *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) (void) s2255_stop_acquire(vc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) spin_lock_irqsave(&vc->qlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) list_for_each_entry_safe(buf, node, &vc->buf_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) list_del(&buf->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) dprintk(vc->dev, 2, "[%p/%d] done\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) buf, buf->vb.vb2_buf.index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) spin_unlock_irqrestore(&vc->qlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) struct s2255_vc *vc = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) struct s2255_mode mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) struct vb2_queue *q = &vc->vb_vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) * Changing the standard implies a format change, which is not allowed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) * while buffers for use with streaming have already been allocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (vb2_is_busy(q))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) mode = vc->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) if (i & V4L2_STD_525_60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) dprintk(vc->dev, 4, "%s 60 Hz\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) /* if changing format, reset frame decimation/intervals */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) if (mode.format != FORMAT_NTSC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) mode.restart = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) mode.format = FORMAT_NTSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) mode.fdec = FDEC_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) vc->width = LINE_SZ_4CIFS_NTSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) vc->height = NUM_LINES_4CIFS_NTSC * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) } else if (i & V4L2_STD_625_50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) dprintk(vc->dev, 4, "%s 50 Hz\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) if (mode.format != FORMAT_PAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) mode.restart = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) mode.format = FORMAT_PAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) mode.fdec = FDEC_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) vc->width = LINE_SZ_4CIFS_PAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) vc->height = NUM_LINES_4CIFS_PAL * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) vc->std = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) if (mode.restart)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) s2255_set_mode(vc, &mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) struct s2255_vc *vc = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) *i = vc->std;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) return 0;
^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) /* Sensoray 2255 is a multiple channel capture device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) It does not have a "crossbar" of inputs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) We use one V4L device per channel. The user must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) be aware that certain combinations are not allowed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) For instance, you cannot do full FPS on more than 2 channels(2 videodevs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) at once in color(you can do full fps on 4 channels with greyscale.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) static int vidioc_enum_input(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) struct v4l2_input *inp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) struct s2255_vc *vc = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) struct s2255_dev *dev = vc->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) u32 status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) if (inp->index != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) inp->type = V4L2_INPUT_TYPE_CAMERA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) inp->std = S2255_NORMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) inp->status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) rc = s2255_cmd_status(vc, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) dprintk(dev, 4, "s2255_cmd_status rc: %d status %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) rc, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) inp->status = (status & 0x01) ? 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) : V4L2_IN_ST_NO_SIGNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) switch (dev->pid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) case 0x2255:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) strscpy(inp->name, "Composite", sizeof(inp->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) case 0x2257:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) strscpy(inp->name, (vc->idx < 2) ? "Composite" : "S-Video",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) sizeof(inp->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) *i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) if (i > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) static int s2255_s_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) struct s2255_vc *vc =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) container_of(ctrl->handler, struct s2255_vc, hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) struct s2255_mode mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) mode = vc->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) /* update the mode to the corresponding value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) case V4L2_CID_BRIGHTNESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) mode.bright = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) case V4L2_CID_CONTRAST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) mode.contrast = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) case V4L2_CID_HUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) mode.hue = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) case V4L2_CID_SATURATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) mode.saturation = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) case V4L2_CID_S2255_COLORFILTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) mode.color &= ~MASK_INPUT_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) mode.color |= !ctrl->val << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) case V4L2_CID_JPEG_COMPRESSION_QUALITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) vc->jpegqual = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) mode.restart = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) /* set mode here. Note: stream does not need restarted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) some V4L programs restart stream unnecessarily
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) after a s_crtl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) s2255_set_mode(vc, &mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) static int vidioc_g_jpegcomp(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) struct v4l2_jpegcompression *jc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) struct s2255_vc *vc = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) memset(jc, 0, sizeof(*jc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) jc->quality = vc->jpegqual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) dprintk(vc->dev, 2, "%s: quality %d\n", __func__, jc->quality);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) static int vidioc_s_jpegcomp(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) const struct v4l2_jpegcompression *jc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) struct s2255_vc *vc = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if (jc->quality < 0 || jc->quality > 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) v4l2_ctrl_s_ctrl(vc->jpegqual_ctrl, jc->quality);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) dprintk(vc->dev, 2, "%s: quality %d\n", __func__, jc->quality);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) static int vidioc_g_parm(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) struct v4l2_streamparm *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) __u32 def_num, def_dem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) struct s2255_vc *vc = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) sp->parm.capture.capturemode = vc->cap_parm.capturemode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) sp->parm.capture.readbuffers = S2255_MIN_BUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) def_num = (vc->mode.format == FORMAT_NTSC) ? 1001 : 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) def_dem = (vc->mode.format == FORMAT_NTSC) ? 30000 : 25000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) sp->parm.capture.timeperframe.denominator = def_dem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) switch (vc->mode.fdec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) case FDEC_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) sp->parm.capture.timeperframe.numerator = def_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) case FDEC_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) sp->parm.capture.timeperframe.numerator = def_num * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) case FDEC_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) sp->parm.capture.timeperframe.numerator = def_num * 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) case FDEC_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) sp->parm.capture.timeperframe.numerator = def_num * 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) dprintk(vc->dev, 4, "%s capture mode, %d timeperframe %d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) sp->parm.capture.capturemode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) sp->parm.capture.timeperframe.numerator,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) sp->parm.capture.timeperframe.denominator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) static int vidioc_s_parm(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) struct v4l2_streamparm *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) struct s2255_vc *vc = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) struct s2255_mode mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) int fdec = FDEC_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) __u32 def_num, def_dem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) mode = vc->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) /* high quality capture mode requires a stream restart */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) if ((vc->cap_parm.capturemode != sp->parm.capture.capturemode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) && vb2_is_streaming(&vc->vb_vidq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) if (def_dem != sp->parm.capture.timeperframe.denominator)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) sp->parm.capture.timeperframe.numerator = def_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) else if (sp->parm.capture.timeperframe.numerator <= def_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) sp->parm.capture.timeperframe.numerator = def_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) else if (sp->parm.capture.timeperframe.numerator <= (def_num * 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) sp->parm.capture.timeperframe.numerator = def_num * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) fdec = FDEC_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) } else if (sp->parm.capture.timeperframe.numerator <= (def_num * 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) sp->parm.capture.timeperframe.numerator = def_num * 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) fdec = FDEC_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) sp->parm.capture.timeperframe.numerator = def_num * 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) fdec = FDEC_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) mode.fdec = fdec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) sp->parm.capture.timeperframe.denominator = def_dem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) sp->parm.capture.readbuffers = S2255_MIN_BUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) s2255_set_mode(vc, &mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) dprintk(vc->dev, 4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) sp->parm.capture.capturemode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) sp->parm.capture.timeperframe.numerator,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) sp->parm.capture.timeperframe.denominator, fdec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) #define NUM_SIZE_ENUMS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) static const struct v4l2_frmsize_discrete ntsc_sizes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) { 640, 480 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) { 640, 240 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) { 320, 240 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) static const struct v4l2_frmsize_discrete pal_sizes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) { 704, 576 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) { 704, 288 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) { 352, 288 },
^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) static int vidioc_enum_framesizes(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) struct v4l2_frmsizeenum *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) struct s2255_vc *vc = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) int is_ntsc = vc->std & V4L2_STD_525_60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) const struct s2255_fmt *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) if (fe->index >= NUM_SIZE_ENUMS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) fmt = format_by_fourcc(fe->pixel_format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) if (fmt == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) fe->type = V4L2_FRMSIZE_TYPE_DISCRETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) fe->discrete = is_ntsc ? ntsc_sizes[fe->index] : pal_sizes[fe->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) static int vidioc_enum_frameintervals(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) struct v4l2_frmivalenum *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) struct s2255_vc *vc = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) const struct s2255_fmt *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) const struct v4l2_frmsize_discrete *sizes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) int is_ntsc = vc->std & V4L2_STD_525_60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) #define NUM_FRAME_ENUMS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) int frm_dec[NUM_FRAME_ENUMS] = {1, 2, 3, 5};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) if (fe->index >= NUM_FRAME_ENUMS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) fmt = format_by_fourcc(fe->pixel_format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) if (fmt == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) sizes = is_ntsc ? ntsc_sizes : pal_sizes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) for (i = 0; i < NUM_SIZE_ENUMS; i++, sizes++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) if (fe->width == sizes->width &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) fe->height == sizes->height)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) if (i == NUM_SIZE_ENUMS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) fe->type = V4L2_FRMIVAL_TYPE_DISCRETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) fe->discrete.denominator = is_ntsc ? 30000 : 25000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) fe->discrete.numerator = (is_ntsc ? 1001 : 1000) * frm_dec[fe->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) dprintk(vc->dev, 4, "%s discrete %d/%d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) fe->discrete.numerator,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) fe->discrete.denominator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) static int s2255_open(struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) struct s2255_vc *vc = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) struct s2255_dev *dev = vc->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) int state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) rc = v4l2_fh_open(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) if (rc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) dprintk(dev, 1, "s2255: %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) state = atomic_read(&dev->fw_data->fw_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) case S2255_FW_DISCONNECTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) case S2255_FW_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) s2255_dev_err(&dev->udev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) "firmware load failed. retrying.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) s2255_fwload_start(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) wait_event_timeout(dev->fw_data->wait_fw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) ((atomic_read(&dev->fw_data->fw_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) == S2255_FW_SUCCESS) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) (atomic_read(&dev->fw_data->fw_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) == S2255_FW_DISCONNECTING)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) msecs_to_jiffies(S2255_LOAD_TIMEOUT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) /* state may have changed, re-read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) state = atomic_read(&dev->fw_data->fw_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) case S2255_FW_NOTLOADED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) case S2255_FW_LOADED_DSPWAIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) /* give S2255_LOAD_TIMEOUT time for firmware to load in case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) driver loaded and then device immediately opened */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) pr_info("%s waiting for firmware load\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) wait_event_timeout(dev->fw_data->wait_fw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) ((atomic_read(&dev->fw_data->fw_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) == S2255_FW_SUCCESS) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) (atomic_read(&dev->fw_data->fw_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) == S2255_FW_DISCONNECTING)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) msecs_to_jiffies(S2255_LOAD_TIMEOUT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) /* state may have changed, re-read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) state = atomic_read(&dev->fw_data->fw_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) case S2255_FW_SUCCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) /* state may have changed in above switch statement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) case S2255_FW_SUCCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) case S2255_FW_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) pr_info("2255 firmware load failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) case S2255_FW_DISCONNECTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) pr_info("%s: disconnecting\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) case S2255_FW_LOADED_DSPWAIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) case S2255_FW_NOTLOADED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) pr_info("%s: firmware not loaded, please retry\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) * Timeout on firmware load means device unusable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) * Set firmware failure state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) * On next s2255_open the firmware will be reloaded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) atomic_set(&dev->fw_data->fw_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) S2255_FW_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) pr_info("%s: unknown state\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) if (!vc->configured) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) /* configure channel to default state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) vc->fmt = &formats[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) s2255_set_mode(vc, &vc->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) vc->configured = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) return 0;
^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) static void s2255_destroy(struct s2255_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) dprintk(dev, 1, "%s", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) /* board shutdown stops the read pipe if it is running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) s2255_board_shutdown(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) /* make sure firmware still not trying to load */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) del_timer_sync(&dev->timer); /* only started in .probe and .open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) if (dev->fw_data->fw_urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) usb_kill_urb(dev->fw_data->fw_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) usb_free_urb(dev->fw_data->fw_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) dev->fw_data->fw_urb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) release_firmware(dev->fw_data->fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) kfree(dev->fw_data->pfw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) kfree(dev->fw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) /* reset the DSP so firmware can be reloaded next time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) s2255_reset_dsppower(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) mutex_destroy(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) usb_put_dev(dev->udev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) v4l2_device_unregister(&dev->v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) kfree(dev->cmdbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) static const struct v4l2_file_operations s2255_fops_v4l = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) .open = s2255_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) .release = vb2_fop_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) .poll = vb2_fop_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) .mmap = vb2_fop_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) .read = vb2_fop_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) .vidioc_querycap = vidioc_querycap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) .vidioc_reqbufs = vb2_ioctl_reqbufs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) .vidioc_querybuf = vb2_ioctl_querybuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) .vidioc_qbuf = vb2_ioctl_qbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) .vidioc_dqbuf = vb2_ioctl_dqbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) .vidioc_s_std = vidioc_s_std,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) .vidioc_g_std = vidioc_g_std,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) .vidioc_enum_input = vidioc_enum_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) .vidioc_g_input = vidioc_g_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) .vidioc_s_input = vidioc_s_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) .vidioc_streamon = vb2_ioctl_streamon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) .vidioc_streamoff = vb2_ioctl_streamoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) .vidioc_s_jpegcomp = vidioc_s_jpegcomp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) .vidioc_g_jpegcomp = vidioc_g_jpegcomp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) .vidioc_s_parm = vidioc_s_parm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) .vidioc_g_parm = vidioc_g_parm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) .vidioc_enum_framesizes = vidioc_enum_framesizes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) .vidioc_log_status = v4l2_ctrl_log_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) static void s2255_video_device_release(struct video_device *vdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) struct s2255_vc *vc =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) container_of(vdev, struct s2255_vc, vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) dprintk(dev, 4, "%s, chnls: %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) atomic_read(&dev->num_channels));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) v4l2_ctrl_handler_free(&vc->hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) if (atomic_dec_and_test(&dev->num_channels))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) s2255_destroy(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) static const struct video_device template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) .name = "s2255v",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) .fops = &s2255_fops_v4l,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) .ioctl_ops = &s2255_ioctl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) .release = s2255_video_device_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) .tvnorms = S2255_NORMS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) static const struct v4l2_ctrl_ops s2255_ctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) .s_ctrl = s2255_s_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) static const struct v4l2_ctrl_config color_filter_ctrl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) .ops = &s2255_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) .name = "Color Filter",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) .id = V4L2_CID_S2255_COLORFILTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) .type = V4L2_CTRL_TYPE_BOOLEAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) .max = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) .step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) .def = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) static int s2255_probe_v4l(struct s2255_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) int cur_nr = video_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) struct s2255_vc *vc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) struct vb2_queue *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) /* initialize all video 4 linux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) /* register 4 video devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) for (i = 0; i < MAX_CHANNELS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) vc = &dev->vc[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) INIT_LIST_HEAD(&vc->buf_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) v4l2_ctrl_handler_init(&vc->hdl, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) V4L2_CID_BRIGHTNESS, -127, 127, 1, DEF_BRIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) V4L2_CID_CONTRAST, 0, 255, 1, DEF_CONTRAST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) V4L2_CID_SATURATION, 0, 255, 1, DEF_SATURATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) v4l2_ctrl_new_std(&vc->hdl, &s2255_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) V4L2_CID_HUE, 0, 255, 1, DEF_HUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) vc->jpegqual_ctrl = v4l2_ctrl_new_std(&vc->hdl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) &s2255_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) V4L2_CID_JPEG_COMPRESSION_QUALITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 0, 100, 1, S2255_DEF_JPEG_QUAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) if (dev->dsp_fw_ver >= S2255_MIN_DSP_COLORFILTER &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) (dev->pid != 0x2257 || vc->idx <= 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) v4l2_ctrl_new_custom(&vc->hdl, &color_filter_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) if (vc->hdl.error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) ret = vc->hdl.error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) v4l2_ctrl_handler_free(&vc->hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) dev_err(&dev->udev->dev, "couldn't register control\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) q = &vc->vb_vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) q->io_modes = VB2_MMAP | VB2_READ | VB2_USERPTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) q->drv_priv = vc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) q->lock = &vc->vb_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) q->buf_struct_size = sizeof(struct s2255_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) q->mem_ops = &vb2_vmalloc_memops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) q->ops = &s2255_video_qops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) ret = vb2_queue_init(q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) dev_err(&dev->udev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) "%s vb2_queue_init 0x%x\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) /* register video devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) vc->vdev = template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) vc->vdev.queue = q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) vc->vdev.ctrl_handler = &vc->hdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) vc->vdev.lock = &dev->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) vc->vdev.v4l2_dev = &dev->v4l2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) vc->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) video_set_drvdata(&vc->vdev, vc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) if (video_nr == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) ret = video_register_device(&vc->vdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) VFL_TYPE_VIDEO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) video_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) ret = video_register_device(&vc->vdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) VFL_TYPE_VIDEO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) cur_nr + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) dev_err(&dev->udev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) "failed to register video device!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) atomic_inc(&dev->num_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) video_device_node_name(&vc->vdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) pr_info("Sensoray 2255 V4L driver Revision: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) S2255_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) /* if no channels registered, return error and probe will fail*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) if (atomic_read(&dev->num_channels) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) v4l2_device_unregister(&dev->v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) pr_warn("s2255: Not all channels available.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) /* this function moves the usb stream read pipe data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) * into the system buffers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) * returns 0 on success, EAGAIN if more data to process( call this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) * function again).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) * Received frame structure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) * bytes 0-3: marker : 0x2255DA4AL (S2255_MARKER_FRAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) * bytes 4-7: channel: 0-3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) * bytes 8-11: payload size: size of the frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) * bytes 12-payloadsize+12: frame data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) char *pdest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) u32 offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) int bframe = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) char *psrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) unsigned long copy_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) unsigned long size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) s32 idx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) struct s2255_framei *frm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) unsigned char *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) struct s2255_vc *vc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) dprintk(dev, 100, "buffer to user\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) vc = &dev->vc[dev->cc];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) idx = vc->cur_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) frm = &vc->buffer.frame[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) if (frm->ulState == S2255_READ_IDLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) int jj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) unsigned int cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) __le32 *pdword; /*data from dsp is little endian */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) int payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) /* search for marker codes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) pdata = (unsigned char *)pipe_info->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) pdword = (__le32 *)pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); jj++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) switch (*pdword) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) case S2255_MARKER_FRAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) dprintk(dev, 4, "marker @ offset: %d [%x %x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) jj, pdata[0], pdata[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) offset = jj + PREFIX_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) bframe = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) cc = le32_to_cpu(pdword[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) if (cc >= MAX_CHANNELS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) dprintk(dev, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) "bad channel\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) /* reverse it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) dev->cc = G_chnmap[cc];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) vc = &dev->vc[dev->cc];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) payload = le32_to_cpu(pdword[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) if (payload > vc->req_image_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) vc->bad_payload++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) /* discard the bad frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) vc->pkt_size = payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) vc->jpg_size = le32_to_cpu(pdword[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) case S2255_MARKER_RESPONSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) pdata += DEF_USB_BLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) jj += DEF_USB_BLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) if (le32_to_cpu(pdword[1]) >= MAX_CHANNELS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) cc = G_chnmap[le32_to_cpu(pdword[1])];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) if (cc >= MAX_CHANNELS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) vc = &dev->vc[cc];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) switch (pdword[2]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) case S2255_RESPONSE_SETMODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) /* check if channel valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) /* set mode ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) vc->setmode_ready = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) wake_up(&vc->wait_setmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) dprintk(dev, 5, "setmode rdy %d\n", cc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) case S2255_RESPONSE_FW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) dev->chn_ready |= (1 << cc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) if ((dev->chn_ready & 0x0f) != 0x0f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) /* all channels ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) pr_info("s2255: fw loaded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) atomic_set(&dev->fw_data->fw_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) S2255_FW_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) wake_up(&dev->fw_data->wait_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) case S2255_RESPONSE_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) vc->vidstatus = le32_to_cpu(pdword[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) vc->vidstatus_ready = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) wake_up(&vc->wait_vidstatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) dprintk(dev, 5, "vstat %x chan %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) le32_to_cpu(pdword[3]), cc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) pr_info("s2255 unknown resp\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) pdata++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) pdata++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) if (bframe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) } /* for */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) if (!bframe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) vc = &dev->vc[dev->cc];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) idx = vc->cur_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) frm = &vc->buffer.frame[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) /* search done. now find out if should be acquiring on this channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) if (!vb2_is_streaming(&vc->vb_vidq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) /* we found a frame, but this channel is turned off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) frm->ulState = S2255_READ_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) if (frm->ulState == S2255_READ_IDLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) frm->ulState = S2255_READ_FRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) frm->cur_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) /* skip the marker 512 bytes (and offset if out of sync) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) psrc = (u8 *)pipe_info->transfer_buffer + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) if (frm->lpvbits == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) dprintk(dev, 1, "s2255 frame buffer == NULL.%p %p %d %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) frm, dev, dev->cc, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) pdest = frm->lpvbits + frm->cur_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) copy_size = (pipe_info->cur_transfer_size - offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) size = vc->pkt_size - PREFIX_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) /* sanity check on pdest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) if ((copy_size + frm->cur_size) < vc->req_image_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) memcpy(pdest, psrc, copy_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) frm->cur_size += copy_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) dprintk(dev, 4, "cur_size: %lu, size: %lu\n", frm->cur_size, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) if (frm->cur_size >= size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) dprintk(dev, 2, "******[%d]Buffer[%d]full*******\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) dev->cc, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) vc->last_frame = vc->cur_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) vc->cur_frame++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) /* end of system frame ring buffer, start at zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) if ((vc->cur_frame == SYS_FRAMES) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) (vc->cur_frame == vc->buffer.dwFrames))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) vc->cur_frame = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) /* frame ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) if (vb2_is_streaming(&vc->vb_vidq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) s2255_got_frame(vc, vc->jpg_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) vc->frame_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) frm->ulState = S2255_READ_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) frm->cur_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) /* done successfully */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) static void s2255_read_video_callback(struct s2255_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) struct s2255_pipeinfo *pipe_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) dprintk(dev, 50, "callback read video\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) if (dev->cc >= MAX_CHANNELS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) dev->cc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) dev_err(&dev->udev->dev, "invalid channel\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) /* otherwise copy to the system buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) res = save_frame(dev, pipe_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) if (res != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) dprintk(dev, 4, "s2255: read callback failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) dprintk(dev, 50, "callback read video done\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) u16 Index, u16 Value, void *TransferBuffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) s32 TransferBufferLength, int bOut)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) unsigned char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) buf = kmalloc(TransferBufferLength, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) if (!bOut) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) Request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) USB_TYPE_VENDOR | USB_RECIP_DEVICE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) USB_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) Value, Index, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) TransferBufferLength, USB_CTRL_SET_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) if (r >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) memcpy(TransferBuffer, buf, TransferBufferLength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) memcpy(buf, TransferBuffer, TransferBufferLength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) Value, Index, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) TransferBufferLength, USB_CTRL_SET_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) * retrieve FX2 firmware version. future use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) * @param dev pointer to device extension
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) * @return -1 for fail, else returns firmware version as an int(16 bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) static int s2255_get_fx2fw(struct s2255_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) int fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) unsigned char transBuffer[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) S2255_VR_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) dprintk(dev, 2, "get fw error: %x\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) fw = transBuffer[0] + (transBuffer[1] << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) dprintk(dev, 2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) return fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) * Create the system ring buffer to copy frames into from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) * usb read pipe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) static int s2255_create_sys_buffers(struct s2255_vc *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) unsigned long i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) unsigned long reqsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) vc->buffer.dwFrames = SYS_FRAMES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) /* always allocate maximum size(PAL) for system buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) reqsize = SYS_FRAMES_MAXSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) if (reqsize > SYS_FRAMES_MAXSIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) reqsize = SYS_FRAMES_MAXSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) for (i = 0; i < SYS_FRAMES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) /* allocate the frames */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) vc->buffer.frame[i].lpvbits = vmalloc(reqsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) vc->buffer.frame[i].size = reqsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) if (vc->buffer.frame[i].lpvbits == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) pr_info("out of memory. using less frames\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) vc->buffer.dwFrames = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) /* make sure internal states are set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) for (i = 0; i < SYS_FRAMES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) vc->buffer.frame[i].ulState = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) vc->buffer.frame[i].cur_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) vc->cur_frame = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) vc->last_frame = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) static int s2255_release_sys_buffers(struct s2255_vc *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) unsigned long i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) for (i = 0; i < SYS_FRAMES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) vfree(vc->buffer.frame[i].lpvbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) vc->buffer.frame[i].lpvbits = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) static int s2255_board_init(struct s2255_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) int fw_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) struct s2255_pipeinfo *pipe = &dev->pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) dprintk(dev, 4, "board init: %p", dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) memset(pipe, 0, sizeof(*pipe));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) pipe->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) pipe->cur_transfer_size = S2255_USB_XFER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) pipe->max_transfer_size = S2255_USB_XFER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) pipe->transfer_buffer = kzalloc(pipe->max_transfer_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) if (pipe->transfer_buffer == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) dprintk(dev, 1, "out of memory!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) /* query the firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) fw_ver = s2255_get_fx2fw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) pr_info("s2255: usb firmware version %d.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) (fw_ver >> 8) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) fw_ver & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) if (fw_ver < S2255_CUR_USB_FWVER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) pr_info("s2255: newer USB firmware available\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) for (j = 0; j < MAX_CHANNELS; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) struct s2255_vc *vc = &dev->vc[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) vc->mode = mode_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) if (dev->pid == 0x2257 && j > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) vc->mode.color |= (1 << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) vc->jpegqual = S2255_DEF_JPEG_QUAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) vc->width = LINE_SZ_4CIFS_NTSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) vc->height = NUM_LINES_4CIFS_NTSC * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) vc->std = V4L2_STD_NTSC_M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) vc->fmt = &formats[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) vc->mode.restart = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) vc->req_image_size = get_transfer_size(&mode_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) vc->frame_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) /* create the system buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) s2255_create_sys_buffers(vc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) /* start read pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) s2255_start_readpipe(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) dprintk(dev, 1, "%s: success\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) static int s2255_board_shutdown(struct s2255_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) dprintk(dev, 1, "%s: dev: %p", __func__, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) for (i = 0; i < MAX_CHANNELS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) if (vb2_is_streaming(&dev->vc[i].vb_vidq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) s2255_stop_acquire(&dev->vc[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) s2255_stop_readpipe(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) for (i = 0; i < MAX_CHANNELS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) s2255_release_sys_buffers(&dev->vc[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) /* release transfer buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) kfree(dev->pipe.transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) static void read_pipe_completion(struct urb *purb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) struct s2255_pipeinfo *pipe_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) struct s2255_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) int pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) pipe_info = purb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) if (pipe_info == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) dev_err(&purb->dev->dev, "no context!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) dev = pipe_info->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) if (dev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) dev_err(&purb->dev->dev, "no context!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) status = purb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) /* if shutting down, do not resubmit, exit immediately */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) if (status == -ESHUTDOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) dprintk(dev, 2, "%s: err shutdown\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) pipe_info->err_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) if (pipe_info->state == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) dprintk(dev, 2, "%s: exiting USB pipe", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) if (status == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) s2255_read_video_callback(dev, pipe_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) pipe_info->err_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) dprintk(dev, 1, "%s: failed URB %d\n", __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) /* reuse urb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) pipe_info->transfer_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) pipe_info->cur_transfer_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) read_pipe_completion, pipe_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) if (pipe_info->state != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) dev_err(&dev->udev->dev, "error submitting urb\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) dprintk(dev, 2, "%s :complete state 0\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) static int s2255_start_readpipe(struct s2255_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) int pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) struct s2255_pipeinfo *pipe_info = &dev->pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) dprintk(dev, 2, "%s: IN %d\n", __func__, dev->read_endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) pipe_info->state = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) pipe_info->err_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) if (!pipe_info->stream_urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) /* transfer buffer allocated in board_init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) pipe_info->transfer_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) pipe_info->cur_transfer_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) read_pipe_completion, pipe_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) pr_err("s2255: start read pipe failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) /* starts acquisition process */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) static int s2255_start_acquire(struct s2255_vc *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) unsigned long chn_rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) __le32 *buffer = dev->cmdbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) mutex_lock(&dev->cmdlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) chn_rev = G_chnmap[vc->idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) vc->last_frame = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) vc->bad_payload = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) vc->cur_frame = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) for (j = 0; j < SYS_FRAMES; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) vc->buffer.frame[j].ulState = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) vc->buffer.frame[j].cur_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) /* send the start command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) buffer[0] = IN_DATA_TOKEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) buffer[1] = (__le32) cpu_to_le32(chn_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) buffer[2] = CMD_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) if (res != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) dev_err(&dev->udev->dev, "CMD_START error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) dprintk(dev, 2, "start acquire exit[%d] %d\n", vc->idx, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) mutex_unlock(&dev->cmdlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) static int s2255_stop_acquire(struct s2255_vc *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) unsigned long chn_rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) struct s2255_dev *dev = to_s2255_dev(vc->vdev.v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) __le32 *buffer = dev->cmdbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) mutex_lock(&dev->cmdlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) chn_rev = G_chnmap[vc->idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) /* send the stop command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) buffer[0] = IN_DATA_TOKEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) buffer[1] = (__le32) cpu_to_le32(chn_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) buffer[2] = CMD_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) if (res != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) dev_err(&dev->udev->dev, "CMD_STOP error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) dprintk(dev, 4, "%s: chn %d, res %d\n", __func__, vc->idx, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) mutex_unlock(&dev->cmdlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) static void s2255_stop_readpipe(struct s2255_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) struct s2255_pipeinfo *pipe = &dev->pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) pipe->state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) if (pipe->stream_urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) /* cancel urb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) usb_kill_urb(pipe->stream_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) usb_free_urb(pipe->stream_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) pipe->stream_urb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) dprintk(dev, 4, "%s", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) static void s2255_fwload_start(struct s2255_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) s2255_reset_dsppower(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) dev->fw_data->fw_size = dev->fw_data->fw->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) memcpy(dev->fw_data->pfw_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) dev->fw_data->fw->data, CHUNK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) dev->fw_data->fw_loaded = CHUNK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) usb_sndbulkpipe(dev->udev, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) dev->fw_data->pfw_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) CHUNK_SIZE, s2255_fwchunk_complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) dev->fw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) mod_timer(&dev->timer, jiffies + HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) /* standard usb probe function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) static int s2255_probe(struct usb_interface *interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) struct s2255_dev *dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) struct usb_host_interface *iface_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) struct usb_endpoint_descriptor *endpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) int retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) __le32 *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) int fw_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) /* allocate memory for our device state and initialize it to zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) if (dev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) s2255_dev_err(&interface->dev, "out of memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) dev->cmdbuf = kzalloc(S2255_CMDBUF_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) if (dev->cmdbuf == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) s2255_dev_err(&interface->dev, "out of memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) goto errorFWDATA1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) atomic_set(&dev->num_channels, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) dev->pid = id->idProduct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) if (!dev->fw_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) goto errorFWDATA1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) mutex_init(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) mutex_init(&dev->cmdlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) /* grab usb_device and save it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) dev->udev = usb_get_dev(interface_to_usbdev(interface));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) if (dev->udev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) dev_err(&interface->dev, "null usb device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) retval = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) goto errorUDEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) dev_dbg(&interface->dev, "dev: %p, udev %p interface %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) dev, dev->udev, interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) dev->interface = interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) /* set up the endpoint information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) iface_desc = interface->cur_altsetting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) dev_dbg(&interface->dev, "num EP: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) iface_desc->desc.bNumEndpoints);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) endpoint = &iface_desc->endpoint[i].desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) /* we found the bulk in endpoint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) dev->read_endpoint = endpoint->bEndpointAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) if (!dev->read_endpoint) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) goto errorEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) timer_setup(&dev->timer, s2255_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) init_waitqueue_head(&dev->fw_data->wait_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) for (i = 0; i < MAX_CHANNELS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) struct s2255_vc *vc = &dev->vc[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) vc->idx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) vc->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) init_waitqueue_head(&vc->wait_setmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) init_waitqueue_head(&vc->wait_vidstatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) spin_lock_init(&vc->qlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) mutex_init(&vc->vb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) if (!dev->fw_data->fw_urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) goto errorFWURB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) if (!dev->fw_data->pfw_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) dev_err(&interface->dev, "out of memory!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) goto errorFWDATA2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) /* load the first chunk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) if (request_firmware(&dev->fw_data->fw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) FIRMWARE_FILE_NAME, &dev->udev->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) dev_err(&interface->dev, "sensoray 2255 failed to get firmware\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) goto errorREQFW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) /* check the firmware is valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) fw_size = dev->fw_data->fw->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) if (*pdata != S2255_FW_MARKER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) dev_err(&interface->dev, "Firmware invalid.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) retval = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) goto errorFWMARKER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) /* make sure firmware is the latest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) __le32 *pRel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) pRel = (__le32 *) &dev->fw_data->fw->data[fw_size - 4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) pr_info("s2255 dsp fw version %x\n", le32_to_cpu(*pRel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) dev->dsp_fw_ver = le32_to_cpu(*pRel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) if (dev->dsp_fw_ver < S2255_CUR_DSP_FWVER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) pr_info("s2255: f2255usb.bin out of date.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) if (dev->pid == 0x2257 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) pr_warn("2257 needs firmware %d or above.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) S2255_MIN_DSP_COLORFILTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) usb_reset_device(dev->udev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) /* load 2255 board specific */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) retval = s2255_board_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) goto errorBOARDINIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) s2255_fwload_start(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) /* loads v4l specific */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) retval = s2255_probe_v4l(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) goto errorBOARDINIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) dev_info(&interface->dev, "Sensoray 2255 detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) errorBOARDINIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) s2255_board_shutdown(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) errorFWMARKER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) release_firmware(dev->fw_data->fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) errorREQFW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) kfree(dev->fw_data->pfw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) errorFWDATA2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) usb_free_urb(dev->fw_data->fw_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) errorFWURB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) del_timer_sync(&dev->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) errorEP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) usb_put_dev(dev->udev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) errorUDEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) kfree(dev->fw_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) mutex_destroy(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) errorFWDATA1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) kfree(dev->cmdbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) pr_warn("Sensoray 2255 driver load failed: 0x%x\n", retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) /* disconnect routine. when board is removed physically or with rmmod */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) static void s2255_disconnect(struct usb_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) int channels = atomic_read(&dev->num_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) mutex_lock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) v4l2_device_disconnect(&dev->v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) mutex_unlock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) /*see comments in the uvc_driver.c usb disconnect function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) atomic_inc(&dev->num_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) /* unregister each video device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) for (i = 0; i < channels; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) video_unregister_device(&dev->vc[i].vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) /* wake up any of our timers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) wake_up(&dev->fw_data->wait_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) for (i = 0; i < MAX_CHANNELS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) dev->vc[i].setmode_ready = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) wake_up(&dev->vc[i].wait_setmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) dev->vc[i].vidstatus_ready = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) wake_up(&dev->vc[i].wait_vidstatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) if (atomic_dec_and_test(&dev->num_channels))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) s2255_destroy(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) dev_info(&interface->dev, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) static struct usb_driver s2255_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) .name = S2255_DRIVER_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) .probe = s2255_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) .disconnect = s2255_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) .id_table = s2255_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) module_usb_driver(s2255_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) MODULE_VERSION(S2255_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) MODULE_FIRMWARE(FIRMWARE_FILE_NAME);