aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/konica.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca/konica.c')
-rw-r--r--drivers/media/video/gspca/konica.c289
1 files changed, 71 insertions, 218 deletions
diff --git a/drivers/media/video/gspca/konica.c b/drivers/media/video/gspca/konica.c
index f0c0d74dfe92..bbf91e07e38b 100644
--- a/drivers/media/video/gspca/konica.c
+++ b/drivers/media/video/gspca/konica.c
@@ -50,107 +50,8 @@ struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
struct urb *last_data_urb;
u8 snapshot_pressed;
- u8 brightness;
- u8 contrast;
- u8 saturation;
- u8 whitebal;
- u8 sharpness;
};
-/* V4L2 controls supported by the driver */
-static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setwhitebal(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getwhitebal(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
-
-static const struct ctrl sd_ctrls[] = {
-#define SD_BRIGHTNESS 0
- {
- {
- .id = V4L2_CID_BRIGHTNESS,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Brightness",
- .minimum = 0,
- .maximum = 9,
- .step = 1,
-#define BRIGHTNESS_DEFAULT 4
- .default_value = BRIGHTNESS_DEFAULT,
- .flags = 0,
- },
- .set = sd_setbrightness,
- .get = sd_getbrightness,
- },
-#define SD_CONTRAST 1
- {
- {
- .id = V4L2_CID_CONTRAST,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Contrast",
- .minimum = 0,
- .maximum = 9,
- .step = 4,
-#define CONTRAST_DEFAULT 10
- .default_value = CONTRAST_DEFAULT,
- .flags = 0,
- },
- .set = sd_setcontrast,
- .get = sd_getcontrast,
- },
-#define SD_SATURATION 2
- {
- {
- .id = V4L2_CID_SATURATION,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Saturation",
- .minimum = 0,
- .maximum = 9,
- .step = 1,
-#define SATURATION_DEFAULT 4
- .default_value = SATURATION_DEFAULT,
- .flags = 0,
- },
- .set = sd_setsaturation,
- .get = sd_getsaturation,
- },
-#define SD_WHITEBAL 3
- {
- {
- .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "White Balance",
- .minimum = 0,
- .maximum = 33,
- .step = 1,
-#define WHITEBAL_DEFAULT 25
- .default_value = WHITEBAL_DEFAULT,
- .flags = 0,
- },
- .set = sd_setwhitebal,
- .get = sd_getwhitebal,
- },
-#define SD_SHARPNESS 4
- {
- {
- .id = V4L2_CID_SHARPNESS,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Sharpness",
- .minimum = 0,
- .maximum = 9,
- .step = 1,
-#define SHARPNESS_DEFAULT 4
- .default_value = SHARPNESS_DEFAULT,
- .flags = 0,
- },
- .set = sd_setsharpness,
- .get = sd_getsharpness,
- },
-};
/* .priv is what goes to register 8 for this mode, known working values:
0x00 -> 176x144, cropped
@@ -202,7 +103,8 @@ static void reg_w(struct gspca_dev *gspca_dev, u16 value, u16 index)
0,
1000);
if (ret < 0) {
- pr_err("reg_w err %d\n", ret);
+ pr_err("reg_w err writing %02x to %02x: %d\n",
+ value, index, ret);
gspca_dev->usb_err = ret;
}
}
@@ -223,7 +125,7 @@ static void reg_r(struct gspca_dev *gspca_dev, u16 value, u16 index)
2,
1000);
if (ret < 0) {
- pr_err("reg_w err %d\n", ret);
+ pr_err("reg_r err %d\n", ret);
gspca_dev->usb_err = ret;
}
}
@@ -242,34 +144,33 @@ static void konica_stream_off(struct gspca_dev *gspca_dev)
static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
{
- struct sd *sd = (struct sd *) gspca_dev;
-
gspca_dev->cam.cam_mode = vga_mode;
gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
gspca_dev->cam.no_urb_create = 1;
- sd->brightness = BRIGHTNESS_DEFAULT;
- sd->contrast = CONTRAST_DEFAULT;
- sd->saturation = SATURATION_DEFAULT;
- sd->whitebal = WHITEBAL_DEFAULT;
- sd->sharpness = SHARPNESS_DEFAULT;
-
return 0;
}
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
- /* HDG not sure if these 2 reads are needed */
- reg_r(gspca_dev, 0, 0x10);
- PDEBUG(D_PROBE, "Reg 0x10 reads: %02x %02x",
- gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
- reg_r(gspca_dev, 0, 0x10);
- PDEBUG(D_PROBE, "Reg 0x10 reads: %02x %02x",
- gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
+ int i;
+
+ /*
+ * The konica needs a freaking large time to "boot" (approx 6.5 sec.),
+ * and does not want to be bothered while doing so :|
+ * Register 0x10 counts from 1 - 3, with 3 being "ready"
+ */
+ msleep(6000);
+ for (i = 0; i < 20; i++) {
+ reg_r(gspca_dev, 0, 0x10);
+ if (gspca_dev->usb_buf[0] == 3)
+ break;
+ msleep(100);
+ }
reg_w(gspca_dev, 0, 0x0d);
- return 0;
+ return gspca_dev->usb_err;
}
static int sd_start(struct gspca_dev *gspca_dev)
@@ -289,12 +190,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
- reg_w(gspca_dev, sd->brightness, BRIGHTNESS_REG);
- reg_w(gspca_dev, sd->whitebal, WHITEBAL_REG);
- reg_w(gspca_dev, sd->contrast, CONTRAST_REG);
- reg_w(gspca_dev, sd->saturation, SATURATION_REG);
- reg_w(gspca_dev, sd->sharpness, SHARPNESS_REG);
-
n = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
reg_w(gspca_dev, n, 0x08);
@@ -479,125 +374,82 @@ resubmit:
pr_err("usb_submit_urb(status_urb) ret %d\n", st);
}
-static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->brightness = val;
- if (gspca_dev->streaming) {
- konica_stream_off(gspca_dev);
- reg_w(gspca_dev, sd->brightness, BRIGHTNESS_REG);
- konica_stream_on(gspca_dev);
- }
-
- return 0;
-}
-
-static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->brightness;
+ struct gspca_dev *gspca_dev =
+ container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
- return 0;
-}
+ gspca_dev->usb_err = 0;
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
+ if (!gspca_dev->streaming)
+ return 0;
- sd->contrast = val;
- if (gspca_dev->streaming) {
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
konica_stream_off(gspca_dev);
- reg_w(gspca_dev, sd->contrast, CONTRAST_REG);
+ reg_w(gspca_dev, ctrl->val, BRIGHTNESS_REG);
konica_stream_on(gspca_dev);
- }
-
- return 0;
-}
-
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->contrast;
-
- return 0;
-}
-
-static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->saturation = val;
- if (gspca_dev->streaming) {
+ break;
+ case V4L2_CID_CONTRAST:
konica_stream_off(gspca_dev);
- reg_w(gspca_dev, sd->saturation, SATURATION_REG);
+ reg_w(gspca_dev, ctrl->val, CONTRAST_REG);
konica_stream_on(gspca_dev);
- }
- return 0;
-}
-
-static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->saturation;
-
- return 0;
-}
-
-static int sd_setwhitebal(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->whitebal = val;
- if (gspca_dev->streaming) {
+ break;
+ case V4L2_CID_SATURATION:
konica_stream_off(gspca_dev);
- reg_w(gspca_dev, sd->whitebal, WHITEBAL_REG);
+ reg_w(gspca_dev, ctrl->val, SATURATION_REG);
konica_stream_on(gspca_dev);
- }
- return 0;
-}
-
-static int sd_getwhitebal(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->whitebal;
-
- return 0;
-}
-
-static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->sharpness = val;
- if (gspca_dev->streaming) {
+ break;
+ case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
konica_stream_off(gspca_dev);
- reg_w(gspca_dev, sd->sharpness, SHARPNESS_REG);
+ reg_w(gspca_dev, ctrl->val, WHITEBAL_REG);
konica_stream_on(gspca_dev);
+ break;
+ case V4L2_CID_SHARPNESS:
+ konica_stream_off(gspca_dev);
+ reg_w(gspca_dev, ctrl->val, SHARPNESS_REG);
+ konica_stream_on(gspca_dev);
+ break;
}
- return 0;
+ return gspca_dev->usb_err;
}
-static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->sharpness;
+static const struct v4l2_ctrl_ops sd_ctrl_ops = {
+ .s_ctrl = sd_s_ctrl,
+};
+static int sd_init_controls(struct gspca_dev *gspca_dev)
+{
+ struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
+
+ gspca_dev->vdev.ctrl_handler = hdl;
+ v4l2_ctrl_handler_init(hdl, 5);
+ v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
+ V4L2_CID_BRIGHTNESS, 0, 9, 1, 4);
+ /* Needs to be verified */
+ v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
+ V4L2_CID_CONTRAST, 0, 9, 1, 4);
+ v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
+ V4L2_CID_SATURATION, 0, 9, 1, 4);
+ v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
+ V4L2_CID_WHITE_BALANCE_TEMPERATURE,
+ 0, 33, 1, 25);
+ v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
+ V4L2_CID_SHARPNESS, 0, 9, 1, 4);
+
+ if (hdl->error) {
+ pr_err("Could not initialize controls\n");
+ return hdl->error;
+ }
return 0;
}
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
- .ctrls = sd_ctrls,
- .nctrls = ARRAY_SIZE(sd_ctrls),
.config = sd_config,
.init = sd_init,
+ .init_controls = sd_init_controls,
.start = sd_start,
.stopN = sd_stopN,
#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
@@ -628,6 +480,7 @@ static struct usb_driver sd_driver = {
#ifdef CONFIG_PM
.suspend = gspca_suspend,
.resume = gspca_resume,
+ .reset_resume = gspca_resume,
#endif
};