提交 71e84ea7 编写于 作者: J Jean-François Moine 提交者: Mauro Carvalho Chehab

[media] gspca - stv06xx/st6422: Use the new video control mechanism

Signed-off-by: NJean-François Moine <moinejf@free.fr>
Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
上级 7e5f9059
...@@ -28,6 +28,20 @@ ...@@ -28,6 +28,20 @@
#include "stv06xx_st6422.h" #include "stv06xx_st6422.h"
/* controls */
enum e_ctrl {
BRIGHTNESS,
CONTRAST,
GAIN,
EXPOSURE,
NCTRLS /* number of controls */
};
/* sensor settings */
struct st6422_settings {
struct gspca_ctrl ctrls[NCTRLS];
};
static struct v4l2_pix_format st6422_mode[] = { static struct v4l2_pix_format st6422_mode[] = {
/* Note we actually get 124 lines of data, of which we skip the 4st /* Note we actually get 124 lines of data, of which we skip the 4st
4 as they are garbage */ 4 as they are garbage */
...@@ -57,9 +71,14 @@ static struct v4l2_pix_format st6422_mode[] = { ...@@ -57,9 +71,14 @@ static struct v4l2_pix_format st6422_mode[] = {
}, },
}; };
static const struct ctrl st6422_ctrl[] = { /* V4L2 controls supported by the driver */
#define BRIGHTNESS_IDX 0 static void st6422_set_brightness(struct gspca_dev *gspca_dev);
{ static void st6422_set_contrast(struct gspca_dev *gspca_dev);
static void st6422_set_gain(struct gspca_dev *gspca_dev);
static void st6422_set_exposure(struct gspca_dev *gspca_dev);
static const struct ctrl st6422_ctrl[NCTRLS] = {
[BRIGHTNESS] = {
{ {
.id = V4L2_CID_BRIGHTNESS, .id = V4L2_CID_BRIGHTNESS,
.type = V4L2_CTRL_TYPE_INTEGER, .type = V4L2_CTRL_TYPE_INTEGER,
...@@ -69,11 +88,9 @@ static const struct ctrl st6422_ctrl[] = { ...@@ -69,11 +88,9 @@ static const struct ctrl st6422_ctrl[] = {
.step = 1, .step = 1,
.default_value = 3 .default_value = 3
}, },
.set = st6422_set_brightness, .set_control = st6422_set_brightness
.get = st6422_get_brightness
}, },
#define CONTRAST_IDX 1 [CONTRAST] = {
{
{ {
.id = V4L2_CID_CONTRAST, .id = V4L2_CID_CONTRAST,
.type = V4L2_CTRL_TYPE_INTEGER, .type = V4L2_CTRL_TYPE_INTEGER,
...@@ -83,11 +100,9 @@ static const struct ctrl st6422_ctrl[] = { ...@@ -83,11 +100,9 @@ static const struct ctrl st6422_ctrl[] = {
.step = 1, .step = 1,
.default_value = 11 .default_value = 11
}, },
.set = st6422_set_contrast, .set_control = st6422_set_contrast
.get = st6422_get_contrast
}, },
#define GAIN_IDX 2 [GAIN] = {
{
{ {
.id = V4L2_CID_GAIN, .id = V4L2_CID_GAIN,
.type = V4L2_CTRL_TYPE_INTEGER, .type = V4L2_CTRL_TYPE_INTEGER,
...@@ -97,49 +112,43 @@ static const struct ctrl st6422_ctrl[] = { ...@@ -97,49 +112,43 @@ static const struct ctrl st6422_ctrl[] = {
.step = 1, .step = 1,
.default_value = 64 .default_value = 64
}, },
.set = st6422_set_gain, .set_control = st6422_set_gain
.get = st6422_get_gain
}, },
#define EXPOSURE_IDX 3 [EXPOSURE] = {
{
{ {
.id = V4L2_CID_EXPOSURE, .id = V4L2_CID_EXPOSURE,
.type = V4L2_CTRL_TYPE_INTEGER, .type = V4L2_CTRL_TYPE_INTEGER,
.name = "Exposure", .name = "Exposure",
.minimum = 0, .minimum = 0,
.maximum = 1023, #define EXPOSURE_MAX 1023
.maximum = EXPOSURE_MAX,
.step = 1, .step = 1,
.default_value = 256 .default_value = 256
}, },
.set = st6422_set_exposure, .set_control = st6422_set_exposure
.get = st6422_get_exposure
}, },
}; };
static int st6422_probe(struct sd *sd) static int st6422_probe(struct sd *sd)
{ {
int i; struct st6422_settings *sensor_settings;
s32 *sensor_settings;
if (sd->bridge != BRIDGE_ST6422) if (sd->bridge != BRIDGE_ST6422)
return -ENODEV; return -ENODEV;
info("st6422 sensor detected"); info("st6422 sensor detected");
sensor_settings = kmalloc(ARRAY_SIZE(st6422_ctrl) * sizeof(s32), sensor_settings = kmalloc(sizeof *sensor_settings, GFP_KERNEL);
GFP_KERNEL);
if (!sensor_settings) if (!sensor_settings)
return -ENOMEM; return -ENOMEM;
sd->gspca_dev.cam.cam_mode = st6422_mode; sd->gspca_dev.cam.cam_mode = st6422_mode;
sd->gspca_dev.cam.nmodes = ARRAY_SIZE(st6422_mode); sd->gspca_dev.cam.nmodes = ARRAY_SIZE(st6422_mode);
sd->gspca_dev.cam.ctrls = sensor_settings->ctrls;
sd->desc.ctrls = st6422_ctrl; sd->desc.ctrls = st6422_ctrl;
sd->desc.nctrls = ARRAY_SIZE(st6422_ctrl); sd->desc.nctrls = ARRAY_SIZE(st6422_ctrl);
sd->sensor_priv = sensor_settings; sd->sensor_priv = sensor_settings;
for (i = 0; i < sd->desc.nctrls; i++)
sensor_settings[i] = st6422_ctrl[i].qctrl.default_value;
return 0; return 0;
} }
...@@ -234,77 +243,92 @@ static void st6422_disconnect(struct sd *sd) ...@@ -234,77 +243,92 @@ static void st6422_disconnect(struct sd *sd)
kfree(sd->sensor_priv); kfree(sd->sensor_priv);
} }
static int st6422_start(struct sd *sd) static int setbrightness(struct sd *sd)
{
struct st6422_settings *sensor_settings = sd->sensor_priv;
/* val goes from 0 -> 31 */
return stv06xx_write_bridge(sd, 0x1432,
sensor_settings->ctrls[BRIGHTNESS].val);
}
static int setcontrast(struct sd *sd)
{
struct st6422_settings *sensor_settings = sd->sensor_priv;
/* Val goes from 0 -> 15 */
return stv06xx_write_bridge(sd, 0x143a,
sensor_settings->ctrls[CONTRAST].val | 0xf0);
}
static int setgain(struct sd *sd)
{ {
struct st6422_settings *sensor_settings = sd->sensor_priv;
u8 gain;
int err; int err;
struct cam *cam = &sd->gspca_dev.cam;
s32 *sensor_settings = sd->sensor_priv;
if (cam->cam_mode[sd->gspca_dev.curr_mode].priv) gain = sensor_settings->ctrls[GAIN].val;
err = stv06xx_write_bridge(sd, 0x1505, 0x0f);
else
err = stv06xx_write_bridge(sd, 0x1505, 0x02);
if (err < 0)
return err;
err = st6422_set_brightness(&sd->gspca_dev, /* Set red, green, blue, gain */
sensor_settings[BRIGHTNESS_IDX]); err = stv06xx_write_bridge(sd, 0x0509, gain);
if (err < 0) if (err < 0)
return err; return err;
err = st6422_set_contrast(&sd->gspca_dev, err = stv06xx_write_bridge(sd, 0x050a, gain);
sensor_settings[CONTRAST_IDX]);
if (err < 0) if (err < 0)
return err; return err;
err = st6422_set_exposure(&sd->gspca_dev, err = stv06xx_write_bridge(sd, 0x050b, gain);
sensor_settings[EXPOSURE_IDX]);
if (err < 0) if (err < 0)
return err; return err;
err = st6422_set_gain(&sd->gspca_dev, /* 2 mystery writes */
sensor_settings[GAIN_IDX]); err = stv06xx_write_bridge(sd, 0x050c, 0x2a);
if (err < 0) if (err < 0)
return err; return err;
PDEBUG(D_STREAM, "Starting stream"); return stv06xx_write_bridge(sd, 0x050d, 0x01);
return 0;
} }
static int st6422_stop(struct sd *sd) static int setexposure(struct sd *sd)
{ {
PDEBUG(D_STREAM, "Halting stream"); struct st6422_settings *sensor_settings = sd->sensor_priv;
u16 expo;
return 0; int err;
}
static int st6422_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
s32 *sensor_settings = sd->sensor_priv;
*val = sensor_settings[BRIGHTNESS_IDX];
PDEBUG(D_V4L2, "Read brightness %d", *val); expo = sensor_settings->ctrls[EXPOSURE].val;
err = stv06xx_write_bridge(sd, 0x143d, expo & 0xff);
if (err < 0)
return err;
return 0; return stv06xx_write_bridge(sd, 0x143e, expo >> 8);
} }
static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val) static int st6422_start(struct sd *sd)
{ {
int err; int err;
struct sd *sd = (struct sd *) gspca_dev; struct cam *cam = &sd->gspca_dev.cam;
s32 *sensor_settings = sd->sensor_priv;
sensor_settings[BRIGHTNESS_IDX] = val; if (cam->cam_mode[sd->gspca_dev.curr_mode].priv)
err = stv06xx_write_bridge(sd, 0x1505, 0x0f);
else
err = stv06xx_write_bridge(sd, 0x1505, 0x02);
if (err < 0)
return err;
if (!gspca_dev->streaming) err = setbrightness(sd);
return 0; if (err < 0)
return err;
/* val goes from 0 -> 31 */ err = setcontrast(sd);
PDEBUG(D_V4L2, "Set brightness to %d", val); if (err < 0)
err = stv06xx_write_bridge(sd, 0x1432, val); return err;
err = setexposure(sd);
if (err < 0)
return err;
err = setgain(sd);
if (err < 0) if (err < 0)
return err; return err;
...@@ -313,125 +337,65 @@ static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val) ...@@ -313,125 +337,65 @@ static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
return (err < 0) ? err : 0; return (err < 0) ? err : 0;
} }
static int st6422_get_contrast(struct gspca_dev *gspca_dev, __s32 *val) static int st6422_stop(struct sd *sd)
{ {
struct sd *sd = (struct sd *) gspca_dev; PDEBUG(D_STREAM, "Halting stream");
s32 *sensor_settings = sd->sensor_priv;
*val = sensor_settings[CONTRAST_IDX];
PDEBUG(D_V4L2, "Read contrast %d", *val);
return 0; return 0;
} }
static int st6422_set_contrast(struct gspca_dev *gspca_dev, __s32 val) static void st6422_set_brightness(struct gspca_dev *gspca_dev)
{ {
int err; int err;
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
s32 *sensor_settings = sd->sensor_priv;
sensor_settings[CONTRAST_IDX] = val;
if (!gspca_dev->streaming) err = setbrightness(sd);
return 0;
/* Val goes from 0 -> 15 */
PDEBUG(D_V4L2, "Set contrast to %d\n", val);
err = stv06xx_write_bridge(sd, 0x143a, 0xf0 | val);
if (err < 0)
return err;
/* commit settings */ /* commit settings */
err = stv06xx_write_bridge(sd, 0x143f, 0x01); if (err >= 0)
return (err < 0) ? err : 0; err = stv06xx_write_bridge(sd, 0x143f, 0x01);
}
static int st6422_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
s32 *sensor_settings = sd->sensor_priv;
*val = sensor_settings[GAIN_IDX];
PDEBUG(D_V4L2, "Read gain %d", *val); gspca_dev->usb_err = err;
return 0;
} }
static int st6422_set_gain(struct gspca_dev *gspca_dev, __s32 val) static void st6422_set_contrast(struct gspca_dev *gspca_dev)
{ {
int err; int err;
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
s32 *sensor_settings = sd->sensor_priv;
sensor_settings[GAIN_IDX] = val; err = setcontrast(sd);
if (!gspca_dev->streaming)
return 0;
PDEBUG(D_V4L2, "Set gain to %d", val);
/* Set red, green, blue, gain */
err = stv06xx_write_bridge(sd, 0x0509, val);
if (err < 0)
return err;
err = stv06xx_write_bridge(sd, 0x050a, val);
if (err < 0)
return err;
err = stv06xx_write_bridge(sd, 0x050b, val);
if (err < 0)
return err;
/* 2 mystery writes */
err = stv06xx_write_bridge(sd, 0x050c, 0x2a);
if (err < 0)
return err;
err = stv06xx_write_bridge(sd, 0x050d, 0x01);
if (err < 0)
return err;
/* commit settings */ /* commit settings */
err = stv06xx_write_bridge(sd, 0x143f, 0x01); if (err >= 0)
return (err < 0) ? err : 0; err = stv06xx_write_bridge(sd, 0x143f, 0x01);
gspca_dev->usb_err = err;
} }
static int st6422_get_exposure(struct gspca_dev *gspca_dev, __s32 *val) static void st6422_set_gain(struct gspca_dev *gspca_dev)
{ {
int err;
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
s32 *sensor_settings = sd->sensor_priv;
*val = sensor_settings[EXPOSURE_IDX]; err = setgain(sd);
PDEBUG(D_V4L2, "Read exposure %d", *val); /* commit settings */
if (err >= 0)
err = stv06xx_write_bridge(sd, 0x143f, 0x01);
return 0; gspca_dev->usb_err = err;
} }
static int st6422_set_exposure(struct gspca_dev *gspca_dev, __s32 val) static void st6422_set_exposure(struct gspca_dev *gspca_dev)
{ {
int err; int err;
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
s32 *sensor_settings = sd->sensor_priv;
sensor_settings[EXPOSURE_IDX] = val;
if (!gspca_dev->streaming)
return 0;
PDEBUG(D_V4L2, "Set exposure to %d\n", val);
err = stv06xx_write_bridge(sd, 0x143d, val & 0xff);
if (err < 0)
return err;
err = stv06xx_write_bridge(sd, 0x143e, val >> 8); err = setexposure(sd);
if (err < 0)
return err;
/* commit settings */ /* commit settings */
err = stv06xx_write_bridge(sd, 0x143f, 0x01); if (err >= 0)
return (err < 0) ? err : 0; err = stv06xx_write_bridge(sd, 0x143f, 0x01);
gspca_dev->usb_err = err;
} }
...@@ -37,16 +37,6 @@ static int st6422_init(struct sd *sd); ...@@ -37,16 +37,6 @@ static int st6422_init(struct sd *sd);
static int st6422_stop(struct sd *sd); static int st6422_stop(struct sd *sd);
static void st6422_disconnect(struct sd *sd); static void st6422_disconnect(struct sd *sd);
/* V4L2 controls supported by the driver */
static int st6422_get_brightness(struct gspca_dev *gspca_dev, __s32 *val);
static int st6422_set_brightness(struct gspca_dev *gspca_dev, __s32 val);
static int st6422_get_contrast(struct gspca_dev *gspca_dev, __s32 *val);
static int st6422_set_contrast(struct gspca_dev *gspca_dev, __s32 val);
static int st6422_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
static int st6422_set_gain(struct gspca_dev *gspca_dev, __s32 val);
static int st6422_get_exposure(struct gspca_dev *gspca_dev, __s32 *val);
static int st6422_set_exposure(struct gspca_dev *gspca_dev, __s32 val);
const struct stv06xx_sensor stv06xx_sensor_st6422 = { const struct stv06xx_sensor stv06xx_sensor_st6422 = {
.name = "ST6422", .name = "ST6422",
/* No known way to lower framerate in case of less bandwidth */ /* No known way to lower framerate in case of less bandwidth */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册