aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pxa_camera.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2009-03-13 05:08:20 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:43:21 -0400
commit09e231b35173313cd92e27532e5028f2042dcee4 (patch)
tree3ecda063aa52f954d2f797921bdce131d7f1cc28 /drivers/media/video/pxa_camera.c
parent1cd3c0fa927084549005fc22e54d99684b314f14 (diff)
V4L/DVB (11024): soc-camera: separate S_FMT and S_CROP operations
As host and camera drivers become more complex, differences between S_FMT and S_CROP functionality grow, this patch separates them. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/pxa_camera.c')
-rw-r--r--drivers/media/video/pxa_camera.c67
1 files changed, 49 insertions, 18 deletions
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 2cc203cfbe6c..c522616ef38f 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -1150,8 +1150,43 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
1150 return formats; 1150 return formats;
1151} 1151}
1152 1152
1153static int pxa_camera_set_crop(struct soc_camera_device *icd,
1154 struct v4l2_rect *rect)
1155{
1156 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1157 struct pxa_camera_dev *pcdev = ici->priv;
1158 struct soc_camera_sense sense = {
1159 .master_clock = pcdev->mclk,
1160 .pixel_clock_max = pcdev->ciclk / 4,
1161 };
1162 int ret;
1163
1164 /* If PCLK is used to latch data from the sensor, check sense */
1165 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
1166 icd->sense = &sense;
1167
1168 ret = icd->ops->set_crop(icd, rect);
1169
1170 icd->sense = NULL;
1171
1172 if (ret < 0) {
1173 dev_warn(&ici->dev, "Failed to crop to %ux%u@%u:%u\n",
1174 rect->width, rect->height, rect->left, rect->top);
1175 } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
1176 if (sense.pixel_clock > sense.pixel_clock_max) {
1177 dev_err(&ici->dev,
1178 "pixel clock %lu set by the camera too high!",
1179 sense.pixel_clock);
1180 return -EIO;
1181 }
1182 recalculate_fifo_timeout(pcdev, sense.pixel_clock);
1183 }
1184
1185 return ret;
1186}
1187
1153static int pxa_camera_set_fmt(struct soc_camera_device *icd, 1188static int pxa_camera_set_fmt(struct soc_camera_device *icd,
1154 __u32 pixfmt, struct v4l2_rect *rect) 1189 struct v4l2_format *f)
1155{ 1190{
1156 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1191 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1157 struct pxa_camera_dev *pcdev = ici->priv; 1192 struct pxa_camera_dev *pcdev = ici->priv;
@@ -1161,35 +1196,30 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
1161 .master_clock = pcdev->mclk, 1196 .master_clock = pcdev->mclk,
1162 .pixel_clock_max = pcdev->ciclk / 4, 1197 .pixel_clock_max = pcdev->ciclk / 4,
1163 }; 1198 };
1199 struct v4l2_pix_format *pix = &f->fmt.pix;
1200 struct v4l2_format cam_f = *f;
1164 int ret; 1201 int ret;
1165 1202
1166 if (pixfmt) { 1203 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1167 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 1204 if (!xlate) {
1168 if (!xlate) { 1205 dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat);
1169 dev_warn(&ici->dev, "Format %x not found\n", pixfmt); 1206 return -EINVAL;
1170 return -EINVAL;
1171 }
1172
1173 cam_fmt = xlate->cam_fmt;
1174 } 1207 }
1175 1208
1209 cam_fmt = xlate->cam_fmt;
1210
1176 /* If PCLK is used to latch data from the sensor, check sense */ 1211 /* If PCLK is used to latch data from the sensor, check sense */
1177 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) 1212 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
1178 icd->sense = &sense; 1213 icd->sense = &sense;
1179 1214
1180 switch (pixfmt) { 1215 cam_f.fmt.pix.pixelformat = cam_fmt->fourcc;
1181 case 0: /* Only geometry change */ 1216 ret = icd->ops->set_fmt(icd, &cam_f);
1182 ret = icd->ops->set_fmt(icd, pixfmt, rect);
1183 break;
1184 default:
1185 ret = icd->ops->set_fmt(icd, cam_fmt->fourcc, rect);
1186 }
1187 1217
1188 icd->sense = NULL; 1218 icd->sense = NULL;
1189 1219
1190 if (ret < 0) { 1220 if (ret < 0) {
1191 dev_warn(&ici->dev, "Failed to configure for format %x\n", 1221 dev_warn(&ici->dev, "Failed to configure for format %x\n",
1192 pixfmt); 1222 pix->pixelformat);
1193 } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { 1223 } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
1194 if (sense.pixel_clock > sense.pixel_clock_max) { 1224 if (sense.pixel_clock > sense.pixel_clock_max) {
1195 dev_err(&ici->dev, 1225 dev_err(&ici->dev,
@@ -1200,7 +1230,7 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
1200 recalculate_fifo_timeout(pcdev, sense.pixel_clock); 1230 recalculate_fifo_timeout(pcdev, sense.pixel_clock);
1201 } 1231 }
1202 1232
1203 if (pixfmt && !ret) { 1233 if (!ret) {
1204 icd->buswidth = xlate->buswidth; 1234 icd->buswidth = xlate->buswidth;
1205 icd->current_fmt = xlate->host_fmt; 1235 icd->current_fmt = xlate->host_fmt;
1206 } 1236 }
@@ -1364,6 +1394,7 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
1364 .remove = pxa_camera_remove_device, 1394 .remove = pxa_camera_remove_device,
1365 .suspend = pxa_camera_suspend, 1395 .suspend = pxa_camera_suspend,
1366 .resume = pxa_camera_resume, 1396 .resume = pxa_camera_resume,
1397 .set_crop = pxa_camera_set_crop,
1367 .get_formats = pxa_camera_get_formats, 1398 .get_formats = pxa_camera_get_formats,
1368 .set_fmt = pxa_camera_set_fmt, 1399 .set_fmt = pxa_camera_set_fmt,
1369 .try_fmt = pxa_camera_try_fmt, 1400 .try_fmt = pxa_camera_try_fmt,