Skip to content

Commit

Permalink
V4L/DVB (12536): soc-camera: remove .gain and .exposure struct soc_ca…
Browse files Browse the repository at this point in the history
…mera_device members

This makes the soc-camera interface for V4L2 subdevices thinner yet. Handle
gain and exposure internally in each driver just like all other controls.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Guennadi Liakhovetski authored and Mauro Carvalho Chehab committed Sep 19, 2009
1 parent a4c56fd commit 96c7539
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 82 deletions.
43 changes: 28 additions & 15 deletions drivers/media/video/mt9m001.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ struct mt9m001 {
struct v4l2_rect rect; /* Sensor window */
__u32 fourcc;
int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
unsigned int gain;
unsigned int exposure;
unsigned char autoexposure;
};

Expand Down Expand Up @@ -129,8 +131,8 @@ static int mt9m001_init(struct i2c_client *client)
dev_dbg(&client->dev, "%s\n", __func__);

/*
* We don't know, whether platform provides reset,
* issue a soft reset too
* We don't know, whether platform provides reset, issue a soft reset
* too. This returns all registers to their default values.
*/
ret = reg_write(client, MT9M001_RESET, 1);
if (!ret)
Expand Down Expand Up @@ -200,6 +202,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
struct soc_camera_device *icd = client->dev.platform_data;
int ret;
const u16 hblank = 9, vblank = 25;
unsigned int total_h;

if (mt9m001->fourcc == V4L2_PIX_FMT_SBGGR8 ||
mt9m001->fourcc == V4L2_PIX_FMT_SBGGR16)
Expand All @@ -219,6 +222,8 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
soc_camera_limit_side(&rect.top, &rect.height,
MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT);

total_h = rect.height + icd->y_skip_top + vblank;

/* Blanking and start values - default... */
ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank);
if (!ret)
Expand All @@ -236,15 +241,13 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
ret = reg_write(client, MT9M001_WINDOW_HEIGHT,
rect.height + icd->y_skip_top - 1);
if (!ret && mt9m001->autoexposure) {
ret = reg_write(client, MT9M001_SHUTTER_WIDTH,
rect.height + icd->y_skip_top + vblank);
ret = reg_write(client, MT9M001_SHUTTER_WIDTH, total_h);
if (!ret) {
const struct v4l2_queryctrl *qctrl =
soc_camera_find_qctrl(icd->ops,
V4L2_CID_EXPOSURE);
icd->exposure = (524 + (rect.height + icd->y_skip_top +
vblank - 1) *
(qctrl->maximum - qctrl->minimum)) /
mt9m001->exposure = (524 + (total_h - 1) *
(qctrl->maximum - qctrl->minimum)) /
1048 + qctrl->minimum;
}
}
Expand Down Expand Up @@ -457,6 +460,12 @@ static int mt9m001_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
case V4L2_CID_EXPOSURE_AUTO:
ctrl->value = mt9m001->autoexposure;
break;
case V4L2_CID_GAIN:
ctrl->value = mt9m001->gain;
break;
case V4L2_CID_EXPOSURE:
ctrl->value = mt9m001->exposure;
break;
}
return 0;
}
Expand Down Expand Up @@ -518,7 +527,7 @@ static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
}

/* Success */
icd->gain = ctrl->value;
mt9m001->gain = ctrl->value;
break;
case V4L2_CID_EXPOSURE:
/* mt9m001 has maximum == default */
Expand All @@ -535,21 +544,21 @@ static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
shutter);
if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0)
return -EIO;
icd->exposure = ctrl->value;
mt9m001->exposure = ctrl->value;
mt9m001->autoexposure = 0;
}
break;
case V4L2_CID_EXPOSURE_AUTO:
if (ctrl->value) {
const u16 vblank = 25;
unsigned int total_h = mt9m001->rect.height +
icd->y_skip_top + vblank;
if (reg_write(client, MT9M001_SHUTTER_WIDTH,
mt9m001->rect.height +
icd->y_skip_top + vblank) < 0)
total_h) < 0)
return -EIO;
qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
icd->exposure = (524 + (mt9m001->rect.height +
icd->y_skip_top + vblank - 1) *
(qctrl->maximum - qctrl->minimum)) /
mt9m001->exposure = (524 + (total_h - 1) *
(qctrl->maximum - qctrl->minimum)) /
1048 + qctrl->minimum;
mt9m001->autoexposure = 1;
} else
Expand Down Expand Up @@ -629,6 +638,10 @@ static int mt9m001_video_probe(struct soc_camera_device *icd,
if (ret < 0)
dev_err(&client->dev, "Failed to initialise the camera\n");

/* mt9m001_init() has reset the chip, returning registers to defaults */
mt9m001->gain = 64;
mt9m001->exposure = 255;

return ret;
}

