^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2005-2006 Micronas USA Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/pagemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/videodev2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <media/v4l2-common.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <media/v4l2-ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <media/v4l2-subdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <media/v4l2-event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <media/videobuf2-vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <media/i2c/saa7115.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "go7007-priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define call_all(dev, o, f, args...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) v4l2_device_call_until_err(dev, 0, o, f, ##args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static bool valid_pixelformat(u32 pixelformat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) switch (pixelformat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) case V4L2_PIX_FMT_MJPEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) case V4L2_PIX_FMT_MPEG1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) case V4L2_PIX_FMT_MPEG2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) case V4L2_PIX_FMT_MPEG4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static u32 get_frame_type_flag(struct go7007_buffer *vb, int format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) u8 *ptr = vb2_plane_vaddr(&vb->vb.vb2_buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) switch (format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) case V4L2_PIX_FMT_MJPEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return V4L2_BUF_FLAG_KEYFRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) case V4L2_PIX_FMT_MPEG4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) switch ((ptr[vb->frame_offset + 4] >> 6) & 0x3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return V4L2_BUF_FLAG_KEYFRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return V4L2_BUF_FLAG_PFRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return V4L2_BUF_FLAG_BFRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) case V4L2_PIX_FMT_MPEG1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) case V4L2_PIX_FMT_MPEG2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) switch ((ptr[vb->frame_offset + 5] >> 3) & 0x7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return V4L2_BUF_FLAG_KEYFRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return V4L2_BUF_FLAG_PFRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return V4L2_BUF_FLAG_BFRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static void get_resolution(struct go7007 *go, int *width, int *height)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) switch (go->standard) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) case GO7007_STD_NTSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) *width = 720;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) *height = 480;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) case GO7007_STD_PAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) *width = 720;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) *height = 576;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) case GO7007_STD_OTHER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) *width = go->board_info->sensor_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) *height = go->board_info->sensor_height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static void set_formatting(struct go7007 *go)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (go->format == V4L2_PIX_FMT_MJPEG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) go->pali = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) go->aspect_ratio = GO7007_RATIO_1_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) go->gop_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) go->ipb = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) go->closed_gop = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) go->repeat_seqhead = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) go->seq_header_enable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) go->gop_header_enable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) go->dvd_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) switch (go->format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) case V4L2_PIX_FMT_MPEG1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) go->pali = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) case V4L2_PIX_FMT_MPEG2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) go->pali = 0x48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) case V4L2_PIX_FMT_MPEG4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* For future reference: this is the list of MPEG4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * profiles that are available, although they are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * untested:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * Profile pali
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * -------------- ----
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * PROFILE_S_L0 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * PROFILE_S_L1 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * PROFILE_S_L2 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * PROFILE_S_L3 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * PROFILE_ARTS_L1 0x91
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * PROFILE_ARTS_L2 0x92
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * PROFILE_ARTS_L3 0x93
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * PROFILE_ARTS_L4 0x94
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * PROFILE_AS_L0 0xf0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * PROFILE_AS_L1 0xf1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * PROFILE_AS_L2 0xf2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * PROFILE_AS_L3 0xf3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * PROFILE_AS_L4 0xf4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * PROFILE_AS_L5 0xf5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) go->pali = 0xf5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) go->gop_size = v4l2_ctrl_g_ctrl(go->mpeg_video_gop_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) go->closed_gop = v4l2_ctrl_g_ctrl(go->mpeg_video_gop_closure);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) go->ipb = v4l2_ctrl_g_ctrl(go->mpeg_video_b_frames) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) go->bitrate = v4l2_ctrl_g_ctrl(go->mpeg_video_bitrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) go->repeat_seqhead = v4l2_ctrl_g_ctrl(go->mpeg_video_rep_seqheader);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) go->gop_header_enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) go->dvd_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (go->format == V4L2_PIX_FMT_MPEG2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) go->dvd_mode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) go->bitrate == 9800000 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) go->gop_size == 15 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) go->ipb == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) go->repeat_seqhead == 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) go->closed_gop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) switch (v4l2_ctrl_g_ctrl(go->mpeg_video_aspect_ratio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) case V4L2_MPEG_VIDEO_ASPECT_1x1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) go->aspect_ratio = GO7007_RATIO_1_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) case V4L2_MPEG_VIDEO_ASPECT_4x3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) go->aspect_ratio = GO7007_RATIO_4_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) case V4L2_MPEG_VIDEO_ASPECT_16x9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) go->aspect_ratio = GO7007_RATIO_16_9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) int sensor_height = 0, sensor_width = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int width, height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (fmt != NULL && !valid_pixelformat(fmt->fmt.pix.pixelformat))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) get_resolution(go, &sensor_width, &sensor_height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (fmt == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) width = sensor_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) height = sensor_height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) } else if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (fmt->fmt.pix.width > sensor_width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) width = sensor_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) else if (fmt->fmt.pix.width < 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) width = 144;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) width = fmt->fmt.pix.width & ~0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (fmt->fmt.pix.height > sensor_height)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) height = sensor_height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) else if (fmt->fmt.pix.height < 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) height = 96;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) height = fmt->fmt.pix.height & ~0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) width = fmt->fmt.pix.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (width <= sensor_width / 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) width = sensor_width / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) height = sensor_height / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) } else if (width <= sensor_width / 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) width = sensor_width / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) height = sensor_height / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) width = sensor_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) height = sensor_height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) width &= ~0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) height &= ~0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (fmt != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) u32 pixelformat = fmt->fmt.pix.pixelformat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) memset(fmt, 0, sizeof(*fmt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) fmt->fmt.pix.width = width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) fmt->fmt.pix.height = height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) fmt->fmt.pix.pixelformat = pixelformat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) fmt->fmt.pix.field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) fmt->fmt.pix.bytesperline = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (try)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) go->format = fmt->fmt.pix.pixelformat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) go->width = width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) go->height = height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) go->encoder_h_offset = go->board_info->sensor_h_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) go->encoder_v_offset = go->board_info->sensor_v_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct v4l2_subdev_format format = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .which = V4L2_SUBDEV_FORMAT_ACTIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) format.format.code = MEDIA_BUS_FMT_FIXED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) format.format.width = fmt ? fmt->fmt.pix.width : width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) format.format.height = height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) go->encoder_h_halve = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) go->encoder_v_halve = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) go->encoder_subsample = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) call_all(&go->v4l2_dev, pad, set_fmt, NULL, &format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (width <= sensor_width / 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) go->encoder_h_halve = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) go->encoder_v_halve = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) go->encoder_subsample = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) } else if (width <= sensor_width / 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) go->encoder_h_halve = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) go->encoder_v_halve = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) go->encoder_subsample = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) go->encoder_h_halve = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) go->encoder_v_halve = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) go->encoder_subsample = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static int vidioc_querycap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct v4l2_capability *cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct go7007 *go = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) strscpy(cap->driver, "go7007", sizeof(cap->driver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) strscpy(cap->card, go->name, sizeof(cap->card));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) strscpy(cap->bus_info, go->bus_info, sizeof(cap->bus_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct v4l2_fmtdesc *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) switch (fmt->index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) fmt->pixelformat = V4L2_PIX_FMT_MJPEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) fmt->pixelformat = V4L2_PIX_FMT_MPEG1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) fmt->pixelformat = V4L2_PIX_FMT_MPEG2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) fmt->pixelformat = V4L2_PIX_FMT_MPEG4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) struct v4l2_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct go7007 *go = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) fmt->fmt.pix.width = go->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) fmt->fmt.pix.height = go->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) fmt->fmt.pix.pixelformat = go->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) fmt->fmt.pix.field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) fmt->fmt.pix.bytesperline = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct v4l2_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct go7007 *go = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return set_capture_size(go, fmt, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct v4l2_format *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct go7007 *go = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (vb2_is_busy(&go->vidq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return set_capture_size(go, fmt, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static int go7007_queue_setup(struct vb2_queue *q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) unsigned int *num_buffers, unsigned int *num_planes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) unsigned int sizes[], struct device *alloc_devs[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) sizes[0] = GO7007_BUF_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) *num_planes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (*num_buffers < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) *num_buffers = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static void go7007_buf_queue(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct vb2_queue *vq = vb->vb2_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) struct go7007 *go = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct go7007_buffer *go7007_vb =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) container_of(vbuf, struct go7007_buffer, vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) spin_lock_irqsave(&go->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) list_add_tail(&go7007_vb->list, &go->vidq_active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) spin_unlock_irqrestore(&go->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static int go7007_buf_prepare(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct go7007_buffer *go7007_vb =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) container_of(vbuf, struct go7007_buffer, vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) go7007_vb->modet_active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) go7007_vb->frame_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) vb->planes[0].bytesused = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static void go7007_buf_finish(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct vb2_queue *vq = vb->vb2_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct go7007 *go = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct go7007_buffer *go7007_vb =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) container_of(vbuf, struct go7007_buffer, vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) u32 frame_type_flag = get_frame_type_flag(go7007_vb, go->format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) vbuf->flags &= ~(V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_BFRAME |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) V4L2_BUF_FLAG_PFRAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) vbuf->flags |= frame_type_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) vbuf->field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) static int go7007_start_streaming(struct vb2_queue *q, unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) struct go7007 *go = vb2_get_drv_priv(q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) set_formatting(go);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) mutex_lock(&go->hw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) go->next_seq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) go->active_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) go->modet_event_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) q->streaming = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (go7007_start_encoder(go) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) mutex_unlock(&go->hw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) q->streaming = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) call_all(&go->v4l2_dev, video, s_stream, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) v4l2_ctrl_grab(go->mpeg_video_gop_size, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) v4l2_ctrl_grab(go->mpeg_video_gop_closure, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) v4l2_ctrl_grab(go->mpeg_video_bitrate, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /* Turn on Capture LED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) go7007_write_addr(go, 0x3c82, 0x0005);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) static void go7007_stop_streaming(struct vb2_queue *q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct go7007 *go = vb2_get_drv_priv(q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) q->streaming = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) go7007_stream_stop(go);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) mutex_lock(&go->hw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) go7007_reset_encoder(go);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) mutex_unlock(&go->hw_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) call_all(&go->v4l2_dev, video, s_stream, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) spin_lock_irqsave(&go->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) INIT_LIST_HEAD(&go->vidq_active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) spin_unlock_irqrestore(&go->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) v4l2_ctrl_grab(go->mpeg_video_gop_size, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) v4l2_ctrl_grab(go->mpeg_video_gop_closure, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) v4l2_ctrl_grab(go->mpeg_video_bitrate, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) v4l2_ctrl_grab(go->mpeg_video_aspect_ratio, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /* Turn on Capture LED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (go->board_id == GO7007_BOARDID_ADS_USBAV_709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) go7007_write_addr(go, 0x3c82, 0x000d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) static const struct vb2_ops go7007_video_qops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) .queue_setup = go7007_queue_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) .buf_queue = go7007_buf_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) .buf_prepare = go7007_buf_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) .buf_finish = go7007_buf_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) .start_streaming = go7007_start_streaming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) .stop_streaming = go7007_stop_streaming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) .wait_prepare = vb2_ops_wait_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) .wait_finish = vb2_ops_wait_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static int vidioc_g_parm(struct file *filp, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) struct v4l2_streamparm *parm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct go7007 *go = video_drvdata(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) struct v4l2_fract timeperframe = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) .numerator = 1001 * go->fps_scale,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) .denominator = go->sensor_framerate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) parm->parm.capture.readbuffers = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) parm->parm.capture.timeperframe = timeperframe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static int vidioc_s_parm(struct file *filp, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct v4l2_streamparm *parm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) struct go7007 *go = video_drvdata(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) unsigned int n, d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) n = go->sensor_framerate *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) parm->parm.capture.timeperframe.numerator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) d = 1001 * parm->parm.capture.timeperframe.denominator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (n != 0 && d != 0 && n > d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) go->fps_scale = (n + d/2) / d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) go->fps_scale = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return vidioc_g_parm(filp, priv, parm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) /* VIDIOC_ENUMSTD on go7007 were used for enumerating the supported fps and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) its resolution, when the device is not connected to TV.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) This is were an API abuse, probably used by the lack of specific IOCTL's to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) enumerate it, by the time the driver was written.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) However, since kernel 2.6.19, two new ioctls (VIDIOC_ENUM_FRAMEINTERVALS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) and VIDIOC_ENUM_FRAMESIZES) were added for this purpose.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) The two functions below implement the newer ioctls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static int vidioc_enum_framesizes(struct file *filp, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct v4l2_frmsizeenum *fsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) struct go7007 *go = video_drvdata(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) int width, height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (fsize->index > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (!valid_pixelformat(fsize->pixel_format))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) get_resolution(go, &width, &height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) fsize->discrete.width = (width >> fsize->index) & ~0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) fsize->discrete.height = (height >> fsize->index) & ~0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static int vidioc_enum_frameintervals(struct file *filp, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) struct v4l2_frmivalenum *fival)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct go7007 *go = video_drvdata(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) int width, height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (fival->index > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (!valid_pixelformat(fival->pixel_format))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (!(go->board_info->sensor_flags & GO7007_SENSOR_SCALING)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) get_resolution(go, &width, &height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) for (i = 0; i <= 2; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (fival->width == ((width >> i) & ~0xf) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) fival->height == ((height >> i) & ~0xf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (i > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) fival->discrete.numerator = 1001 * (fival->index + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) fival->discrete.denominator = go->sensor_framerate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) struct go7007 *go = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) *std = go->std;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) static int go7007_s_std(struct go7007 *go)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (go->std & V4L2_STD_625_50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) go->standard = GO7007_STD_PAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) go->sensor_framerate = 25025;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) go->standard = GO7007_STD_NTSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) go->sensor_framerate = 30000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) call_all(&go->v4l2_dev, video, s_std, go->std);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) set_capture_size(go, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id std)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct go7007 *go = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (vb2_is_busy(&go->vidq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) go->std = std;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return go7007_s_std(go);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) struct go7007 *go = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return call_all(&go->v4l2_dev, video, querystd, std);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static int vidioc_enum_input(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) struct v4l2_input *inp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) struct go7007 *go = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (inp->index >= go->board_info->num_inputs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) strscpy(inp->name, go->board_info->inputs[inp->index].name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) sizeof(inp->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) /* If this board has a tuner, it will be the first input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) inp->index == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) inp->type = V4L2_INPUT_TYPE_TUNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) inp->type = V4L2_INPUT_TYPE_CAMERA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (go->board_info->num_aud_inputs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) inp->audioset = (1 << go->board_info->num_aud_inputs) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) inp->audioset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) inp->tuner = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) inp->std = video_devdata(file)->tvnorms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) inp->std = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct go7007 *go = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) *input = go->input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) struct go7007 *go = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if (a->index >= go->board_info->num_aud_inputs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) strscpy(a->name, go->board_info->aud_inputs[a->index].name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) sizeof(a->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) a->capability = V4L2_AUDCAP_STEREO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct go7007 *go = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) a->index = go->aud_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) strscpy(a->name, go->board_info->aud_inputs[go->aud_input].name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) sizeof(a->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) a->capability = V4L2_AUDCAP_STEREO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) static int vidioc_s_audio(struct file *file, void *fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) const struct v4l2_audio *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) struct go7007 *go = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (a->index >= go->board_info->num_aud_inputs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) go->aud_input = a->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) v4l2_subdev_call(go->sd_audio, audio, s_routing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) go->board_info->aud_inputs[go->aud_input].audio_input, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static void go7007_s_input(struct go7007 *go)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) unsigned int input = go->input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) v4l2_subdev_call(go->sd_video, video, s_routing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) go->board_info->inputs[input].video_input, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) go->board_info->video_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (go->board_info->num_aud_inputs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) int aud_input = go->board_info->inputs[input].audio_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) v4l2_subdev_call(go->sd_audio, audio, s_routing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) go->board_info->aud_inputs[aud_input].audio_input, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) go->aud_input = aud_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct go7007 *go = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (input >= go->board_info->num_inputs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (vb2_is_busy(&go->vidq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) go->input = input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) go7007_s_input(go);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) static int vidioc_g_tuner(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) struct v4l2_tuner *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) struct go7007 *go = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (t->index != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) strscpy(t->name, "Tuner", sizeof(t->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return call_all(&go->v4l2_dev, tuner, g_tuner, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) static int vidioc_s_tuner(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) const struct v4l2_tuner *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) struct go7007 *go = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (t->index != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return call_all(&go->v4l2_dev, tuner, s_tuner, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) static int vidioc_g_frequency(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) struct v4l2_frequency *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) struct go7007 *go = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (f->tuner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return call_all(&go->v4l2_dev, tuner, g_frequency, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) static int vidioc_s_frequency(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) const struct v4l2_frequency *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) struct go7007 *go = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) if (f->tuner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) return call_all(&go->v4l2_dev, tuner, s_frequency, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) static int vidioc_log_status(struct file *file, void *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) struct go7007 *go = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) v4l2_ctrl_log_status(file, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) return call_all(&go->v4l2_dev, core, log_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) static int vidioc_subscribe_event(struct v4l2_fh *fh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) const struct v4l2_event_subscription *sub)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) switch (sub->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) case V4L2_EVENT_MOTION_DET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) /* Allow for up to 30 events (1 second for NTSC) to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) * stored. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) return v4l2_event_subscribe(fh, sub, 30, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return v4l2_ctrl_subscribe_event(fh, sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) static int go7007_s_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) struct go7007 *go =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) container_of(ctrl->handler, struct go7007, hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) unsigned y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) u8 *mt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) case V4L2_CID_PIXEL_THRESHOLD0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) go->modet[0].pixel_threshold = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) case V4L2_CID_MOTION_THRESHOLD0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) go->modet[0].motion_threshold = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) case V4L2_CID_MB_THRESHOLD0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) go->modet[0].mb_threshold = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) case V4L2_CID_PIXEL_THRESHOLD1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) go->modet[1].pixel_threshold = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) case V4L2_CID_MOTION_THRESHOLD1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) go->modet[1].motion_threshold = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) case V4L2_CID_MB_THRESHOLD1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) go->modet[1].mb_threshold = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) case V4L2_CID_PIXEL_THRESHOLD2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) go->modet[2].pixel_threshold = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) case V4L2_CID_MOTION_THRESHOLD2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) go->modet[2].motion_threshold = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) case V4L2_CID_MB_THRESHOLD2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) go->modet[2].mb_threshold = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) case V4L2_CID_PIXEL_THRESHOLD3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) go->modet[3].pixel_threshold = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) case V4L2_CID_MOTION_THRESHOLD3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) go->modet[3].motion_threshold = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) case V4L2_CID_MB_THRESHOLD3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) go->modet[3].mb_threshold = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) case V4L2_CID_DETECT_MD_REGION_GRID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) mt = go->modet_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) for (y = 0; y < go->height / 16; y++, mt += go->width / 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) memcpy(mt, ctrl->p_new.p_u8 + y * (720 / 16), go->width / 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) default:
^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) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) static const struct v4l2_file_operations go7007_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) .open = v4l2_fh_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) .release = vb2_fop_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) .unlocked_ioctl = video_ioctl2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) .read = vb2_fop_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) .mmap = vb2_fop_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) .poll = vb2_fop_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) static const struct v4l2_ioctl_ops video_ioctl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) .vidioc_querycap = vidioc_querycap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) .vidioc_reqbufs = vb2_ioctl_reqbufs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) .vidioc_querybuf = vb2_ioctl_querybuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) .vidioc_qbuf = vb2_ioctl_qbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) .vidioc_dqbuf = vb2_ioctl_dqbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) .vidioc_g_std = vidioc_g_std,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) .vidioc_s_std = vidioc_s_std,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) .vidioc_querystd = vidioc_querystd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) .vidioc_enum_input = vidioc_enum_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) .vidioc_g_input = vidioc_g_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) .vidioc_s_input = vidioc_s_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) .vidioc_enumaudio = vidioc_enumaudio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) .vidioc_g_audio = vidioc_g_audio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) .vidioc_s_audio = vidioc_s_audio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) .vidioc_streamon = vb2_ioctl_streamon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) .vidioc_streamoff = vb2_ioctl_streamoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) .vidioc_g_tuner = vidioc_g_tuner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) .vidioc_s_tuner = vidioc_s_tuner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) .vidioc_g_frequency = vidioc_g_frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) .vidioc_s_frequency = vidioc_s_frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) .vidioc_g_parm = vidioc_g_parm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) .vidioc_s_parm = vidioc_s_parm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) .vidioc_enum_framesizes = vidioc_enum_framesizes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) .vidioc_log_status = vidioc_log_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) .vidioc_subscribe_event = vidioc_subscribe_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) static const struct video_device go7007_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) .name = "go7007",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) .fops = &go7007_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) .release = video_device_release_empty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) .ioctl_ops = &video_ioctl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) .tvnorms = V4L2_STD_ALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) static const struct v4l2_ctrl_ops go7007_ctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) .s_ctrl = go7007_s_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) static const struct v4l2_ctrl_config go7007_pixel_threshold0_ctrl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) .ops = &go7007_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) .id = V4L2_CID_PIXEL_THRESHOLD0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) .name = "Pixel Threshold Region 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) .type = V4L2_CTRL_TYPE_INTEGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) .def = 20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) .max = 32767,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) .step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) static const struct v4l2_ctrl_config go7007_motion_threshold0_ctrl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) .ops = &go7007_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) .id = V4L2_CID_MOTION_THRESHOLD0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) .name = "Motion Threshold Region 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) .type = V4L2_CTRL_TYPE_INTEGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) .def = 80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) .max = 32767,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) .step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) static const struct v4l2_ctrl_config go7007_mb_threshold0_ctrl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) .ops = &go7007_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) .id = V4L2_CID_MB_THRESHOLD0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) .name = "MB Threshold Region 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) .type = V4L2_CTRL_TYPE_INTEGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) .def = 200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) .max = 32767,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) .step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) static const struct v4l2_ctrl_config go7007_pixel_threshold1_ctrl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) .ops = &go7007_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) .id = V4L2_CID_PIXEL_THRESHOLD1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) .name = "Pixel Threshold Region 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) .type = V4L2_CTRL_TYPE_INTEGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) .def = 20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) .max = 32767,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) .step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) static const struct v4l2_ctrl_config go7007_motion_threshold1_ctrl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) .ops = &go7007_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) .id = V4L2_CID_MOTION_THRESHOLD1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) .name = "Motion Threshold Region 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) .type = V4L2_CTRL_TYPE_INTEGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) .def = 80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) .max = 32767,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) .step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) static const struct v4l2_ctrl_config go7007_mb_threshold1_ctrl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) .ops = &go7007_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) .id = V4L2_CID_MB_THRESHOLD1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) .name = "MB Threshold Region 1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) .type = V4L2_CTRL_TYPE_INTEGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) .def = 200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) .max = 32767,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) .step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) static const struct v4l2_ctrl_config go7007_pixel_threshold2_ctrl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) .ops = &go7007_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) .id = V4L2_CID_PIXEL_THRESHOLD2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) .name = "Pixel Threshold Region 2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) .type = V4L2_CTRL_TYPE_INTEGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) .def = 20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) .max = 32767,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) .step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) static const struct v4l2_ctrl_config go7007_motion_threshold2_ctrl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) .ops = &go7007_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) .id = V4L2_CID_MOTION_THRESHOLD2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) .name = "Motion Threshold Region 2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) .type = V4L2_CTRL_TYPE_INTEGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) .def = 80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) .max = 32767,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) .step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) static const struct v4l2_ctrl_config go7007_mb_threshold2_ctrl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) .ops = &go7007_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) .id = V4L2_CID_MB_THRESHOLD2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) .name = "MB Threshold Region 2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) .type = V4L2_CTRL_TYPE_INTEGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) .def = 200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) .max = 32767,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) .step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) static const struct v4l2_ctrl_config go7007_pixel_threshold3_ctrl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) .ops = &go7007_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) .id = V4L2_CID_PIXEL_THRESHOLD3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) .name = "Pixel Threshold Region 3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) .type = V4L2_CTRL_TYPE_INTEGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) .def = 20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) .max = 32767,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) .step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) static const struct v4l2_ctrl_config go7007_motion_threshold3_ctrl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) .ops = &go7007_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) .id = V4L2_CID_MOTION_THRESHOLD3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) .name = "Motion Threshold Region 3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) .type = V4L2_CTRL_TYPE_INTEGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) .def = 80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) .max = 32767,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) .step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) static const struct v4l2_ctrl_config go7007_mb_threshold3_ctrl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) .ops = &go7007_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) .id = V4L2_CID_MB_THRESHOLD3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) .name = "MB Threshold Region 3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) .type = V4L2_CTRL_TYPE_INTEGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) .def = 200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) .max = 32767,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) .step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) static const struct v4l2_ctrl_config go7007_mb_regions_ctrl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) .ops = &go7007_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) .id = V4L2_CID_DETECT_MD_REGION_GRID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) .dims = { 576 / 16, 720 / 16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) .max = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) .step = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) int go7007_v4l2_ctrl_init(struct go7007 *go)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) struct v4l2_ctrl_handler *hdl = &go->hdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) struct v4l2_ctrl *ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) v4l2_ctrl_handler_init(hdl, 22);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) go->mpeg_video_gop_size = v4l2_ctrl_new_std(hdl, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, 34, 1, 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) go->mpeg_video_gop_closure = v4l2_ctrl_new_std(hdl, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, 0, 1, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) go->mpeg_video_bitrate = v4l2_ctrl_new_std(hdl, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) V4L2_CID_MPEG_VIDEO_BITRATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 64000, 10000000, 1, 9800000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) go->mpeg_video_b_frames = v4l2_ctrl_new_std(hdl, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 2, 2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) go->mpeg_video_rep_seqheader = v4l2_ctrl_new_std(hdl, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER, 0, 1, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) go->mpeg_video_aspect_ratio = v4l2_ctrl_new_std_menu(hdl, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) V4L2_CID_MPEG_VIDEO_ASPECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) V4L2_MPEG_VIDEO_ASPECT_16x9, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) V4L2_MPEG_VIDEO_ASPECT_1x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) ctrl = v4l2_ctrl_new_std(hdl, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) V4L2_CID_JPEG_ACTIVE_MARKER, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) V4L2_JPEG_ACTIVE_MARKER_DQT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) V4L2_JPEG_ACTIVE_MARKER_DHT, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) V4L2_JPEG_ACTIVE_MARKER_DQT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) V4L2_JPEG_ACTIVE_MARKER_DHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) if (ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold0_ctrl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold0_ctrl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold0_ctrl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold1_ctrl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold1_ctrl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold1_ctrl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold2_ctrl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold2_ctrl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold2_ctrl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) v4l2_ctrl_new_custom(hdl, &go7007_pixel_threshold3_ctrl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) v4l2_ctrl_new_custom(hdl, &go7007_motion_threshold3_ctrl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) v4l2_ctrl_new_custom(hdl, &go7007_mb_threshold3_ctrl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) v4l2_ctrl_new_custom(hdl, &go7007_mb_regions_ctrl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) go->modet_mode = v4l2_ctrl_new_std_menu(hdl, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) V4L2_CID_DETECT_MD_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) V4L2_DETECT_MD_MODE_REGION_GRID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 1 << V4L2_DETECT_MD_MODE_THRESHOLD_GRID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) V4L2_DETECT_MD_MODE_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (hdl->error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) int rv = hdl->error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) v4l2_err(&go->v4l2_dev, "Could not register controls\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) go->v4l2_dev.ctrl_handler = hdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) int go7007_v4l2_init(struct go7007 *go)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) struct video_device *vdev = &go->vdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) mutex_init(&go->serialize_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) mutex_init(&go->queue_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) INIT_LIST_HEAD(&go->vidq_active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) go->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) go->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) go->vidq.ops = &go7007_video_qops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) go->vidq.mem_ops = &vb2_vmalloc_memops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) go->vidq.drv_priv = go;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) go->vidq.buf_struct_size = sizeof(struct go7007_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) go->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) go->vidq.lock = &go->queue_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) rv = vb2_queue_init(&go->vidq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if (rv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) *vdev = go7007_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) vdev->lock = &go->serialize_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) vdev->queue = &go->vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) V4L2_CAP_STREAMING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) if (go->board_info->num_aud_inputs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) vdev->device_caps |= V4L2_CAP_AUDIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) vdev->device_caps |= V4L2_CAP_TUNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) video_set_drvdata(vdev, go);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) vdev->v4l2_dev = &go->v4l2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (!v4l2_device_has_op(&go->v4l2_dev, 0, video, querystd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) v4l2_disable_ioctl(vdev, VIDIOC_QUERYSTD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) v4l2_disable_ioctl(vdev, VIDIOC_S_FREQUENCY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) v4l2_disable_ioctl(vdev, VIDIOC_G_FREQUENCY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) v4l2_disable_ioctl(vdev, VIDIOC_S_TUNER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) v4l2_disable_ioctl(vdev, VIDIOC_G_TUNER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) struct v4l2_frequency f = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) .type = V4L2_TUNER_ANALOG_TV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) .frequency = 980,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) call_all(&go->v4l2_dev, tuner, s_frequency, &f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) v4l2_disable_ioctl(vdev, VIDIOC_G_STD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) v4l2_disable_ioctl(vdev, VIDIOC_S_STD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) vdev->tvnorms = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) v4l2_disable_ioctl(vdev, VIDIOC_ENUM_FRAMESIZES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) if (go->board_info->num_aud_inputs == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) v4l2_disable_ioctl(vdev, VIDIOC_G_AUDIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) v4l2_disable_ioctl(vdev, VIDIOC_S_AUDIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) v4l2_disable_ioctl(vdev, VIDIOC_ENUMAUDIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) /* Setup correct crystal frequency on this board */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (go->board_info->sensor_flags & GO7007_SENSOR_SAA7115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) v4l2_subdev_call(go->sd_video, video, s_crystal_freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) SAA7115_FREQ_24_576_MHZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) SAA7115_FREQ_FL_APLL | SAA7115_FREQ_FL_UCGC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) SAA7115_FREQ_FL_DOUBLE_ASCLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) go7007_s_input(go);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) go7007_s_std(go);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) rv = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if (rv < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) dev_info(go->dev, "registered device %s [v4l2]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) video_device_node_name(vdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) void go7007_v4l2_remove(struct go7007 *go)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) v4l2_ctrl_handler_free(&go->hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }