static void gspca_set_default_mode(struct gspca_dev *gspca_dev)
{
- struct gspca_ctrl *ctrl;
int i;
i = gspca_dev->cam.nmodes - 1; /* take the highest mode */
gspca_dev->height = gspca_dev->cam.cam_mode[i].height;
gspca_dev->pixfmt = gspca_dev->cam.cam_mode[i].pixelformat;
- /* set the current control values to their default values
- * which may have changed in sd_init() */
/* does nothing if ctrl_handler == NULL */
v4l2_ctrl_handler_setup(gspca_dev->vdev.ctrl_handler);
- ctrl = gspca_dev->cam.ctrls;
- if (ctrl != NULL) {
- for (i = 0;
- i < gspca_dev->sd_desc->nctrls;
- i++, ctrl++)
- ctrl->val = ctrl->def;
- }
}
static int wxh_to_mode(struct gspca_dev *gspca_dev,
return 0;
}
-static int get_ctrl(struct gspca_dev *gspca_dev,
- int id)
-{
- const struct ctrl *ctrls;
- int i;
-
- for (i = 0, ctrls = gspca_dev->sd_desc->ctrls;
- i < gspca_dev->sd_desc->nctrls;
- i++, ctrls++) {
- if (gspca_dev->ctrl_dis & (1 << i))
- continue;
- if (id == ctrls->qctrl.id)
- return i;
- }
- return -1;
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *q_ctrl)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
- const struct ctrl *ctrls;
- struct gspca_ctrl *gspca_ctrl;
- int i, idx;
- u32 id;
-
- id = q_ctrl->id;
- if (id & V4L2_CTRL_FLAG_NEXT_CTRL) {
- id &= V4L2_CTRL_ID_MASK;
- id++;
- idx = -1;
- for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
- if (gspca_dev->ctrl_dis & (1 << i))
- continue;
- if (gspca_dev->sd_desc->ctrls[i].qctrl.id < id)
- continue;
- if (idx >= 0
- && gspca_dev->sd_desc->ctrls[i].qctrl.id
- > gspca_dev->sd_desc->ctrls[idx].qctrl.id)
- continue;
- idx = i;
- }
- } else {
- idx = get_ctrl(gspca_dev, id);
- }
- if (idx < 0)
- return -EINVAL;
- ctrls = &gspca_dev->sd_desc->ctrls[idx];
- memcpy(q_ctrl, &ctrls->qctrl, sizeof *q_ctrl);
- if (gspca_dev->cam.ctrls != NULL) {
- gspca_ctrl = &gspca_dev->cam.ctrls[idx];
- q_ctrl->default_value = gspca_ctrl->def;
- q_ctrl->minimum = gspca_ctrl->min;
- q_ctrl->maximum = gspca_ctrl->max;
- }
- if (gspca_dev->ctrl_inac & (1 << idx))
- q_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
- const struct ctrl *ctrls;
- struct gspca_ctrl *gspca_ctrl;
- int idx;
-
- idx = get_ctrl(gspca_dev, ctrl->id);
- if (idx < 0)
- return -EINVAL;
- if (gspca_dev->ctrl_inac & (1 << idx))
- return -EINVAL;
- ctrls = &gspca_dev->sd_desc->ctrls[idx];
- if (gspca_dev->cam.ctrls != NULL) {
- gspca_ctrl = &gspca_dev->cam.ctrls[idx];
- if (ctrl->value < gspca_ctrl->min
- || ctrl->value > gspca_ctrl->max)
- return -ERANGE;
- } else {
- gspca_ctrl = NULL;
- if (ctrl->value < ctrls->qctrl.minimum
- || ctrl->value > ctrls->qctrl.maximum)
- return -ERANGE;
- }
- PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value);
- gspca_dev->usb_err = 0;
- if (ctrls->set != NULL)
- return ctrls->set(gspca_dev, ctrl->value);
- if (gspca_ctrl != NULL) {
- gspca_ctrl->val = ctrl->value;
- if (ctrls->set_control != NULL
- && gspca_dev->streaming)
- ctrls->set_control(gspca_dev);
- }
- return gspca_dev->usb_err;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
- const struct ctrl *ctrls;
- int idx;
-
- idx = get_ctrl(gspca_dev, ctrl->id);
- if (idx < 0)
- return -EINVAL;
- ctrls = &gspca_dev->sd_desc->ctrls[idx];
-
- gspca_dev->usb_err = 0;
- if (ctrls->get != NULL)
- return ctrls->get(gspca_dev, &ctrl->value);
- if (gspca_dev->cam.ctrls != NULL)
- ctrl->value = gspca_dev->cam.ctrls[idx].val;
- return 0;
-}
-
-static int vidioc_querymenu(struct file *file, void *priv,
- struct v4l2_querymenu *qmenu)
-{
- struct gspca_dev *gspca_dev = video_drvdata(file);
-
- if (!gspca_dev->sd_desc->querymenu)
- return -ENOTTY;
- return gspca_dev->sd_desc->querymenu(gspca_dev, qmenu);
-}
-
static int vidioc_enum_input(struct file *file, void *priv,
struct v4l2_input *input)
{
.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
.vidioc_streamon = vidioc_streamon,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_querymenu = vidioc_querymenu,
.vidioc_enum_input = vidioc_enum_input,
.vidioc_g_input = vidioc_g_input,
.vidioc_s_input = vidioc_s_input,
.release = video_device_release_empty, /* We use v4l2_dev.release */
};
-/* initialize the controls */
-static void ctrls_init(struct gspca_dev *gspca_dev)
-{
- struct gspca_ctrl *ctrl;
- int i;
-
- for (i = 0, ctrl = gspca_dev->cam.ctrls;
- i < gspca_dev->sd_desc->nctrls;
- i++, ctrl++) {
- ctrl->def = gspca_dev->sd_desc->ctrls[i].qctrl.default_value;
- ctrl->val = ctrl->def;
- ctrl->min = gspca_dev->sd_desc->ctrls[i].qctrl.minimum;
- ctrl->max = gspca_dev->sd_desc->ctrls[i].qctrl.maximum;
- }
-}
-
/*
* probe and create a new gspca device
*
ret = sd_desc->config(gspca_dev, id);
if (ret < 0)
goto out;
- if (gspca_dev->cam.ctrls != NULL)
- ctrls_init(gspca_dev);
ret = sd_desc->init(gspca_dev);
if (ret < 0)
goto out;
int nrates;
};
-/* control definition */
-struct gspca_ctrl {
- s16 val; /* current value */
- s16 def; /* default value */
- s16 min, max; /* minimum and maximum values */
-};
-
/* device information - set at probe time */
struct cam {
const struct v4l2_pix_format *cam_mode; /* size nmodes */
const struct framerates *mode_framerates; /* must have size nmodes,
* just like cam_mode */
- struct gspca_ctrl *ctrls; /* control table - size nctrls */
- /* may be NULL */
u32 bulk_size; /* buffer size when image transfer by bulk */
u32 input_flags; /* value for ENUM_INPUT status flags */
u8 nmodes; /* size of cam_mode */
struct v4l2_dbg_chip_ident *);
typedef void (*cam_streamparm_op) (struct gspca_dev *,
struct v4l2_streamparm *);
-typedef int (*cam_qmnu_op) (struct gspca_dev *,
- struct v4l2_querymenu *);
typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev,
u8 *data,
int len);
u8 *data,
int len);
-struct ctrl {
- struct v4l2_queryctrl qctrl;
- int (*set)(struct gspca_dev *, __s32);
- int (*get)(struct gspca_dev *, __s32 *);
- cam_v_op set_control;
-};
-
/* subdriver description */
struct sd_desc {
/* information */
const char *name; /* sub-driver name */
-/* controls */
- const struct ctrl *ctrls; /* static control definition */
- int nctrls;
/* mandatory operations */
cam_cf_op config; /* called on probe */
cam_op init; /* called on probe and resume */
cam_v_op dq_callback; /* called when a frame has been dequeued */
cam_get_jpg_op get_jcomp;
cam_set_jpg_op set_jcomp;
- cam_qmnu_op querymenu;
cam_streamparm_op get_streamparm;
cam_streamparm_op set_streamparm;
#ifdef CONFIG_VIDEO_ADV_DEBUG
struct cam cam; /* device information */
const struct sd_desc *sd_desc; /* subdriver description */
- unsigned ctrl_dis; /* disabled controls (bit map) */
- unsigned ctrl_inac; /* inactive controls (bit map) */
struct v4l2_ctrl_handler ctrl_handler;
/* autogain and exposure or gain control cluster, these are global as