Expand Down Expand Up @@ -701,7 +714,7 @@ static int mt9m001_probe(struct i2c_client *client,

/* Second stage probe - when a capture adapter is there */
icd->ops = &mt9m001_ops;
icd->y_skip_top = 1;
icd->y_skip_top = 0;

mt9m001->rect.left = MT9M001_COLUMN_SKIP;
mt9m001->rect.top = MT9M001_ROW_SKIP;
Expand Down
29 changes: 21 additions & 8 deletions drivers/media/video/mt9m111.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ struct mt9m111 {
enum mt9m111_context context;
struct v4l2_rect rect;
u32 pixfmt;
unsigned int gain;
unsigned char autoexposure;
unsigned char datawidth;
unsigned int powered:1;
Expand Down Expand Up @@ -513,7 +514,8 @@ static int mt9m111_set_pixfmt(struct i2c_client *client, u32 pixfmt)
ret = mt9m111_setfmt_yuv(client);
break;
default:
dev_err(&client->dev, "Pixel format not handled : %x\n", pixfmt);
dev_err(&client->dev, "Pixel format not handled : %x\n",
pixfmt);
ret = -EINVAL;
}

Expand All @@ -536,9 +538,9 @@ static int mt9m111_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
};
int ret;

dev_dbg(&client->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n",
__func__, pix->pixelformat, rect.left, rect.top, rect.width,
rect.height);
dev_dbg(&client->dev,
"%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", __func__,
pix->pixelformat, rect.left, rect.top, rect.width, rect.height);

ret = mt9m111_make_rect(client, &rect);
if (!ret)
Expand Down Expand Up @@ -672,8 +674,10 @@ static const struct v4l2_queryctrl mt9m111_controls[] = {
};

static int mt9m111_resume(struct soc_camera_device *icd);
static int mt9m111_suspend(struct soc_camera_device *icd, pm_message_t state);

