diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2011-09-07 04:20:33 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-11-03 16:28:47 -0400 |
commit | 25e965ad2727527216724142d1fbeeb0e9dcf7a8 (patch) | |
tree | d0afa4e2f2931d75353628e6b1957da2f62182d7 /drivers/media/video | |
parent | 7b9d8c3c4cfa0dc21f630c17c5f20e524dab487c (diff) |
[media] rj54n1cb0c: convert to the control framework
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
[g.liakhovetski@gmx.de: simplified pointer arithmetic]
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/rj54n1cb0c.c | 141 |
1 files changed, 38 insertions, 103 deletions
diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c index c30221104c6..9a871537d23 100644 --- a/drivers/media/video/rj54n1cb0c.c +++ b/drivers/media/video/rj54n1cb0c.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <media/soc_mediabus.h> | 18 | #include <media/soc_mediabus.h> |
19 | #include <media/v4l2-subdev.h> | 19 | #include <media/v4l2-subdev.h> |
20 | #include <media/v4l2-chip-ident.h> | 20 | #include <media/v4l2-chip-ident.h> |
21 | #include <media/v4l2-ctrls.h> | ||
21 | 22 | ||
22 | #define RJ54N1_DEV_CODE 0x0400 | 23 | #define RJ54N1_DEV_CODE 0x0400 |
23 | #define RJ54N1_DEV_CODE2 0x0401 | 24 | #define RJ54N1_DEV_CODE2 0x0401 |
@@ -148,6 +149,7 @@ struct rj54n1_clock_div { | |||
148 | 149 | ||
149 | struct rj54n1 { | 150 | struct rj54n1 { |
150 | struct v4l2_subdev subdev; | 151 | struct v4l2_subdev subdev; |
152 | struct v4l2_ctrl_handler hdl; | ||
151 | struct rj54n1_clock_div clk_div; | 153 | struct rj54n1_clock_div clk_div; |
152 | const struct rj54n1_datafmt *fmt; | 154 | const struct rj54n1_datafmt *fmt; |
153 | struct v4l2_rect rect; /* Sensor window */ | 155 | struct v4l2_rect rect; /* Sensor window */ |
@@ -1177,132 +1179,51 @@ static int rj54n1_s_register(struct v4l2_subdev *sd, | |||
1177 | } | 1179 | } |
1178 | #endif | 1180 | #endif |
1179 | 1181 | ||
1180 | static const struct v4l2_queryctrl rj54n1_controls[] = { | 1182 | static int rj54n1_s_ctrl(struct v4l2_ctrl *ctrl) |
1181 | { | ||
1182 | .id = V4L2_CID_VFLIP, | ||
1183 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
1184 | .name = "Flip Vertically", | ||
1185 | .minimum = 0, | ||
1186 | .maximum = 1, | ||
1187 | .step = 1, | ||
1188 | .default_value = 0, | ||
1189 | }, { | ||
1190 | .id = V4L2_CID_HFLIP, | ||
1191 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
1192 | .name = "Flip Horizontally", | ||
1193 | .minimum = 0, | ||
1194 | .maximum = 1, | ||
1195 | .step = 1, | ||
1196 | .default_value = 0, | ||
1197 | }, { | ||
1198 | .id = V4L2_CID_GAIN, | ||
1199 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
1200 | .name = "Gain", | ||
1201 | .minimum = 0, | ||
1202 | .maximum = 127, | ||
1203 | .step = 1, | ||
1204 | .default_value = 66, | ||
1205 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
1206 | }, { | ||
1207 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | ||
1208 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
1209 | .name = "Auto white balance", | ||
1210 | .minimum = 0, | ||
1211 | .maximum = 1, | ||
1212 | .step = 1, | ||
1213 | .default_value = 1, | ||
1214 | }, | ||
1215 | }; | ||
1216 | |||
1217 | static struct soc_camera_ops rj54n1_ops = { | ||
1218 | .controls = rj54n1_controls, | ||
1219 | .num_controls = ARRAY_SIZE(rj54n1_controls), | ||
1220 | }; | ||
1221 | |||
1222 | static int rj54n1_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | ||
1223 | { | 1183 | { |
1184 | struct rj54n1 *rj54n1 = container_of(ctrl->handler, struct rj54n1, hdl); | ||
1185 | struct v4l2_subdev *sd = &rj54n1->subdev; | ||
1224 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 1186 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
1225 | struct rj54n1 *rj54n1 = to_rj54n1(client); | ||
1226 | int data; | 1187 | int data; |
1227 | 1188 | ||
1228 | switch (ctrl->id) { | 1189 | switch (ctrl->id) { |
1229 | case V4L2_CID_VFLIP: | 1190 | case V4L2_CID_VFLIP: |
1230 | data = reg_read(client, RJ54N1_MIRROR_STILL_MODE); | 1191 | if (ctrl->val) |
1231 | if (data < 0) | ||
1232 | return -EIO; | ||
1233 | ctrl->value = !(data & 1); | ||
1234 | break; | ||
1235 | case V4L2_CID_HFLIP: | ||
1236 | data = reg_read(client, RJ54N1_MIRROR_STILL_MODE); | ||
1237 | if (data < 0) | ||
1238 | return -EIO; | ||
1239 | ctrl->value = !(data & 2); | ||
1240 | break; | ||
1241 | case V4L2_CID_GAIN: | ||
1242 | data = reg_read(client, RJ54N1_Y_GAIN); | ||
1243 | if (data < 0) | ||
1244 | return -EIO; | ||
1245 | |||
1246 | ctrl->value = data / 2; | ||
1247 | break; | ||
1248 | case V4L2_CID_AUTO_WHITE_BALANCE: | ||
1249 | ctrl->value = rj54n1->auto_wb; | ||
1250 | break; | ||
1251 | } | ||
1252 | |||
1253 | return 0; | ||
1254 | } | ||
1255 | |||
1256 | static int rj54n1_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | ||
1257 | { | ||
1258 | int data; | ||
1259 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1260 | struct rj54n1 *rj54n1 = to_rj54n1(client); | ||
1261 | const struct v4l2_queryctrl *qctrl; | ||
1262 | |||
1263 | qctrl = soc_camera_find_qctrl(&rj54n1_ops, ctrl->id); | ||
1264 | if (!qctrl) | ||
1265 | return -EINVAL; | ||
1266 | |||
1267 | switch (ctrl->id) { | ||
1268 | case V4L2_CID_VFLIP: | ||
1269 | if (ctrl->value) | ||
1270 | data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 1); | 1192 | data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 1); |
1271 | else | 1193 | else |
1272 | data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 1, 1); | 1194 | data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 1, 1); |
1273 | if (data < 0) | 1195 | if (data < 0) |
1274 | return -EIO; | 1196 | return -EIO; |
1275 | break; | 1197 | return 0; |
1276 | case V4L2_CID_HFLIP: | 1198 | case V4L2_CID_HFLIP: |
1277 | if (ctrl->value) | 1199 | if (ctrl->val) |
1278 | data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 2); | 1200 | data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 2); |
1279 | else | 1201 | else |
1280 | data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 2, 2); | 1202 | data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 2, 2); |
1281 | if (data < 0) | 1203 | if (data < 0) |
1282 | return -EIO; | 1204 | return -EIO; |
1283 | break; | 1205 | return 0; |
1284 | case V4L2_CID_GAIN: | 1206 | case V4L2_CID_GAIN: |
1285 | if (ctrl->value > qctrl->maximum || | 1207 | if (reg_write(client, RJ54N1_Y_GAIN, ctrl->val * 2) < 0) |
1286 | ctrl->value < qctrl->minimum) | ||
1287 | return -EINVAL; | ||
1288 | else if (reg_write(client, RJ54N1_Y_GAIN, ctrl->value * 2) < 0) | ||
1289 | return -EIO; | 1208 | return -EIO; |
1290 | break; | 1209 | return 0; |
1291 | case V4L2_CID_AUTO_WHITE_BALANCE: | 1210 | case V4L2_CID_AUTO_WHITE_BALANCE: |
1292 | /* Auto WB area - whole image */ | 1211 | /* Auto WB area - whole image */ |
1293 | if (reg_set(client, RJ54N1_WB_SEL_WEIGHT_I, ctrl->value << 7, | 1212 | if (reg_set(client, RJ54N1_WB_SEL_WEIGHT_I, ctrl->val << 7, |
1294 | 0x80) < 0) | 1213 | 0x80) < 0) |
1295 | return -EIO; | 1214 | return -EIO; |
1296 | rj54n1->auto_wb = ctrl->value; | 1215 | rj54n1->auto_wb = ctrl->val; |
1297 | break; | 1216 | return 0; |
1298 | } | 1217 | } |
1299 | 1218 | ||
1300 | return 0; | 1219 | return -EINVAL; |
1301 | } | 1220 | } |
1302 | 1221 | ||
1222 | static const struct v4l2_ctrl_ops rj54n1_ctrl_ops = { | ||
1223 | .s_ctrl = rj54n1_s_ctrl, | ||
1224 | }; | ||
1225 | |||
1303 | static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = { | 1226 | static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = { |
1304 | .g_ctrl = rj54n1_g_ctrl, | ||
1305 | .s_ctrl = rj54n1_s_ctrl, | ||
1306 | .g_chip_ident = rj54n1_g_chip_ident, | 1227 | .g_chip_ident = rj54n1_g_chip_ident, |
1307 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1228 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1308 | .g_register = rj54n1_g_register, | 1229 | .g_register = rj54n1_g_register, |
@@ -1432,8 +1353,22 @@ static int rj54n1_probe(struct i2c_client *client, | |||
1432 | return -ENOMEM; | 1353 | return -ENOMEM; |
1433 | 1354 | ||
1434 | v4l2_i2c_subdev_init(&rj54n1->subdev, client, &rj54n1_subdev_ops); | 1355 | v4l2_i2c_subdev_init(&rj54n1->subdev, client, &rj54n1_subdev_ops); |
1356 | v4l2_ctrl_handler_init(&rj54n1->hdl, 4); | ||
1357 | v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops, | ||
1358 | V4L2_CID_VFLIP, 0, 1, 1, 0); | ||
1359 | v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops, | ||
1360 | V4L2_CID_HFLIP, 0, 1, 1, 0); | ||
1361 | v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops, | ||
1362 | V4L2_CID_GAIN, 0, 127, 1, 66); | ||
1363 | v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops, | ||
1364 | V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1); | ||
1365 | rj54n1->subdev.ctrl_handler = &rj54n1->hdl; | ||
1366 | if (rj54n1->hdl.error) { | ||
1367 | int err = rj54n1->hdl.error; | ||
1435 | 1368 | ||
1436 | icd->ops = &rj54n1_ops; | 1369 | kfree(rj54n1); |
1370 | return err; | ||
1371 | } | ||
1437 | 1372 | ||
1438 | rj54n1->clk_div = clk_div; | 1373 | rj54n1->clk_div = clk_div; |
1439 | rj54n1->rect.left = RJ54N1_COLUMN_SKIP; | 1374 | rj54n1->rect.left = RJ54N1_COLUMN_SKIP; |
@@ -1449,12 +1384,11 @@ static int rj54n1_probe(struct i2c_client *client, | |||
1449 | 1384 | ||
1450 | ret = rj54n1_video_probe(icd, client, rj54n1_priv); | 1385 | ret = rj54n1_video_probe(icd, client, rj54n1_priv); |
1451 | if (ret < 0) { | 1386 | if (ret < 0) { |
1452 | icd->ops = NULL; | 1387 | v4l2_ctrl_handler_free(&rj54n1->hdl); |
1453 | kfree(rj54n1); | 1388 | kfree(rj54n1); |
1454 | return ret; | 1389 | return ret; |
1455 | } | 1390 | } |
1456 | 1391 | return v4l2_ctrl_handler_setup(&rj54n1->hdl); | |
1457 | return ret; | ||
1458 | } | 1392 | } |
1459 | 1393 | ||
1460 | static int rj54n1_remove(struct i2c_client *client) | 1394 | static int rj54n1_remove(struct i2c_client *client) |
@@ -1463,9 +1397,10 @@ static int rj54n1_remove(struct i2c_client *client) | |||
1463 | struct soc_camera_device *icd = client->dev.platform_data; | 1397 | struct soc_camera_device *icd = client->dev.platform_data; |
1464 | struct soc_camera_link *icl = to_soc_camera_link(icd); | 1398 | struct soc_camera_link *icl = to_soc_camera_link(icd); |
1465 | 1399 | ||
1466 | icd->ops = NULL; | 1400 | v4l2_device_unregister_subdev(&rj54n1->subdev); |
1467 | if (icl->free_bus) | 1401 | if (icl->free_bus) |
1468 | icl->free_bus(icl); | 1402 | icl->free_bus(icl); |
1403 | v4l2_ctrl_handler_free(&rj54n1->hdl); | ||
1469 | kfree(rj54n1); | 1404 | kfree(rj54n1); |
1470 | 1405 | ||
1471 | return 0; | 1406 | return 0; |