extractedLnx/linux-2.6.37/drivers/staging/easycap/easycap_ioctl.c_easycap_ioctl_bkl.c
static int easycap_ioctl_bkl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
static struct easycap *peasycap;
static struct usb_device *p;
static __u32 isequence;
peasycap = file->private_data;
if (NULL == peasycap) {
SAY("ERROR: peasycap is NULL\n");
return -1;
}
p = peasycap->pusb_device;
if ((struct usb_device *)NULL == p) {
SAY("ERROR: peasycap->pusb_device is NULL\n");
return -EFAULT;
}
/*---------------------------------------------------------------------------*/
/*
* MOST OF THE VARIABLES DECLARED static IN THE case{} BLOCKS BELOW ARE SO
* DECLARED SIMPLY TO AVOID A COMPILER WARNING OF THE KIND:
* easycap_ioctl.c: warning:
* the frame size of ... bytes is larger than 1024 bytes
*/
/*---------------------------------------------------------------------------*/
switch (cmd) {
case VIDIOC_QUERYCAP: {
static struct v4l2_capability v4l2_capability;
static char version[16], *p1, *p2;
static int i, rc, k[3];
static long lng;
JOT(8, "VIDIOC_QUERYCAP\n");
if (16 <= strlen(EASYCAP_DRIVER_VERSION)) {
SAY("ERROR: bad driver version string\n"); return -EINVAL;
}
strcpy(&version[0], EASYCAP_DRIVER_VERSION);
for (i = 0; i < 3; i++)
k[i] = 0;
p2 = &version[0]; i = 0;
while (*p2) {
p1 = p2;
while (*p2 && ('.' != *p2))
p2++;
if (*p2)
*p2++ = 0;
if (3 > i) {
rc = (int) strict_strtol(p1, 10, &lng);
if (0 != rc) {
SAY("ERROR: %i=strict_strtol(%s,.,,)\n", \
rc, p1);
return -EINVAL;
}
k[i] = (int)lng;
}
i++;
}
memset(&v4l2_capability, 0, sizeof(struct v4l2_capability));
strlcpy(&v4l2_capability.driver[0], "easycap", \
sizeof(v4l2_capability.driver));
v4l2_capability.capabilities = \
V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | \
V4L2_CAP_AUDIO | V4L2_CAP_READWRITE;
v4l2_capability.version = KERNEL_VERSION(k[0], k[1], k[2]);
JOT(8, "v4l2_capability.version=(%i,%i,%i)\n", k[0], k[1], k[2]);
strlcpy(&v4l2_capability.card[0], "EasyCAP DC60", \
sizeof(v4l2_capability.card));
if (usb_make_path(peasycap->pusb_device, &v4l2_capability.bus_info[0],\
sizeof(v4l2_capability.bus_info)) < 0) {
strlcpy(&v4l2_capability.bus_info[0], "EasyCAP bus_info", \
sizeof(v4l2_capability.bus_info));
JOT(8, "%s=v4l2_capability.bus_info\n", \
&v4l2_capability.bus_info[0]);
}
if (0 != copy_to_user((void __user *)arg, &v4l2_capability, \
sizeof(struct v4l2_capability))) {
POUT;
return -EFAULT;
}
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_ENUMINPUT: {
static struct v4l2_input v4l2_input;
static __u32 index;
JOT(8, "VIDIOC_ENUMINPUT\n");
if (0 != copy_from_user(&v4l2_input, (void __user *)arg, \
sizeof(struct v4l2_input))) {
POUT;
return -EFAULT;
}
index = v4l2_input.index;
memset(&v4l2_input, 0, sizeof(struct v4l2_input));
switch (index) {
case 0: {
v4l2_input.index = index;
strcpy(&v4l2_input.name[0], "CVBS0");
v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
v4l2_input.audioset = 0x01;
v4l2_input.tuner = 0;
v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
V4L2_STD_NTSC ;
v4l2_input.status = 0;
JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
break;
}
case 1: {
v4l2_input.index = index;
strcpy(&v4l2_input.name[0], "CVBS1");
v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
v4l2_input.audioset = 0x01;
v4l2_input.tuner = 0;
v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
V4L2_STD_NTSC ;
v4l2_input.status = 0;
JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
break;
}
case 2: {
v4l2_input.index = index;
strcpy(&v4l2_input.name[0], "CVBS2");
v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
v4l2_input.audioset = 0x01;
v4l2_input.tuner = 0;
v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
V4L2_STD_NTSC ;
v4l2_input.status = 0;
JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
break;
}
case 3: {
v4l2_input.index = index;
strcpy(&v4l2_input.name[0], "CVBS3");
v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
v4l2_input.audioset = 0x01;
v4l2_input.tuner = 0;
v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
V4L2_STD_NTSC ;
v4l2_input.status = 0;
JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
break;
}
case 4: {
v4l2_input.index = index;
strcpy(&v4l2_input.name[0], "CVBS4");
v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
v4l2_input.audioset = 0x01;
v4l2_input.tuner = 0;
v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
V4L2_STD_NTSC ;
v4l2_input.status = 0;
JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
break;
}
case 5: {
v4l2_input.index = index;
strcpy(&v4l2_input.name[0], "S-VIDEO");
v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
v4l2_input.audioset = 0x01;
v4l2_input.tuner = 0;
v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \
V4L2_STD_NTSC ;
v4l2_input.status = 0;
JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
break;
}
default: {
JOT(8, "%i=index: exhausts inputs\n", index);
return -EINVAL;
}
}
if (0 != copy_to_user((void __user *)arg, &v4l2_input, \
sizeof(struct v4l2_input))) {
POUT;
return -EFAULT;
}
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_G_INPUT: {
static __u32 index;
JOT(8, "VIDIOC_G_INPUT\n");
index = (__u32)peasycap->input;
JOT(8, "user is told: %i\n", index);
if (0 != copy_to_user((void __user *)arg, &index, sizeof(__u32))) {
POUT;
return -EFAULT;
}
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_S_INPUT:
{
static __u32 index;
JOT(8, "VIDIOC_S_INPUT\n");
if (0 != copy_from_user(&index, (void __user *)arg, sizeof(__u32))) {
POUT;
return -EFAULT;
}
JOT(8, "user requests input %i\n", index);
if ((int)index == peasycap->input) {
SAY("requested input already in effect\n");
break;
}
if ((0 > index) || (5 < index)) {
JOT(8, "ERROR: bad requested input: %i\n", index);
return -EINVAL;
}
peasycap->input = (int)index;
select_input(peasycap->pusb_device, peasycap->input, 9);
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_ENUMAUDIO: {
JOT(8, "VIDIOC_ENUMAUDIO\n");
return -EINVAL;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_ENUMAUDOUT: {
static struct v4l2_audioout v4l2_audioout;
JOT(8, "VIDIOC_ENUMAUDOUT\n");
if (0 != copy_from_user(&v4l2_audioout, (void __user *)arg, \
sizeof(struct v4l2_audioout))) {
POUT;
return -EFAULT;
}
if (0 != v4l2_audioout.index)
return -EINVAL;
memset(&v4l2_audioout, 0, sizeof(struct v4l2_audioout));
v4l2_audioout.index = 0;
strcpy(&v4l2_audioout.name[0], "Soundtrack");
if (0 != copy_to_user((void __user *)arg, &v4l2_audioout, \
sizeof(struct v4l2_audioout))) {
POUT;
return -EFAULT;
}
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_QUERYCTRL: {
static int i1;
static struct v4l2_queryctrl v4l2_queryctrl;
JOT(8, "VIDIOC_QUERYCTRL\n");
if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg, \
sizeof(struct v4l2_queryctrl))) {
POUT;
return -EFAULT;
}
i1 = 0;
while (0xFFFFFFFF != easycap_control[i1].id) {
if (easycap_control[i1].id == v4l2_queryctrl.id) {
JOT(8, "VIDIOC_QUERYCTRL %s=easycap_control[%i]" \
".name\n", &easycap_control[i1].name[0], i1);
memcpy(&v4l2_queryctrl, &easycap_control[i1], \
sizeof(struct v4l2_queryctrl));
break;
}
i1++;
}
if (0xFFFFFFFF == easycap_control[i1].id) {
JOT(8, "%i=index: exhausts controls\n", i1);
return -EINVAL;
}
if (0 != copy_to_user((void __user *)arg, &v4l2_queryctrl, \
sizeof(struct v4l2_queryctrl))) {
POUT;
return -EFAULT;
}
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_QUERYMENU: {
JOT(8, "VIDIOC_QUERYMENU unsupported\n");
return -EINVAL;
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_G_CTRL: {
static struct v4l2_control v4l2_control;
JOT(8, "VIDIOC_G_CTRL\n");
if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \
sizeof(struct v4l2_control))) {
POUT;
return -EFAULT;
}
switch (v4l2_control.id) {
case V4L2_CID_BRIGHTNESS: {
v4l2_control.value = peasycap->brightness;
JOT(8, "user enquires brightness: %i\n", v4l2_control.value);
break;
}
case V4L2_CID_CONTRAST: {
v4l2_control.value = peasycap->contrast;
JOT(8, "user enquires contrast: %i\n", v4l2_control.value);
break;
}
case V4L2_CID_SATURATION: {
v4l2_control.value = peasycap->saturation;
JOT(8, "user enquires saturation: %i\n", v4l2_control.value);
break;
}
case V4L2_CID_HUE: {
v4l2_control.value = peasycap->hue;
JOT(8, "user enquires hue: %i\n", v4l2_control.value);
break;
}
case V4L2_CID_AUDIO_VOLUME: {
v4l2_control.value = peasycap->volume;
JOT(8, "user enquires volume: %i\n", v4l2_control.value);
break;
}
case V4L2_CID_AUDIO_MUTE: {
if (1 == peasycap->mute)
v4l2_control.value = true;
else
v4l2_control.value = false;
JOT(8, "user enquires mute: %i\n", v4l2_control.value);
break;
}
default: {
SAY("ERROR: unknown V4L2 control: 0x%08X=id\n", \
v4l2_control.id);
explain_cid(v4l2_control.id);
return -EINVAL;
}
}
if (0 != copy_to_user((void __user *)arg, &v4l2_control, \
sizeof(struct v4l2_control))) {
POUT;
return -EFAULT;
}
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(VIDIOC_S_CTRL_OLD)
case VIDIOC_S_CTRL_OLD: {
JOT(8, "VIDIOC_S_CTRL_OLD required at least for xawtv\n");
}
#endif /*VIDIOC_S_CTRL_OLD*/
case VIDIOC_S_CTRL:
{
static struct v4l2_control v4l2_control;
JOT(8, "VIDIOC_S_CTRL\n");
if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \
sizeof(struct v4l2_control))) {
POUT;
return -EFAULT;
}
switch (v4l2_control.id) {
case V4L2_CID_BRIGHTNESS: {
JOT(8, "user requests brightness %i\n", v4l2_control.value);
if (0 != adjust_brightness(peasycap, v4l2_control.value))
;
break;
}
case V4L2_CID_CONTRAST: {
JOT(8, "user requests contrast %i\n", v4l2_control.value);
if (0 != adjust_contrast(peasycap, v4l2_control.value))
;
break;
}
case V4L2_CID_SATURATION: {
JOT(8, "user requests saturation %i\n", v4l2_control.value);
if (0 != adjust_saturation(peasycap, v4l2_control.value))
;
break;
}
case V4L2_CID_HUE: {
JOT(8, "user requests hue %i\n", v4l2_control.value);
if (0 != adjust_hue(peasycap, v4l2_control.value))
;
break;
}
case V4L2_CID_AUDIO_VOLUME: {
JOT(8, "user requests volume %i\n", v4l2_control.value);
if (0 != adjust_volume(peasycap, v4l2_control.value))
;
break;
}
case V4L2_CID_AUDIO_MUTE: {
int mute;
JOT(8, "user requests mute %i\n", v4l2_control.value);
if (true == v4l2_control.value)
mute = 1;
else
mute = 0;
if (0 != adjust_mute(peasycap, mute))
SAY("WARNING: failed to adjust mute to %i\n", mute);
break;
}
default: {
SAY("ERROR: unknown V4L2 control: 0x%08X=id\n", \
v4l2_control.id);
explain_cid(v4l2_control.id);
return -EINVAL;
}
}
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_S_EXT_CTRLS: {
JOT(8, "VIDIOC_S_EXT_CTRLS unsupported\n");
return -EINVAL;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_ENUM_FMT: {
static __u32 index;
static struct v4l2_fmtdesc v4l2_fmtdesc;
JOT(8, "VIDIOC_ENUM_FMT\n");
if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg, \
sizeof(struct v4l2_fmtdesc))) {
POUT;
return -EFAULT;
}
index = v4l2_fmtdesc.index;
memset(&v4l2_fmtdesc, 0, sizeof(struct v4l2_fmtdesc));
v4l2_fmtdesc.index = index;
v4l2_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
switch (index) {
case 0: {
v4l2_fmtdesc.flags = 0;
strcpy(&v4l2_fmtdesc.description[0], "uyvy");
v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_UYVY;
JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
break;
}
case 1: {
v4l2_fmtdesc.flags = 0;
strcpy(&v4l2_fmtdesc.description[0], "yuy2");
v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_YUYV;
JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
break;
}
case 2: {
v4l2_fmtdesc.flags = 0;
strcpy(&v4l2_fmtdesc.description[0], "rgb24");
v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB24;
JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
break;
}
case 3: {
v4l2_fmtdesc.flags = 0;
strcpy(&v4l2_fmtdesc.description[0], "rgb32");
v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB32;
JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
break;
}
case 4: {
v4l2_fmtdesc.flags = 0;
strcpy(&v4l2_fmtdesc.description[0], "bgr24");
v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR24;
JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
break;
}
case 5: {
v4l2_fmtdesc.flags = 0;
strcpy(&v4l2_fmtdesc.description[0], "bgr32");
v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR32;
JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
break;
}
default: {
JOT(8, "%i=index: exhausts formats\n", index);
return -EINVAL;
}
}
if (0 != copy_to_user((void __user *)arg, &v4l2_fmtdesc, \
sizeof(struct v4l2_fmtdesc))) {
POUT;
return -EFAULT;
}
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_ENUM_FRAMESIZES: {
JOT(8, "VIDIOC_ENUM_FRAMESIZES unsupported\n");
return -EINVAL;
}
case VIDIOC_ENUM_FRAMEINTERVALS: {
JOT(8, "VIDIOC_ENUM_FRAME_INTERVALS unsupported\n");
return -EINVAL;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_G_FMT: {
static struct v4l2_format v4l2_format;
static struct v4l2_pix_format v4l2_pix_format;
JOT(8, "VIDIOC_G_FMT\n");
if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \
sizeof(struct v4l2_format))) {
POUT;
return -EFAULT;
}
if (v4l2_format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
POUT;
return -EINVAL;
}
memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format));
v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
memcpy(&(v4l2_format.fmt.pix), \
&(easycap_format[peasycap->format_offset]\
.v4l2_format.fmt.pix), sizeof(v4l2_pix_format));
JOT(8, "user is told: %s\n", \
&easycap_format[peasycap->format_offset].name[0]);
if (0 != copy_to_user((void __user *)arg, &v4l2_format, \
sizeof(struct v4l2_format))) {
POUT;
return -EFAULT;
}
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_TRY_FMT:
case VIDIOC_S_FMT: {
static struct v4l2_format v4l2_format;
static struct v4l2_pix_format v4l2_pix_format;
static bool try;
static int best_format;
if (VIDIOC_TRY_FMT == cmd) {
JOT(8, "VIDIOC_TRY_FMT\n");
try = true;
} else {
JOT(8, "VIDIOC_S_FMT\n");
try = false;
}
if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \
sizeof(struct v4l2_format))) {
POUT;
return -EFAULT;
}
best_format = adjust_format(peasycap, \
v4l2_format.fmt.pix.width, \
v4l2_format.fmt.pix.height, \
v4l2_format.fmt.pix.pixelformat, \
v4l2_format.fmt.pix.field, \
try);
if (0 > best_format) {
JOT(8, "WARNING: adjust_format() returned %i\n", best_format);
return -ENOENT;
}
/*...........................................................................*/
memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format));
v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
memcpy(&(v4l2_format.fmt.pix), &(easycap_format[best_format]\
.v4l2_format.fmt.pix), sizeof(v4l2_pix_format));
JOT(8, "user is told: %s\n", &easycap_format[best_format].name[0]);
if (0 != copy_to_user((void __user *)arg, &v4l2_format, \
sizeof(struct v4l2_format))) {
POUT;
return -EFAULT;
}
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_CROPCAP: {
static struct v4l2_cropcap v4l2_cropcap;
JOT(8, "VIDIOC_CROPCAP\n");
if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg, \
sizeof(struct v4l2_cropcap))) {
POUT;
return -EFAULT;
}
if (v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
JOT(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
memset(&v4l2_cropcap, 0, sizeof(struct v4l2_cropcap));
v4l2_cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
v4l2_cropcap.bounds.left = 0;
v4l2_cropcap.bounds.top = 0;
v4l2_cropcap.bounds.width = peasycap->width;
v4l2_cropcap.bounds.height = peasycap->height;
v4l2_cropcap.defrect.left = 0;
v4l2_cropcap.defrect.top = 0;
v4l2_cropcap.defrect.width = peasycap->width;
v4l2_cropcap.defrect.height = peasycap->height;
v4l2_cropcap.pixelaspect.numerator = 1;
v4l2_cropcap.pixelaspect.denominator = 1;
JOT(8, "user is told: %ix%i\n", peasycap->width, peasycap->height);
if (0 != copy_to_user((void __user *)arg, &v4l2_cropcap, \
sizeof(struct v4l2_cropcap))) {
POUT;
return -EFAULT;
}
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_G_CROP:
case VIDIOC_S_CROP: {
JOT(8, "VIDIOC_G_CROP|VIDIOC_S_CROP unsupported\n");
return -EINVAL;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_QUERYSTD: {
JOT(8, "VIDIOC_QUERYSTD: " \
"EasyCAP is incapable of detecting standard\n");
return -EINVAL;
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*---------------------------------------------------------------------------*/
/*
* THE MANIPULATIONS INVOLVING last0,last1,last2,last3 CONSTITUTE A WORKAROUND
* FOR WHAT APPEARS TO BE A BUG IN 64-BIT mplayer.
* NOT NEEDED, BUT HOPEFULLY HARMLESS, FOR 32-BIT mplayer.
*/
/*---------------------------------------------------------------------------*/
case VIDIOC_ENUMSTD: {
static int last0 = -1, last1 = -1, last2 = -1, last3 = -1;
static struct v4l2_standard v4l2_standard;
static __u32 index;
static struct easycap_standard const *peasycap_standard;
JOT(8, "VIDIOC_ENUMSTD\n");
if (0 != copy_from_user(&v4l2_standard, (void __user *)arg, \
sizeof(struct v4l2_standard))) {
POUT;
return -EFAULT;
}
index = v4l2_standard.index;
last3 = last2; last2 = last1; last1 = last0; last0 = index;
if ((index == last3) && (index == last2) && \
(index == last1) && (index == last0)) {
index++;
last3 = last2; last2 = last1; last1 = last0; last0 = index;
}
memset(&v4l2_standard, 0, sizeof(struct v4l2_standard));
peasycap_standard = &easycap_standard[0];
while (0xFFFF != peasycap_standard->mask) {
if ((int)(peasycap_standard - &easycap_standard[0]) == index)
break;
peasycap_standard++;
}
if (0xFFFF == peasycap_standard->mask) {
JOT(8, "%i=index: exhausts standards\n", index);
return -EINVAL;
}
JOT(8, "%i=index: %s\n", index, \
&(peasycap_standard->v4l2_standard.name[0]));
memcpy(&v4l2_standard, &(peasycap_standard->v4l2_standard), \
sizeof(struct v4l2_standard));
v4l2_standard.index = index;
if (0 != copy_to_user((void __user *)arg, &v4l2_standard, \
sizeof(struct v4l2_standard))) {
POUT;
return -EFAULT;
}
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_G_STD: {
static v4l2_std_id std_id;
static struct easycap_standard const *peasycap_standard;
JOT(8, "VIDIOC_G_STD\n");
if (0 != copy_from_user(&std_id, (void __user *)arg, \
sizeof(v4l2_std_id))) {
POUT;
return -EFAULT;
}
peasycap_standard = &easycap_standard[peasycap->standard_offset];
std_id = peasycap_standard->v4l2_standard.id;
JOT(8, "user is told: %s\n", \
&peasycap_standard->v4l2_standard.name[0]);
if (0 != copy_to_user((void __user *)arg, &std_id, \
sizeof(v4l2_std_id))) {
POUT;
return -EFAULT;
}
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_S_STD: {
static v4l2_std_id std_id;
static int rc;
JOT(8, "VIDIOC_S_STD\n");
if (0 != copy_from_user(&std_id, (void __user *)arg, \
sizeof(v4l2_std_id))) {
POUT;
return -EFAULT;
}
rc = adjust_standard(peasycap, std_id);
if (0 > rc) {
JOT(8, "WARNING: adjust_standard() returned %i\n", rc);
return -ENOENT;
}
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_REQBUFS: {
static int nbuffers;
static struct v4l2_requestbuffers v4l2_requestbuffers;
JOT(8, "VIDIOC_REQBUFS\n");
if (0 != copy_from_user(&v4l2_requestbuffers, (void __user *)arg, \
sizeof(struct v4l2_requestbuffers))) {
POUT;
return -EFAULT;
}
if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) {
POUT;
return -EINVAL;
}
nbuffers = v4l2_requestbuffers.count;
JOT(8, " User requests %i buffers ...\n", nbuffers);
if (nbuffers < 2)
nbuffers = 2;
if (nbuffers > FRAME_BUFFER_MANY)
nbuffers = FRAME_BUFFER_MANY;
if (v4l2_requestbuffers.count == nbuffers) {
JOT(8, " ... agree to %i buffers\n", \
nbuffers);
} else {
JOT(8, " ... insist on %i buffers\n", \
nbuffers);
v4l2_requestbuffers.count = nbuffers;
}
peasycap->frame_buffer_many = nbuffers;
if (0 != copy_to_user((void __user *)arg, &v4l2_requestbuffers, \
sizeof(struct v4l2_requestbuffers))) {
POUT;
return -EFAULT;
}
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_QUERYBUF: {
static __u32 index;
static struct v4l2_buffer v4l2_buffer;
JOT(8, "VIDIOC_QUERYBUF\n");
if (peasycap->video_eof) {
JOT(8, "returning -1 because %i=video_eof\n", \
peasycap->video_eof);
return -1;
}
if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
sizeof(struct v4l2_buffer))) {
POUT;
return -EFAULT;
}
if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
index = v4l2_buffer.index;
if (index < 0 || index >= peasycap->frame_buffer_many)
return -EINVAL;
memset(&v4l2_buffer, 0, sizeof(struct v4l2_buffer));
v4l2_buffer.index = index;
v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
v4l2_buffer.bytesused = peasycap->frame_buffer_used;
v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | \
peasycap->done[index] | \
peasycap->queued[index];
v4l2_buffer.field = peasycap->field;
v4l2_buffer.memory = V4L2_MEMORY_MMAP;
v4l2_buffer.m.offset = index * FRAME_BUFFER_SIZE;
v4l2_buffer.length = FRAME_BUFFER_SIZE;
JOT(16, " %10i=index\n", v4l2_buffer.index);
JOT(16, " 0x%08X=type\n", v4l2_buffer.type);
JOT(16, " %10i=bytesused\n", v4l2_buffer.bytesused);
JOT(16, " 0x%08X=flags\n", v4l2_buffer.flags);
JOT(16, " %10i=field\n", v4l2_buffer.field);
JOT(16, " %10li=timestamp.tv_usec\n", \
(long)v4l2_buffer.timestamp.tv_usec);
JOT(16, " %10i=sequence\n", v4l2_buffer.sequence);
JOT(16, " 0x%08X=memory\n", v4l2_buffer.memory);
JOT(16, " %10i=m.offset\n", v4l2_buffer.m.offset);
JOT(16, " %10i=length\n", v4l2_buffer.length);
if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
sizeof(struct v4l2_buffer))) {
POUT;
return -EFAULT;
}
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_QBUF: {
static struct v4l2_buffer v4l2_buffer;
JOT(8, "VIDIOC_QBUF\n");
if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
sizeof(struct v4l2_buffer))) {
POUT;
return -EFAULT;
}
if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
if (v4l2_buffer.memory != V4L2_MEMORY_MMAP)
return -EINVAL;
if (v4l2_buffer.index < 0 || \
(v4l2_buffer.index >= peasycap->frame_buffer_many))
return -EINVAL;
v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED;
peasycap->done[v4l2_buffer.index] = 0;
peasycap->queued[v4l2_buffer.index] = V4L2_BUF_FLAG_QUEUED;
if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
sizeof(struct v4l2_buffer))) {
POUT;
return -EFAULT;
}
JOT(8, "..... user queueing frame buffer %i\n", \
(int)v4l2_buffer.index);
peasycap->frame_lock = 0;
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_DQBUF:
{
#if defined(AUDIOTIME)
static struct signed_div_result sdr;
static long long int above, below, dnbydt, fudge, sll;
static unsigned long long int ull;
static struct timeval timeval0;
struct timeval timeval1;
#endif /*AUDIOTIME*/
static struct timeval timeval, timeval2;
static int i, j;
static struct v4l2_buffer v4l2_buffer;
JOT(8, "VIDIOC_DQBUF\n");
if ((peasycap->video_idle) || (peasycap->video_eof)) {
JOT(8, "returning -EIO because " \
"%i=video_idle %i=video_eof\n", \
peasycap->video_idle, peasycap->video_eof);
return -EIO;
}
if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \
sizeof(struct v4l2_buffer))) {
POUT;
return -EFAULT;
}
if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
if (!peasycap->video_isoc_streaming) {
JOT(16, "returning -EIO because video urbs not streaming\n");
return -EIO;
}
/*---------------------------------------------------------------------------*/
/*
* IF THE USER HAS PREVIOUSLY CALLED easycap_poll(), AS DETERMINED BY FINDING
* THE FLAG peasycap->polled SET, THERE MUST BE NO FURTHER WAIT HERE. IN THIS
* CASE, JUST CHOOSE THE FRAME INDICATED BY peasycap->frame_read
*/
/*---------------------------------------------------------------------------*/
if (!peasycap->polled) {
if (-EIO == easycap_dqbuf(peasycap, 0))
return -EIO;
} else {
if (peasycap->video_eof)
return -EIO;
}
if (V4L2_BUF_FLAG_DONE != peasycap->done[peasycap->frame_read]) {
SAY("ERROR: V4L2_BUF_FLAG_DONE != 0x%08X\n", \
peasycap->done[peasycap->frame_read]);
}
peasycap->polled = 0;
if (!(isequence % 10)) {
for (i = 0; i < 179; i++)
peasycap->merit[i] = peasycap->merit[i+1];
peasycap->merit[179] = merit_saa(peasycap->pusb_device);
j = 0;
for (i = 0; i < 180; i++)
j += peasycap->merit[i];
if (90 < j) {
SAY("easycap driver shutting down " \
"on condition blue\n");
peasycap->video_eof = 1; peasycap->audio_eof = 1;
}
}
v4l2_buffer.index = peasycap->frame_read;
v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
v4l2_buffer.bytesused = peasycap->frame_buffer_used;
v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE;
v4l2_buffer.field = peasycap->field;
if (V4L2_FIELD_ALTERNATE == v4l2_buffer.field)
v4l2_buffer.field = \
0x000F & (peasycap->\
frame_buffer[peasycap->frame_read][0].kount);
do_gettimeofday(&timeval);
timeval2 = timeval;
#if defined(AUDIOTIME)
if (!peasycap->timeval0.tv_sec) {
timeval0 = timeval;
timeval1 = timeval;
timeval2 = timeval;
dnbydt = 192000;
if (mutex_lock_interruptible(&(peasycap->mutex_timeval0)))
return -ERESTARTSYS;
peasycap->timeval0 = timeval0;
mutex_unlock(&(peasycap->mutex_timeval0));
} else {
if (mutex_lock_interruptible(&(peasycap->mutex_timeval1)))
return -ERESTARTSYS;
dnbydt = peasycap->dnbydt;
timeval1 = peasycap->timeval1;
mutex_unlock(&(peasycap->mutex_timeval1));
above = dnbydt * MICROSECONDS(timeval, timeval1);
below = 192000;
sdr = signed_div(above, below);
above = sdr.quotient + timeval1.tv_usec - 350000;
below = 1000000;
sdr = signed_div(above, below);
timeval2.tv_usec = sdr.remainder;
timeval2.tv_sec = timeval1.tv_sec + sdr.quotient;
}
if (!(isequence % 500)) {
fudge = ((long long int)(1000000)) * \
((long long int)(timeval.tv_sec - \
timeval2.tv_sec)) + \
(long long int)(timeval.tv_usec - \
timeval2.tv_usec);
sdr = signed_div(fudge, 1000);
sll = sdr.quotient;
ull = sdr.remainder;
SAY("%5lli.%-3lli=ms timestamp fudge\n", sll, ull);
}
#endif /*AUDIOTIME*/
v4l2_buffer.timestamp = timeval2;
v4l2_buffer.sequence = isequence++;
v4l2_buffer.memory = V4L2_MEMORY_MMAP;
v4l2_buffer.m.offset = v4l2_buffer.index * FRAME_BUFFER_SIZE;
v4l2_buffer.length = FRAME_BUFFER_SIZE;
JOT(16, " %10i=index\n", v4l2_buffer.index);
JOT(16, " 0x%08X=type\n", v4l2_buffer.type);
JOT(16, " %10i=bytesused\n", v4l2_buffer.bytesused);
JOT(16, " 0x%08X=flags\n", v4l2_buffer.flags);
JOT(16, " %10i=field\n", v4l2_buffer.field);
JOT(16, " %10li=timestamp.tv_usec\n", \
(long)v4l2_buffer.timestamp.tv_usec);
JOT(16, " %10i=sequence\n", v4l2_buffer.sequence);
JOT(16, " 0x%08X=memory\n", v4l2_buffer.memory);
JOT(16, " %10i=m.offset\n", v4l2_buffer.m.offset);
JOT(16, " %10i=length\n", v4l2_buffer.length);
if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \
sizeof(struct v4l2_buffer))) {
POUT;
return -EFAULT;
}
JOT(8, "..... user is offered frame buffer %i\n", \
peasycap->frame_read);
peasycap->frame_lock = 1;
if (peasycap->frame_read == peasycap->frame_fill) {
if (peasycap->frame_lock) {
JOT(8, "ERROR: filling frame buffer " \
"while offered to user\n");
}
}
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*---------------------------------------------------------------------------*/
/*
* AUDIO URBS HAVE ALREADY BEEN SUBMITTED WHEN THIS COMMAND IS RECEIVED;
* VIDEO URBS HAVE NOT.
*/
/*---------------------------------------------------------------------------*/
case VIDIOC_STREAMON: {
static int i;
JOT(8, "VIDIOC_STREAMON\n");
isequence = 0;
for (i = 0; i < 180; i++)
peasycap->merit[i] = 0;
if ((struct usb_device *)NULL == peasycap->pusb_device) {
SAY("ERROR: peasycap->pusb_device is NULL\n");
return -EFAULT;
}
submit_video_urbs(peasycap);
peasycap->video_idle = 0;
peasycap->audio_idle = 0;
peasycap->video_eof = 0;
peasycap->audio_eof = 0;
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_STREAMOFF: {
JOT(8, "VIDIOC_STREAMOFF\n");
if ((struct usb_device *)NULL == peasycap->pusb_device) {
SAY("ERROR: peasycap->pusb_device is NULL\n");
return -EFAULT;
}
peasycap->video_idle = 1;
peasycap->audio_idle = 1; peasycap->timeval0.tv_sec = 0;
/*---------------------------------------------------------------------------*/
/*
* IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO THE STREAMOFF COMMAND
* THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE.
*/
/*---------------------------------------------------------------------------*/
JOT(8, "calling wake_up on wq_video and wq_audio\n");
wake_up_interruptible(&(peasycap->wq_video));
wake_up_interruptible(&(peasycap->wq_audio));
/*---------------------------------------------------------------------------*/
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_G_PARM: {
static struct v4l2_streamparm v4l2_streamparm;
JOT(8, "VIDIOC_G_PARM\n");
if (0 != copy_from_user(&v4l2_streamparm, (void __user *)arg, \
sizeof(struct v4l2_streamparm))) {
POUT;
return -EFAULT;
}
if (v4l2_streamparm.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
POUT;
return -EINVAL;
}
v4l2_streamparm.parm.capture.capability = 0;
v4l2_streamparm.parm.capture.capturemode = 0;
v4l2_streamparm.parm.capture.timeperframe.numerator = 1;
v4l2_streamparm.parm.capture.timeperframe.denominator = 30;
v4l2_streamparm.parm.capture.readbuffers = peasycap->frame_buffer_many;
v4l2_streamparm.parm.capture.extendedmode = 0;
if (0 != copy_to_user((void __user *)arg, &v4l2_streamparm, \
sizeof(struct v4l2_streamparm))) {
POUT;
return -EFAULT;
}
break;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_S_PARM: {
JOT(8, "VIDIOC_S_PARM unsupported\n");
return -EINVAL;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_G_AUDIO: {
JOT(8, "VIDIOC_G_AUDIO unsupported\n");
return -EINVAL;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_S_AUDIO: {
JOT(8, "VIDIOC_S_AUDIO unsupported\n");
return -EINVAL;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_S_TUNER: {
JOT(8, "VIDIOC_S_TUNER unsupported\n");
return -EINVAL;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_G_FBUF:
case VIDIOC_S_FBUF:
case VIDIOC_OVERLAY: {
JOT(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n");
return -EINVAL;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
case VIDIOC_G_TUNER: {
JOT(8, "VIDIOC_G_TUNER unsupported\n");
return -EINVAL;
}
case VIDIOC_G_FREQUENCY:
case VIDIOC_S_FREQUENCY: {
JOT(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n");
return -EINVAL;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
default: {
JOT(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd);
explain_ioctl(cmd);
POUT;
return -ENOIOCTLCMD;
}
}
return 0;
}
Generated by GNU enscript 1.6.4.