static struct soc_camera_ops mt9m111_ops = {
.suspend = mt9m111_suspend,
.resume = mt9m111_resume,
.query_bus_param = mt9m111_query_bus_param,
.set_bus_param = mt9m111_set_bus_param,
Expand Down Expand Up @@ -714,13 +718,13 @@ static int mt9m111_get_global_gain(struct i2c_client *client)

static int mt9m111_set_global_gain(struct i2c_client *client, int gain)
{
struct soc_camera_device *icd = client->dev.platform_data;
struct mt9m111 *mt9m111 = to_mt9m111(client);
u16 val;

if (gain > 63 * 2 * 2)
return -EINVAL;

icd->gain = gain;
mt9m111->gain = gain;
if ((gain >= 64 * 2) && (gain < 63 * 2 * 2))
val = (1 << 10) | (1 << 9) | (gain / 4);
else if ((gain >= 64) && (gain < 64 * 2))
Expand Down Expand Up @@ -844,17 +848,26 @@ static int mt9m111_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
return ret;
}

static int mt9m111_suspend(struct soc_camera_device *icd, pm_message_t state)
{
struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
struct mt9m111 *mt9m111 = to_mt9m111(client);

mt9m111->gain = mt9m111_get_global_gain(client);

return 0;
}

static int mt9m111_restore_state(struct i2c_client *client)
{
struct mt9m111 *mt9m111 = to_mt9m111(client);
struct soc_camera_device *icd = client->dev.platform_data;

mt9m111_set_context(client, mt9m111->context);
mt9m111_set_pixfmt(client, mt9m111->pixfmt);
mt9m111_setup_rect(client, &mt9m111->rect);
mt9m111_set_flip(client, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS);
mt9m111_set_flip(client, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS);
mt9m111_set_global_gain(client, icd->gain);
mt9m111_set_global_gain(client, mt9m111->gain);
mt9m111_set_autoexposure(client, mt9m111->autoexposure);
mt9m111_set_autowhitebalance(client, mt9m111->autowhitebalance);
return 0;
Expand Down
37 changes: 24 additions & 13 deletions drivers/media/video/mt9t031.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ struct mt9t031 {
int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */
u16 xskip;
u16 yskip;
unsigned int gain;
unsigned int exposure;
unsigned char autoexposure;
};

Expand Down Expand Up @@ -301,16 +303,15 @@ static int mt9t031_set_params(struct soc_camera_device *icd,
ret = reg_write(client, MT9T031_WINDOW_HEIGHT,
rect->height + icd->y_skip_top - 1);
if (ret >= 0 && mt9t031->autoexposure) {
ret = set_shutter(client,
rect->height + icd->y_skip_top + vblank);
unsigned int total_h = rect->height + icd->y_skip_top + vblank;
ret = set_shutter(client, total_h);
if (ret >= 0) {
const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
const struct v4l2_queryctrl *qctrl =
soc_camera_find_qctrl(icd->ops,
V4L2_CID_EXPOSURE);
icd->exposure = (shutter_max / 2 + (rect->height +
icd->y_skip_top + vblank - 1) *
(qctrl->maximum - qctrl->minimum)) /
mt9t031->exposure = (shutter_max / 2 + (total_h - 1) *
(qctrl->maximum - qctrl->minimum)) /
shutter_max + qctrl->minimum;
}
}
Expand Down Expand Up @@ -553,6 +554,12 @@ static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
case V4L2_CID_EXPOSURE_AUTO:
ctrl->value = mt9t031->autoexposure;
break;
case V4L2_CID_GAIN:
ctrl->value = mt9t031->gain;
break;
case V4L2_CID_EXPOSURE:
ctrl->value = mt9t031->exposure;
break;
}
return 0;
}
Expand Down Expand Up @@ -624,7 +631,7 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
}

/* Success */
icd->gain = ctrl->value;
mt9t031->gain = ctrl->value;
break;
case V4L2_CID_EXPOSURE:
/* mt9t031 has maximum == default */
Expand All @@ -641,22 +648,22 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
old, shutter);
if (set_shutter(client, shutter) < 0)
return -EIO;
icd->exposure = ctrl->value;
mt9t031->exposure = ctrl->value;
mt9t031->autoexposure = 0;
}
break;
case V4L2_CID_EXPOSURE_AUTO:
if (ctrl->value) {
const u16 vblank = MT9T031_VERTICAL_BLANK;
const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
if (set_shutter(client, mt9t031->rect.height +
icd->y_skip_top + vblank) < 0)
unsigned int total_h = mt9t031->rect.height +
icd->y_skip_top + vblank;

if (set_shutter(client, total_h) < 0)
return -EIO;
qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
icd->exposure = (shutter_max / 2 +
(mt9t031->rect.height +
icd->y_skip_top + vblank - 1) *
(qctrl->maximum - qctrl->minimum)) /
mt9t031->exposure = (shutter_max / 2 + (total_h - 1) *
(qctrl->maximum - qctrl->minimum)) /
shutter_max + qctrl->minimum;
mt9t031->autoexposure = 1;
} else
Expand Down Expand Up @@ -700,6 +707,10 @@ static int mt9t031_video_probe(struct i2c_client *client)
if (ret < 0)
dev_err(&client->dev, "Failed to initialise the camera\n");

/* mt9t031_idle() has reset the chip to default. */
mt9t031->exposure = 255;
mt9t031->gain = 64;

return ret;
}

Expand Down
Loading

0 comments on commit 96c7539

Please sign in to comment.