#include <linux/i2c-algo-sgi.h>
#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <linux/video_decoder.h>
#include <linux/mutex.h>
#include <asm/paccess.h>
#define VINO_DATA_NORM_PAL 1
#define VINO_DATA_NORM_SECAM 2
#define VINO_DATA_NORM_D1 3
-/* The following are special entries that can be used to
- * autodetect the norm. */
-#define VINO_DATA_NORM_AUTO 0xfe
-#define VINO_DATA_NORM_AUTO_EXT 0xff
#define VINO_DATA_NORM_COUNT 4
struct vino_interrupt_data int_data;
/* V4L support */
- struct video_device *v4l_device;
+ struct video_device *vdev;
};
struct vino_client {
};
struct vino_settings {
+ struct v4l2_device v4l2_dev;
struct vino_channel_settings a;
struct vino_channel_settings b;
static const char *vino_driver_name = "vino";
static const char *vino_driver_description = "SGI VINO";
static const char *vino_bus_name = "GIO64 bus";
-static const char *vino_v4l_device_name_a = "SGI VINO Channel A";
-static const char *vino_v4l_device_name_b = "SGI VINO Channel B";
+static const char *vino_vdev_name_a = "SGI VINO Channel A";
+static const char *vino_vdev_name_b = "SGI VINO Channel B";
static void vino_capture_tasklet(unsigned long channel);
.name = "Composite",
.std = V4L2_STD_NTSC | V4L2_STD_PAL
| V4L2_STD_SECAM,
- },{
+ }, {
.name = "S-Video",
.std = V4L2_STD_NTSC | V4L2_STD_PAL
| V4L2_STD_SECAM,
- },{
+ }, {
.name = "D1/IndyCam",
.std = V4L2_STD_NTSC,
}
.bpp = 1,
.pixelformat = V4L2_PIX_FMT_GREY,
.colorspace = V4L2_COLORSPACE_SMPTE170M,
- },{
+ }, {
.description = "8-bit dithered RGB 3-3-2",
.bpp = 1,
.pixelformat = V4L2_PIX_FMT_RGB332,
.colorspace = V4L2_COLORSPACE_SRGB,
- },{
+ }, {
.description = "32-bit RGB",
.bpp = 4,
.pixelformat = V4L2_PIX_FMT_RGB32,
.colorspace = V4L2_COLORSPACE_SRGB,
- },{
+ }, {
.description = "YUV 4:2:2",
.bpp = 2,
.pixelformat = V4L2_PIX_FMT_YUYV, // XXX: swapped?
+ VINO_NTSC_HEIGHT / 2 - 1,
.right = VINO_NTSC_WIDTH,
},
- },{
+ }, {
.description = "PAL",
.std = V4L2_STD_PAL,
.fps_min = 5,
+ VINO_PAL_HEIGHT / 2 - 1,
.right = VINO_PAL_WIDTH,
},
- },{
+ }, {
.description = "SECAM",
.std = V4L2_STD_SECAM,
.fps_min = 5,
+ VINO_PAL_HEIGHT / 2 - 1,
.right = VINO_PAL_WIDTH,
},
- },{
+ }, {
.description = "NTSC/D1",
.std = V4L2_STD_NTSC,
.fps_min = 6,
.maximum = 1,
.step = 1,
.default_value = INDYCAM_AGC_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_AGC, 0 },
- },{
+ }, {
.id = V4L2_CID_AUTO_WHITE_BALANCE,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "Automatic White Balance",
.maximum = 1,
.step = 1,
.default_value = INDYCAM_AWB_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_AWB, 0 },
- },{
+ }, {
.id = V4L2_CID_GAIN,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Gain",
.maximum = INDYCAM_GAIN_MAX,
.step = 1,
.default_value = INDYCAM_GAIN_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_GAIN, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE,
+ }, {
+ .id = INDYCAM_CONTROL_RED_SATURATION,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Red Saturation",
.minimum = INDYCAM_RED_SATURATION_MIN,
.maximum = INDYCAM_RED_SATURATION_MAX,
.step = 1,
.default_value = INDYCAM_RED_SATURATION_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_RED_SATURATION, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 1,
+ }, {
+ .id = INDYCAM_CONTROL_BLUE_SATURATION,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Blue Saturation",
.minimum = INDYCAM_BLUE_SATURATION_MIN,
.maximum = INDYCAM_BLUE_SATURATION_MAX,
.step = 1,
.default_value = INDYCAM_BLUE_SATURATION_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_BLUE_SATURATION, 0 },
- },{
+ }, {
.id = V4L2_CID_RED_BALANCE,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Red Balance",
.maximum = INDYCAM_RED_BALANCE_MAX,
.step = 1,
.default_value = INDYCAM_RED_BALANCE_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_RED_BALANCE, 0 },
- },{
+ }, {
.id = V4L2_CID_BLUE_BALANCE,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Blue Balance",
.maximum = INDYCAM_BLUE_BALANCE_MAX,
.step = 1,
.default_value = INDYCAM_BLUE_BALANCE_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_BLUE_BALANCE, 0 },
- },{
+ }, {
.id = V4L2_CID_EXPOSURE,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Shutter Control",
.maximum = INDYCAM_SHUTTER_MAX,
.step = 1,
.default_value = INDYCAM_SHUTTER_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_SHUTTER, 0 },
- },{
+ }, {
.id = V4L2_CID_GAMMA,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Gamma",
.maximum = INDYCAM_GAMMA_MAX,
.step = 1,
.default_value = INDYCAM_GAMMA_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_GAMMA, 0 },
}
};
.maximum = SAA7191_HUE_MAX,
.step = 1,
.default_value = SAA7191_HUE_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_HUE, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE,
+ }, {
+ .id = SAA7191_CONTROL_BANDPASS,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Luminance Bandpass",
.minimum = SAA7191_BANDPASS_MIN,
.maximum = SAA7191_BANDPASS_MAX,
.step = 1,
.default_value = SAA7191_BANDPASS_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_BANDPASS, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 1,
+ }, {
+ .id = SAA7191_CONTROL_BANDPASS_WEIGHT,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Luminance Bandpass Weight",
.minimum = SAA7191_BANDPASS_WEIGHT_MIN,
.maximum = SAA7191_BANDPASS_WEIGHT_MAX,
.step = 1,
.default_value = SAA7191_BANDPASS_WEIGHT_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_BANDPASS_WEIGHT, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 2,
+ }, {
+ .id = SAA7191_CONTROL_CORING,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "HF Luminance Coring",
.minimum = SAA7191_CORING_MIN,
.maximum = SAA7191_CORING_MAX,
.step = 1,
.default_value = SAA7191_CORING_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_CORING, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 3,
+ }, {
+ .id = SAA7191_CONTROL_FORCE_COLOUR,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "Force Colour",
.minimum = SAA7191_FORCE_COLOUR_MIN,
.maximum = SAA7191_FORCE_COLOUR_MAX,
.step = 1,
.default_value = SAA7191_FORCE_COLOUR_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_FORCE_COLOUR, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 4,
+ }, {
+ .id = SAA7191_CONTROL_CHROMA_GAIN,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Chrominance Gain Control",
.minimum = SAA7191_CHROMA_GAIN_MIN,
.maximum = SAA7191_CHROMA_GAIN_MAX,
.step = 1,
.default_value = SAA7191_CHROMA_GAIN_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_CHROMA_GAIN, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 5,
+ }, {
+ .id = SAA7191_CONTROL_VTRC,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "VTR Time Constant",
.minimum = SAA7191_VTRC_MIN,
.maximum = SAA7191_VTRC_MAX,
.step = 1,
.default_value = SAA7191_VTRC_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_VTRC, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 6,
+ }, {
+ .id = SAA7191_CONTROL_LUMA_DELAY,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Luminance Delay Compensation",
.minimum = SAA7191_LUMA_DELAY_MIN,
.maximum = SAA7191_LUMA_DELAY_MAX,
.step = 1,
.default_value = SAA7191_LUMA_DELAY_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_LUMA_DELAY, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 7,
+ }, {
+ .id = SAA7191_CONTROL_VNR,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Vertical Noise Reduction",
.minimum = SAA7191_VNR_MIN,
.maximum = SAA7191_VNR_MAX,
.step = 1,
.default_value = SAA7191_VNR_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_VNR, 0 },
}
};
}
}
-static int vino_get_saa7191_norm(unsigned int data_norm)
-{
- switch (data_norm) {
- case VINO_DATA_NORM_AUTO:
- return SAA7191_NORM_AUTO;
- case VINO_DATA_NORM_AUTO_EXT:
- return SAA7191_NORM_AUTO_EXT;
- case VINO_DATA_NORM_PAL:
- return SAA7191_NORM_PAL;
- case VINO_DATA_NORM_NTSC:
- return SAA7191_NORM_NTSC;
- case VINO_DATA_NORM_SECAM:
- return SAA7191_NORM_SECAM;
- default:
- printk(KERN_ERR "VINO: vino_get_saa7191_norm(): "
- "invalid norm!\n");
- return -1;
- }
-}
-
-static int vino_get_from_saa7191_norm(int saa7191_norm)
-{
- switch (saa7191_norm) {
- case SAA7191_NORM_PAL:
- return VINO_DATA_NORM_PAL;
- case SAA7191_NORM_NTSC:
- return VINO_DATA_NORM_NTSC;
- case SAA7191_NORM_SECAM:
- return VINO_DATA_NORM_SECAM;
- default:
- printk(KERN_ERR "VINO: vino_get_from_saa7191_norm(): "
- "invalid norm!\n");
- return VINO_DATA_NORM_NONE;
- }
-}
-
-static int vino_saa7191_set_norm(unsigned int *data_norm)
-{
- int saa7191_norm, new_data_norm;
- int err = 0;
-
- saa7191_norm = vino_get_saa7191_norm(*data_norm);
-
- err = i2c_decoder_command(DECODER_SAA7191_SET_NORM,
- &saa7191_norm);
- if (err)
- goto out;
-
- if ((*data_norm == VINO_DATA_NORM_AUTO)
- || (*data_norm == VINO_DATA_NORM_AUTO_EXT)) {
- struct saa7191_status status;
-
- err = i2c_decoder_command(DECODER_SAA7191_GET_STATUS,
- &status);
- if (err)
- goto out;
-
- new_data_norm =
- vino_get_from_saa7191_norm(status.norm);
- if (new_data_norm == VINO_DATA_NORM_NONE) {
- err = -EINVAL;
- goto out;
- }
-
- *data_norm = (unsigned int)new_data_norm;
- }
-
-out:
- return err;
-}
-
/* execute with input_lock locked */
static int vino_is_input_owner(struct vino_channel_settings *vcs)
{
vcs->data_norm = VINO_DATA_NORM_D1;
} else if (vino_drvdata->decoder.driver
&& (vino_drvdata->decoder.owner == VINO_NO_CHANNEL)) {
- int input, data_norm;
- int saa7191_input;
+ int input;
+ int data_norm;
+ v4l2_std_id norm;
+ struct v4l2_routing route = { 0, 0 };
i2c_use_client(vino_drvdata->decoder.driver);
input = VINO_INPUT_COMPOSITE;
- saa7191_input = vino_get_saa7191_input(input);
- ret = i2c_decoder_command(DECODER_SET_INPUT,
- &saa7191_input);
+ route.input = vino_get_saa7191_input(input);
+ ret = i2c_decoder_command(VIDIOC_INT_S_VIDEO_ROUTING, &route);
if (ret) {
ret = -EINVAL;
goto out;
/* Don't hold spinlocks while auto-detecting norm
* as it may take a while... */
- data_norm = VINO_DATA_NORM_AUTO_EXT;
-
- ret = vino_saa7191_set_norm(&data_norm);
- if ((ret == -EBUSY) || (ret == -EAGAIN)) {
- data_norm = VINO_DATA_NORM_PAL;
- ret = vino_saa7191_set_norm(&data_norm);
+ ret = i2c_decoder_command(VIDIOC_QUERYSTD, &norm);
+ if (!ret) {
+ for (data_norm = 0; data_norm < 3; data_norm++) {
+ if (vino_data_norms[data_norm].std & norm)
+ break;
+ }
+ if (data_norm == 3)
+ data_norm = VINO_DATA_NORM_PAL;
+ ret = i2c_decoder_command(VIDIOC_S_STD, &norm);
}
spin_lock_irqsave(&vino_drvdata->input_lock, flags);
if (vino_drvdata->decoder.owner == vcs->channel) {
int data_norm;
- int saa7191_input;
+ v4l2_std_id norm;
+ struct v4l2_routing route = { 0, 0 };
- saa7191_input = vino_get_saa7191_input(input);
- ret = i2c_decoder_command(DECODER_SET_INPUT,
- &saa7191_input);
+ route.input = vino_get_saa7191_input(input);
+ ret = i2c_decoder_command(VIDIOC_INT_S_VIDEO_ROUTING, &route);
if (ret) {
vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
ret = -EINVAL;
/* Don't hold spinlocks while auto-detecting norm
* as it may take a while... */
- data_norm = VINO_DATA_NORM_AUTO_EXT;
-
- ret = vino_saa7191_set_norm(&data_norm);
- if ((ret == -EBUSY) || (ret == -EAGAIN)) {
- data_norm = VINO_DATA_NORM_PAL;
- ret = vino_saa7191_set_norm(&data_norm);
+ ret = i2c_decoder_command(VIDIOC_QUERYSTD, &norm);
+ if (!ret) {
+ for (data_norm = 0; data_norm < 3; data_norm++) {
+ if (vino_data_norms[data_norm].std & norm)
+ break;
+ }
+ if (data_norm == 3)
+ data_norm = VINO_DATA_NORM_PAL;
+ ret = i2c_decoder_command(VIDIOC_S_STD, &norm);
}
spin_lock_irqsave(&vino_drvdata->input_lock, flags);
if (vcs2->input == VINO_INPUT_D1) {
vino_drvdata->camera.owner = vcs2->channel;
} else {
- i2c_release_client(vino_drvdata->
- camera.driver);
+ i2c_release_client(vino_drvdata->camera.driver);
vino_drvdata->camera.owner = VINO_NO_CHANNEL;
}
}
switch (vcs->input) {
case VINO_INPUT_D1:
/* only one "norm" supported */
- if ((data_norm != VINO_DATA_NORM_D1)
- && (data_norm != VINO_DATA_NORM_AUTO)
- && (data_norm != VINO_DATA_NORM_AUTO_EXT))
+ if (data_norm != VINO_DATA_NORM_D1)
return -EINVAL;
break;
case VINO_INPUT_COMPOSITE:
case VINO_INPUT_SVIDEO: {
+ v4l2_std_id norm;
+
if ((data_norm != VINO_DATA_NORM_PAL)
&& (data_norm != VINO_DATA_NORM_NTSC)
- && (data_norm != VINO_DATA_NORM_SECAM)
- && (data_norm != VINO_DATA_NORM_AUTO)
- && (data_norm != VINO_DATA_NORM_AUTO_EXT))
+ && (data_norm != VINO_DATA_NORM_SECAM))
return -EINVAL;
spin_unlock_irqrestore(&vino_drvdata->input_lock, *flags);
/* Don't hold spinlocks while setting norm
* as it may take a while... */
- err = vino_saa7191_set_norm(&data_norm);
+ norm = vino_data_norms[data_norm].std;
+ err = i2c_decoder_command(VIDIOC_S_STD, &norm);
spin_lock_irqsave(&vino_drvdata->input_lock, *flags);
return VINO_DATA_FMT_NONE;
}
-static int vino_enum_data_norm(struct vino_channel_settings *vcs, __u32 index)
-{
- int data_norm = VINO_DATA_NORM_NONE;
- unsigned long flags;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- switch(vcs->input) {
- case VINO_INPUT_COMPOSITE:
- case VINO_INPUT_SVIDEO:
- if (index == 0) {
- data_norm = VINO_DATA_NORM_PAL;
- } else if (index == 1) {
- data_norm = VINO_DATA_NORM_NTSC;
- } else if (index == 2) {
- data_norm = VINO_DATA_NORM_SECAM;
- }
- break;
- case VINO_INPUT_D1:
- if (index == 0) {
- data_norm = VINO_DATA_NORM_D1;
- }
- break;
- }
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- return data_norm;
-}
-
-static int vino_enum_input(struct vino_channel_settings *vcs, __u32 index)
+static int vino_int_enum_input(struct vino_channel_settings *vcs, __u32 index)
{
int input = VINO_INPUT_NONE;
unsigned long flags;
/* V4L2 ioctls */
-static void vino_v4l2_querycap(struct v4l2_capability *cap)
+static int vino_querycap(struct file *file, void *__fh,
+ struct v4l2_capability *cap)
{
memset(cap, 0, sizeof(struct v4l2_capability));
V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_STREAMING;
// V4L2_CAP_OVERLAY, V4L2_CAP_READWRITE
+ return 0;
}
-static int vino_v4l2_enuminput(struct vino_channel_settings *vcs,
+static int vino_enum_input(struct file *file, void *__fh,
struct v4l2_input *i)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
__u32 index = i->index;
int input;
dprintk("requested index = %d\n", index);
- input = vino_enum_input(vcs, index);
+ input = vino_int_enum_input(vcs, index);
if (input == VINO_INPUT_NONE)
return -EINVAL;
i->std = vino_inputs[input].std;
strcpy(i->name, vino_inputs[input].name);
- if ((input == VINO_INPUT_COMPOSITE)
- || (input == VINO_INPUT_SVIDEO)) {
- struct saa7191_status status;
- i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status);
- i->status |= status.signal ? 0 : V4L2_IN_ST_NO_SIGNAL;
- i->status |= status.color ? 0 : V4L2_IN_ST_NO_COLOR;
- }
-
+ if (input == VINO_INPUT_COMPOSITE || input == VINO_INPUT_SVIDEO)
+ i2c_decoder_command(VIDIOC_INT_G_INPUT_STATUS, &i->status);
return 0;
}
-static int vino_v4l2_g_input(struct vino_channel_settings *vcs,
+static int vino_g_input(struct file *file, void *__fh,
unsigned int *i)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
__u32 index;
int input;
unsigned long flags;
return 0;
}
-static int vino_v4l2_s_input(struct vino_channel_settings *vcs,
- unsigned int *i)
+static int vino_s_input(struct file *file, void *__fh,
+ unsigned int i)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
int input;
- dprintk("requested input = %d\n", *i);
+ dprintk("requested input = %d\n", i);
- input = vino_enum_input(vcs, *i);
+ input = vino_int_enum_input(vcs, i);
if (input == VINO_INPUT_NONE)
return -EINVAL;
return vino_set_input(vcs, input);
}
-static int vino_v4l2_enumstd(struct vino_channel_settings *vcs,
- struct v4l2_standard *s)
-{
- int index = s->index;
- int data_norm;
-
- data_norm = vino_enum_data_norm(vcs, index);
- dprintk("standard index = %d\n", index);
-
- if (data_norm == VINO_DATA_NORM_NONE)
- return -EINVAL;
-
- dprintk("standard name = %s\n",
- vino_data_norms[data_norm].description);
-
- memset(s, 0, sizeof(struct v4l2_standard));
- s->index = index;
-
- s->id = vino_data_norms[data_norm].std;
- s->frameperiod.numerator = 1;
- s->frameperiod.denominator =
- vino_data_norms[data_norm].fps_max;
- s->framelines =
- vino_data_norms[data_norm].framelines;
- strcpy(s->name,
- vino_data_norms[data_norm].description);
-
- return 0;
-}
-
-static int vino_v4l2_querystd(struct vino_channel_settings *vcs,
+static int vino_querystd(struct file *file, void *__fh,
v4l2_std_id *std)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
int err = 0;
break;
case VINO_INPUT_COMPOSITE:
case VINO_INPUT_SVIDEO: {
- struct saa7191_status status;
-
- i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status);
-
- if (status.signal) {
- if (status.signal_60hz) {
- *std = V4L2_STD_NTSC;
- } else {
- *std = V4L2_STD_PAL | V4L2_STD_SECAM;
- }
- } else {
- *std = vino_inputs[vcs->input].std;
- }
+ i2c_decoder_command(VIDIOC_QUERYSTD, std);
break;
}
default:
return err;
}
-static int vino_v4l2_g_std(struct vino_channel_settings *vcs,
+static int vino_g_std(struct file *file, void *__fh,
v4l2_std_id *std)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
spin_lock_irqsave(&vino_drvdata->input_lock, flags);
return 0;
}
-static int vino_v4l2_s_std(struct vino_channel_settings *vcs,
+static int vino_s_std(struct file *file, void *__fh,
v4l2_std_id *std)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
int ret = 0;
if (vcs->input == VINO_INPUT_D1)
goto out;
- if (((*std) & V4L2_STD_PAL)
- && ((*std) & V4L2_STD_NTSC)
- && ((*std) & V4L2_STD_SECAM)) {
- ret = vino_set_data_norm(vcs, VINO_DATA_NORM_AUTO_EXT,
- &flags);
- } else if ((*std) & V4L2_STD_PAL) {
+ if ((*std) & V4L2_STD_PAL) {
ret = vino_set_data_norm(vcs, VINO_DATA_NORM_PAL,
&flags);
} else if ((*std) & V4L2_STD_NTSC) {
return ret;
}
-static int vino_v4l2_enum_fmt(struct vino_channel_settings *vcs,
+static int vino_enum_fmt_vid_cap(struct file *file, void *__fh,
struct v4l2_fmtdesc *fd)
{
enum v4l2_buf_type type = fd->type;
int index = fd->index;
+
dprintk("format index = %d\n", index);
- switch (fd->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if ((fd->index < 0) ||
- (fd->index >= VINO_DATA_FMT_COUNT))
- return -EINVAL;
- dprintk("format name = %s\n",
- vino_data_formats[index].description);
-
- memset(fd, 0, sizeof(struct v4l2_fmtdesc));
- fd->index = index;
- fd->type = type;
- fd->pixelformat = vino_data_formats[index].pixelformat;
- strcpy(fd->description, vino_data_formats[index].description);
- break;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
+ if ((fd->index < 0) ||
+ (fd->index >= VINO_DATA_FMT_COUNT))
return -EINVAL;
- }
-
+ dprintk("format name = %s\n",
+ vino_data_formats[index].description);
+
+ memset(fd, 0, sizeof(struct v4l2_fmtdesc));
+ fd->index = index;
+ fd->type = type;
+ fd->pixelformat = vino_data_formats[index].pixelformat;
+ strcpy(fd->description, vino_data_formats[index].description);
return 0;
}
-static int vino_v4l2_try_fmt(struct vino_channel_settings *vcs,
+static int vino_try_fmt_vid_cap(struct file *file, void *__fh,
struct v4l2_format *f)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
struct vino_channel_settings tempvcs;
unsigned long flags;
+ struct v4l2_pix_format *pf = &f->fmt.pix;
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct v4l2_pix_format *pf = &f->fmt.pix;
-
- dprintk("requested: w = %d, h = %d\n",
- pf->width, pf->height);
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings));
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
+ dprintk("requested: w = %d, h = %d\n",
+ pf->width, pf->height);
- tempvcs.data_format = vino_find_data_format(pf->pixelformat);
- if (tempvcs.data_format == VINO_DATA_FMT_NONE) {
- tempvcs.data_format = VINO_DATA_FMT_GREY;
- pf->pixelformat =
- vino_data_formats[tempvcs.data_format].
- pixelformat;
- }
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
+ memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings));
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
- /* data format must be set before clipping/scaling */
- vino_set_scaling(&tempvcs, pf->width, pf->height);
+ tempvcs.data_format = vino_find_data_format(pf->pixelformat);
+ if (tempvcs.data_format == VINO_DATA_FMT_NONE) {
+ tempvcs.data_format = VINO_DATA_FMT_GREY;
+ pf->pixelformat =
+ vino_data_formats[tempvcs.data_format].
+ pixelformat;
+ }
- dprintk("data format = %s\n",
- vino_data_formats[tempvcs.data_format].description);
+ /* data format must be set before clipping/scaling */
+ vino_set_scaling(&tempvcs, pf->width, pf->height);
- pf->width = (tempvcs.clipping.right - tempvcs.clipping.left) /
- tempvcs.decimation;
- pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) /
- tempvcs.decimation;
+ dprintk("data format = %s\n",
+ vino_data_formats[tempvcs.data_format].description);
- pf->field = V4L2_FIELD_INTERLACED;
- pf->bytesperline = tempvcs.line_size;
- pf->sizeimage = tempvcs.line_size *
- (tempvcs.clipping.bottom - tempvcs.clipping.top) /
- tempvcs.decimation;
- pf->colorspace =
- vino_data_formats[tempvcs.data_format].colorspace;
+ pf->width = (tempvcs.clipping.right - tempvcs.clipping.left) /
+ tempvcs.decimation;
+ pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) /
+ tempvcs.decimation;
- pf->priv = 0;
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
- }
+ pf->field = V4L2_FIELD_INTERLACED;
+ pf->bytesperline = tempvcs.line_size;
+ pf->sizeimage = tempvcs.line_size *
+ (tempvcs.clipping.bottom - tempvcs.clipping.top) /
+ tempvcs.decimation;
+ pf->colorspace =
+ vino_data_formats[tempvcs.data_format].colorspace;
+ pf->priv = 0;
return 0;
}
-static int vino_v4l2_g_fmt(struct vino_channel_settings *vcs,
+static int vino_g_fmt_vid_cap(struct file *file, void *__fh,
struct v4l2_format *f)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
+ struct v4l2_pix_format *pf = &f->fmt.pix;
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct v4l2_pix_format *pf = &f->fmt.pix;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- pf->width = (vcs->clipping.right - vcs->clipping.left) /
- vcs->decimation;
- pf->height = (vcs->clipping.bottom - vcs->clipping.top) /
- vcs->decimation;
- pf->pixelformat =
- vino_data_formats[vcs->data_format].pixelformat;
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- pf->field = V4L2_FIELD_INTERLACED;
- pf->bytesperline = vcs->line_size;
- pf->sizeimage = vcs->line_size *
- (vcs->clipping.bottom - vcs->clipping.top) /
- vcs->decimation;
- pf->colorspace =
- vino_data_formats[vcs->data_format].colorspace;
+ pf->width = (vcs->clipping.right - vcs->clipping.left) /
+ vcs->decimation;
+ pf->height = (vcs->clipping.bottom - vcs->clipping.top) /
+ vcs->decimation;
+ pf->pixelformat =
+ vino_data_formats[vcs->data_format].pixelformat;
- pf->priv = 0;
+ pf->field = V4L2_FIELD_INTERLACED;
+ pf->bytesperline = vcs->line_size;
+ pf->sizeimage = vcs->line_size *
+ (vcs->clipping.bottom - vcs->clipping.top) /
+ vcs->decimation;
+ pf->colorspace =
+ vino_data_formats[vcs->data_format].colorspace;
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
- }
+ pf->priv = 0;
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
return 0;
}
-static int vino_v4l2_s_fmt(struct vino_channel_settings *vcs,
+static int vino_s_fmt_vid_cap(struct file *file, void *__fh,
struct v4l2_format *f)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
int data_format;
unsigned long flags;
+ struct v4l2_pix_format *pf = &f->fmt.pix;
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct v4l2_pix_format *pf = &f->fmt.pix;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- data_format = vino_find_data_format(pf->pixelformat);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- if (data_format == VINO_DATA_FMT_NONE) {
- vcs->data_format = VINO_DATA_FMT_GREY;
- pf->pixelformat =
- vino_data_formats[vcs->data_format].
- pixelformat;
- } else {
- vcs->data_format = data_format;
- }
+ data_format = vino_find_data_format(pf->pixelformat);
- /* data format must be set before clipping/scaling */
- vino_set_scaling(vcs, pf->width, pf->height);
+ if (data_format == VINO_DATA_FMT_NONE) {
+ vcs->data_format = VINO_DATA_FMT_GREY;
+ pf->pixelformat =
+ vino_data_formats[vcs->data_format].
+ pixelformat;
+ } else {
+ vcs->data_format = data_format;
+ }
- dprintk("data format = %s\n",
- vino_data_formats[vcs->data_format].description);
+ /* data format must be set before clipping/scaling */
+ vino_set_scaling(vcs, pf->width, pf->height);
- pf->width = vcs->clipping.right - vcs->clipping.left;
- pf->height = vcs->clipping.bottom - vcs->clipping.top;
+ dprintk("data format = %s\n",
+ vino_data_formats[vcs->data_format].description);
- pf->field = V4L2_FIELD_INTERLACED;
- pf->bytesperline = vcs->line_size;
- pf->sizeimage = vcs->line_size *
- (vcs->clipping.bottom - vcs->clipping.top) /
- vcs->decimation;
- pf->colorspace =
- vino_data_formats[vcs->data_format].colorspace;
+ pf->width = vcs->clipping.right - vcs->clipping.left;
+ pf->height = vcs->clipping.bottom - vcs->clipping.top;
- pf->priv = 0;
+ pf->field = V4L2_FIELD_INTERLACED;
+ pf->bytesperline = vcs->line_size;
+ pf->sizeimage = vcs->line_size *
+ (vcs->clipping.bottom - vcs->clipping.top) /
+ vcs->decimation;
+ pf->colorspace =
+ vino_data_formats[vcs->data_format].colorspace;
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
- }
+ pf->priv = 0;
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
return 0;
}
-static int vino_v4l2_cropcap(struct vino_channel_settings *vcs,
+static int vino_cropcap(struct file *file, void *__fh,
struct v4l2_cropcap *ccap)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
const struct vino_data_norm *norm;
unsigned long flags;
return 0;
}
-static int vino_v4l2_g_crop(struct vino_channel_settings *vcs,
+static int vino_g_crop(struct file *file, void *__fh,
struct v4l2_crop *c)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
switch (c->type) {
return 0;
}
-static int vino_v4l2_s_crop(struct vino_channel_settings *vcs,
+static int vino_s_crop(struct file *file, void *__fh,
struct v4l2_crop *c)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
switch (c->type) {
return 0;
}
-static int vino_v4l2_g_parm(struct vino_channel_settings *vcs,
+static int vino_g_parm(struct file *file, void *__fh,
struct v4l2_streamparm *sp)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
switch (sp->type) {
return 0;
}
-static int vino_v4l2_s_parm(struct vino_channel_settings *vcs,
+static int vino_s_parm(struct file *file, void *__fh,
struct v4l2_streamparm *sp)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
switch (sp->type) {
return 0;
}
-static int vino_v4l2_reqbufs(struct vino_channel_settings *vcs,
+static int vino_reqbufs(struct file *file, void *__fh,
struct v4l2_requestbuffers *rb)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
if (vcs->reading)
return -EBUSY;
fb->id, fb->size, fb->data_size, fb->offset);
}
-static int vino_v4l2_querybuf(struct vino_channel_settings *vcs,
+static int vino_querybuf(struct file *file, void *__fh,
struct v4l2_buffer *b)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
if (vcs->reading)
return -EBUSY;
return 0;
}
-static int vino_v4l2_qbuf(struct vino_channel_settings *vcs,
+static int vino_qbuf(struct file *file, void *__fh,
struct v4l2_buffer *b)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
if (vcs->reading)
return -EBUSY;
return 0;
}
-static int vino_v4l2_dqbuf(struct vino_channel_settings *vcs,
- struct v4l2_buffer *b,
- unsigned int nonblocking)
+static int vino_dqbuf(struct file *file, void *__fh,
+ struct v4l2_buffer *b)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
+ unsigned int nonblocking = file->f_flags & O_NONBLOCK;
if (vcs->reading)
return -EBUSY;
return 0;
}
-static int vino_v4l2_streamon(struct vino_channel_settings *vcs)
+static int vino_streamon(struct file *file, void *__fh,
+ enum v4l2_buf_type i)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned int incoming;
int ret;
if (vcs->reading)
return 0;
}
-static int vino_v4l2_streamoff(struct vino_channel_settings *vcs)
+static int vino_streamoff(struct file *file, void *__fh,
+ enum v4l2_buf_type i)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
if (vcs->reading)
return -EBUSY;
return 0;
}
-static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs,
+static int vino_queryctrl(struct file *file, void *__fh,
struct v4l2_queryctrl *queryctrl)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
int i;
int err = 0;
return err;
}
-static int vino_v4l2_g_ctrl(struct vino_channel_settings *vcs,
+static int vino_g_ctrl(struct file *file, void *__fh,
struct v4l2_control *control)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
int i;
int err = 0;
switch (vcs->input) {
case VINO_INPUT_D1: {
- struct indycam_control indycam_ctrl;
-
+ err = -EINVAL;
for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
- if (vino_indycam_v4l2_controls[i].id ==
- control->id) {
- goto found1;
+ if (vino_indycam_v4l2_controls[i].id == control->id) {
+ err = 0;
+ break;
}
}
- err = -EINVAL;
- goto out;
-
-found1:
- indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0];
-
- err = i2c_camera_command(DECODER_INDYCAM_GET_CONTROL,
- &indycam_ctrl);
- if (err) {
- err = -EINVAL;
+ if (err)
goto out;
- }
- control->value = indycam_ctrl.value;
+ err = i2c_camera_command(VIDIOC_G_CTRL, &control);
+ if (err)
+ err = -EINVAL;
break;
}
case VINO_INPUT_COMPOSITE:
case VINO_INPUT_SVIDEO: {
- struct saa7191_control saa7191_ctrl;
-
+ err = -EINVAL;
for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
- if (vino_saa7191_v4l2_controls[i].id ==
- control->id) {
- goto found2;
+ if (vino_saa7191_v4l2_controls[i].id == control->id) {
+ err = 0;
+ break;
}
}
- err = -EINVAL;
- goto out;
-
-found2:
- saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0];
-
- err = i2c_decoder_command(DECODER_SAA7191_GET_CONTROL,
- &saa7191_ctrl);
- if (err) {
- err = -EINVAL;
+ if (err)
goto out;
- }
- control->value = saa7191_ctrl.value;
+ err = i2c_decoder_command(VIDIOC_G_CTRL, &control);
+ if (err)
+ err = -EINVAL;
break;
}
default:
return err;
}
-static int vino_v4l2_s_ctrl(struct vino_channel_settings *vcs,
+static int vino_s_ctrl(struct file *file, void *__fh,
struct v4l2_control *control)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
int i;
int err = 0;
switch (vcs->input) {
case VINO_INPUT_D1: {
- struct indycam_control indycam_ctrl;
-
+ err = -EINVAL;
for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
- if (vino_indycam_v4l2_controls[i].id ==
- control->id) {
- if ((control->value >=
- vino_indycam_v4l2_controls[i].minimum)
- && (control->value <=
- vino_indycam_v4l2_controls[i].
- maximum)) {
- goto found1;
- } else {
- err = -ERANGE;
- goto out;
- }
+ if (vino_indycam_v4l2_controls[i].id == control->id) {
+ err = 0;
+ break;
}
}
-
- err = -EINVAL;
- goto out;
-
-found1:
- indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0];
- indycam_ctrl.value = control->value;
-
- err = i2c_camera_command(DECODER_INDYCAM_SET_CONTROL,
- &indycam_ctrl);
+ if (err)
+ goto out;
+ if (control->value < vino_indycam_v4l2_controls[i].minimum ||
+ control->value > vino_indycam_v4l2_controls[i].maximum) {
+ err = -ERANGE;
+ goto out;
+ }
+ err = i2c_camera_command(VIDIOC_S_CTRL, &control);
if (err)
err = -EINVAL;
break;
}
case VINO_INPUT_COMPOSITE:
case VINO_INPUT_SVIDEO: {
- struct saa7191_control saa7191_ctrl;
-
+ err = -EINVAL;
for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
- if (vino_saa7191_v4l2_controls[i].id ==
- control->id) {
- if ((control->value >=
- vino_saa7191_v4l2_controls[i].minimum)
- && (control->value <=
- vino_saa7191_v4l2_controls[i].
- maximum)) {
- goto found2;
- } else {
- err = -ERANGE;
- goto out;
- }
+ if (vino_saa7191_v4l2_controls[i].id == control->id) {
+ err = 0;
+ break;
}
}
- err = -EINVAL;
- goto out;
-
-found2:
- saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0];
- saa7191_ctrl.value = control->value;
+ if (err)
+ goto out;
+ if (control->value < vino_saa7191_v4l2_controls[i].minimum ||
+ control->value > vino_saa7191_v4l2_controls[i].maximum) {
+ err = -ERANGE;
+ goto out;
+ }
- err = i2c_decoder_command(DECODER_SAA7191_SET_CONTROL,
- &saa7191_ctrl);
+ err = i2c_decoder_command(VIDIOC_S_CTRL, &control);
if (err)
err = -EINVAL;
break;
ret = POLLIN | POLLRDNORM;
error:
-
return ret;
}
-static long vino_do_ioctl(struct file *file, unsigned int cmd, void *arg)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
-
-#ifdef VINO_DEBUG
- switch (_IOC_TYPE(cmd)) {
- case 'v':
- dprintk("ioctl(): V4L1 unsupported (0x%08x)\n", cmd);
- break;
- case 'V':
- dprintk("ioctl(): V4L2 %s (0x%08x)\n",
- v4l2_ioctl_names[_IOC_NR(cmd)], cmd);
- break;
- default:
- dprintk("ioctl(): unsupported command 0x%08x\n", cmd);
- }
-#endif
-
- switch (cmd) {
- /* V4L2 interface */
- case VIDIOC_QUERYCAP: {
- vino_v4l2_querycap(arg);
- break;
- }
- case VIDIOC_ENUMINPUT: {
- return vino_v4l2_enuminput(vcs, arg);
- }
- case VIDIOC_G_INPUT: {
- return vino_v4l2_g_input(vcs, arg);
- }
- case VIDIOC_S_INPUT: {
- return vino_v4l2_s_input(vcs, arg);
- }
- case VIDIOC_ENUMSTD: {
- return vino_v4l2_enumstd(vcs, arg);
- }
- case VIDIOC_QUERYSTD: {
- return vino_v4l2_querystd(vcs, arg);
- }
- case VIDIOC_G_STD: {
- return vino_v4l2_g_std(vcs, arg);
- }
- case VIDIOC_S_STD: {
- return vino_v4l2_s_std(vcs, arg);
- }
- case VIDIOC_ENUM_FMT: {
- return vino_v4l2_enum_fmt(vcs, arg);
- }
- case VIDIOC_TRY_FMT: {
- return vino_v4l2_try_fmt(vcs, arg);
- }
- case VIDIOC_G_FMT: {
- return vino_v4l2_g_fmt(vcs, arg);
- }
- case VIDIOC_S_FMT: {
- return vino_v4l2_s_fmt(vcs, arg);
- }
- case VIDIOC_CROPCAP: {
- return vino_v4l2_cropcap(vcs, arg);
- }
- case VIDIOC_G_CROP: {
- return vino_v4l2_g_crop(vcs, arg);
- }
- case VIDIOC_S_CROP: {
- return vino_v4l2_s_crop(vcs, arg);
- }
- case VIDIOC_G_PARM: {
- return vino_v4l2_g_parm(vcs, arg);
- }
- case VIDIOC_S_PARM: {
- return vino_v4l2_s_parm(vcs, arg);
- }
- case VIDIOC_REQBUFS: {
- return vino_v4l2_reqbufs(vcs, arg);
- }
- case VIDIOC_QUERYBUF: {
- return vino_v4l2_querybuf(vcs, arg);
- }
- case VIDIOC_QBUF: {
- return vino_v4l2_qbuf(vcs, arg);
- }
- case VIDIOC_DQBUF: {
- return vino_v4l2_dqbuf(vcs, arg, file->f_flags & O_NONBLOCK);
- }
- case VIDIOC_STREAMON: {
- return vino_v4l2_streamon(vcs);
- }
- case VIDIOC_STREAMOFF: {
- return vino_v4l2_streamoff(vcs);
- }
- case VIDIOC_QUERYCTRL: {
- return vino_v4l2_queryctrl(vcs, arg);
- }
- case VIDIOC_G_CTRL: {
- return vino_v4l2_g_ctrl(vcs, arg);
- }
- case VIDIOC_S_CTRL: {
- return vino_v4l2_s_ctrl(vcs, arg);
- }
- default:
- return -ENOIOCTLCMD;
- }
-
- return 0;
-}
-
static long vino_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
if (mutex_lock_interruptible(&vcs->mutex))
return -EINTR;
- ret = video_usercopy(file, cmd, arg, vino_do_ioctl);
+ ret = video_ioctl2(file, cmd, arg);
mutex_unlock(&vcs->mutex);
/* __initdata */
static int vino_init_stage;
+const struct v4l2_ioctl_ops vino_ioctl_ops = {
+ .vidioc_enum_fmt_vid_cap = vino_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vino_g_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vino_s_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vino_try_fmt_vid_cap,
+ .vidioc_querycap = vino_querycap,
+ .vidioc_enum_input = vino_enum_input,
+ .vidioc_g_input = vino_g_input,
+ .vidioc_s_input = vino_s_input,
+ .vidioc_g_std = vino_g_std,
+ .vidioc_s_std = vino_s_std,
+ .vidioc_querystd = vino_querystd,
+ .vidioc_cropcap = vino_cropcap,
+ .vidioc_s_crop = vino_s_crop,
+ .vidioc_g_crop = vino_g_crop,
+ .vidioc_s_parm = vino_s_parm,
+ .vidioc_g_parm = vino_g_parm,
+ .vidioc_reqbufs = vino_reqbufs,
+ .vidioc_querybuf = vino_querybuf,
+ .vidioc_qbuf = vino_qbuf,
+ .vidioc_dqbuf = vino_dqbuf,
+ .vidioc_streamon = vino_streamon,
+ .vidioc_streamoff = vino_streamoff,
+ .vidioc_queryctrl = vino_queryctrl,
+ .vidioc_g_ctrl = vino_g_ctrl,
+ .vidioc_s_ctrl = vino_s_ctrl,
+};
+
static const struct v4l2_file_operations vino_fops = {
.owner = THIS_MODULE,
.open = vino_open,
.release = vino_close,
- .ioctl = vino_ioctl,
+ .unlocked_ioctl = vino_ioctl,
.mmap = vino_mmap,
.poll = vino_poll,
};
-static struct video_device v4l_device_template = {
+static struct video_device vdev_template = {
.name = "NOT SET",
.fops = &vino_fops,
+ .ioctl_ops = &vino_ioctl_ops,
+ .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
.minor = -1,
};
static void vino_module_cleanup(int stage)
{
switch(stage) {
+ case 11:
+ video_unregister_device(vino_drvdata->b.vdev);
+ vino_drvdata->b.vdev = NULL;
case 10:
- video_unregister_device(vino_drvdata->b.v4l_device);
- vino_drvdata->b.v4l_device = NULL;
+ video_unregister_device(vino_drvdata->a.vdev);
+ vino_drvdata->a.vdev = NULL;
case 9:
- video_unregister_device(vino_drvdata->a.v4l_device);
- vino_drvdata->a.v4l_device = NULL;
- case 8:
vino_i2c_del_bus();
- case 7:
+ case 8:
free_irq(SGI_VINO_IRQ, NULL);
+ case 7:
+ if (vino_drvdata->b.vdev) {
+ video_device_release(vino_drvdata->b.vdev);
+ vino_drvdata->b.vdev = NULL;
+ }
case 6:
- if (vino_drvdata->b.v4l_device) {
- video_device_release(vino_drvdata->b.v4l_device);
- vino_drvdata->b.v4l_device = NULL;
+ if (vino_drvdata->a.vdev) {
+ video_device_release(vino_drvdata->a.vdev);
+ vino_drvdata->a.vdev = NULL;
}
case 5:
- if (vino_drvdata->a.v4l_device) {
- video_device_release(vino_drvdata->a.v4l_device);
- vino_drvdata->a.v4l_device = NULL;
- }
- case 4:
/* all entries in dma_cpu dummy table have the same address */
dma_unmap_single(NULL,
vino_drvdata->dummy_desc_table.dma_cpu[0],
(void *)vino_drvdata->
dummy_desc_table.dma_cpu,
vino_drvdata->dummy_desc_table.dma);
- case 3:
+ case 4:
free_page(vino_drvdata->dummy_page);
+ case 3:
+ v4l2_device_unregister(&vino_drvdata->v4l2_dev);
case 2:
kfree(vino_drvdata);
case 1:
static int vino_init(void)
{
dma_addr_t dma_dummy_address;
+ int err;
int i;
vino_drvdata = kzalloc(sizeof(struct vino_settings), GFP_KERNEL);
return -ENOMEM;
}
vino_init_stage++;
+ strlcpy(vino_drvdata->v4l2_dev.name, "vino",
+ sizeof(vino_drvdata->v4l2_dev.name));
+ err = v4l2_device_register(NULL, &vino_drvdata->v4l2_dev);
+ if (err)
+ return err;
+ vino_init_stage++;
/* create a dummy dma descriptor */
vino_drvdata->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA);
spin_lock_init(&vcs->fb_queue.queue_lock);
init_waitqueue_head(&vcs->fb_queue.frame_wait_queue);
- vcs->v4l_device = video_device_alloc();
- if (!vcs->v4l_device) {
+ vcs->vdev = video_device_alloc();
+ if (!vcs->vdev) {
vino_module_cleanup(vino_init_stage);
return -ENOMEM;
}
vino_init_stage++;
- memcpy(vcs->v4l_device, &v4l_device_template,
+ memcpy(vcs->vdev, &vdev_template,
sizeof(struct video_device));
- strcpy(vcs->v4l_device->name, name);
- vcs->v4l_device->release = video_device_release;
+ strcpy(vcs->vdev->name, name);
+ vcs->vdev->release = video_device_release;
+ vcs->vdev->v4l2_dev = &vino_drvdata->v4l2_dev;
- video_set_drvdata(vcs->v4l_device, vcs);
+ video_set_drvdata(vcs->vdev, vcs);
return 0;
}
spin_lock_init(&vino_drvdata->input_lock);
ret = vino_init_channel_settings(&vino_drvdata->a, VINO_CHANNEL_A,
- vino_v4l_device_name_a);
+ vino_vdev_name_a);
if (ret)
return ret;
ret = vino_init_channel_settings(&vino_drvdata->b, VINO_CHANNEL_B,
- vino_v4l_device_name_b);
+ vino_vdev_name_b);
if (ret)
return ret;
vino_module_cleanup(vino_init_stage);
return ret;
}
+ i2c_set_adapdata(&vino_i2c_adapter, &vino_drvdata->v4l2_dev);
vino_init_stage++;
- ret = video_register_device(vino_drvdata->a.v4l_device,
+ ret = video_register_device(vino_drvdata->a.vdev,
VFL_TYPE_GRABBER, -1);
if (ret < 0) {
printk(KERN_ERR "VINO channel A Video4Linux-device "
}
vino_init_stage++;
- ret = video_register_device(vino_drvdata->b.v4l_device,
+ ret = video_register_device(vino_drvdata->b.vdev,
VFL_TYPE_GRABBER, -1);
if (ret < 0) {
printk(KERN_ERR "VINO channel B Video4Linux-device "