.. | .. |
---|
8 | 8 | * V0.0X01.0X02 fix mclk issue when probe multiple camera. |
---|
9 | 9 | * V0.0X01.0X03 add otp function. |
---|
10 | 10 | * V0.0X01.0X04 add enum_frame_interval function. |
---|
11 | | - * V0.0X01.0X05 add quick stream on/off |
---|
12 | | - * V0.0X01.0X06 add function g_mmbus_config |
---|
13 | 11 | */ |
---|
14 | 12 | |
---|
15 | 13 | #include <linux/clk.h> |
---|
.. | .. |
---|
39 | 37 | #include <linux/rk-camera-module.h> |
---|
40 | 38 | |
---|
41 | 39 | /* verify default register values */ |
---|
42 | | -//#define CHECK_REG_VALUE |
---|
| 40 | +#define CHECK_REG_VALUE |
---|
43 | 41 | |
---|
44 | | -#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x06) |
---|
| 42 | +#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x04) |
---|
45 | 43 | |
---|
46 | 44 | #ifndef V4L2_CID_DIGITAL_GAIN |
---|
47 | 45 | #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN |
---|
.. | .. |
---|
543 | 541 | {0x5045, 0x05}, //[2] enable MWB manual bias |
---|
544 | 542 | {0x5048, 0x10}, //MWB manual bias be the same with 0x4003 BLC target. |
---|
545 | 543 | //{0x0100, 0x01}, |
---|
546 | | - |
---|
547 | 544 | {REG_NULL, 0x00}, |
---|
548 | 545 | }; |
---|
549 | 546 | |
---|
.. | .. |
---|
932 | 929 | if (ov5670_module_info[i].id == otp->module_id) |
---|
933 | 930 | break; |
---|
934 | 931 | } |
---|
935 | | - strlcpy(inf->fac.module, ov5670_module_info[i].name, |
---|
| 932 | + strscpy(inf->fac.module, ov5670_module_info[i].name, |
---|
936 | 933 | sizeof(inf->fac.module)); |
---|
937 | 934 | |
---|
938 | 935 | for (i = 0; i < ARRAY_SIZE(ov5670_lens_info) - 1; i++) { |
---|
939 | 936 | if (ov5670_lens_info[i].id == otp->lens_id) |
---|
940 | 937 | break; |
---|
941 | 938 | } |
---|
942 | | - strlcpy(inf->fac.lens, ov5670_lens_info[i].name, |
---|
| 939 | + strscpy(inf->fac.lens, ov5670_lens_info[i].name, |
---|
943 | 940 | sizeof(inf->fac.lens)); |
---|
944 | 941 | } |
---|
945 | 942 | |
---|
.. | .. |
---|
978 | 975 | struct rkmodule_inf *inf) |
---|
979 | 976 | { |
---|
980 | 977 | struct ov5670_otp_info *otp = ov5670->otp; |
---|
| 978 | + |
---|
981 | 979 | memset(inf, 0, sizeof(*inf)); |
---|
982 | | - strlcpy(inf->base.sensor, OV5670_NAME, sizeof(inf->base.sensor)); |
---|
983 | | - strlcpy(inf->base.module, ov5670->module_name, |
---|
| 980 | + strscpy(inf->base.sensor, OV5670_NAME, sizeof(inf->base.sensor)); |
---|
| 981 | + strscpy(inf->base.module, ov5670->module_name, |
---|
984 | 982 | sizeof(inf->base.module)); |
---|
985 | | - strlcpy(inf->base.lens, ov5670->len_name, sizeof(inf->base.lens)); |
---|
| 983 | + strscpy(inf->base.lens, ov5670->len_name, sizeof(inf->base.lens)); |
---|
986 | 984 | if (otp) |
---|
987 | 985 | ov5670_get_otp(otp, inf); |
---|
988 | 986 | } |
---|
.. | .. |
---|
999 | 997 | { |
---|
1000 | 998 | struct ov5670 *ov5670 = to_ov5670(sd); |
---|
1001 | 999 | long ret = 0; |
---|
1002 | | - u32 stream = 0; |
---|
1003 | 1000 | |
---|
1004 | 1001 | switch (cmd) { |
---|
1005 | 1002 | case RKMODULE_GET_MODULE_INFO: |
---|
.. | .. |
---|
1007 | 1004 | break; |
---|
1008 | 1005 | case RKMODULE_AWB_CFG: |
---|
1009 | 1006 | ov5670_set_awb_cfg(ov5670, (struct rkmodule_awb_cfg *)arg); |
---|
1010 | | - break; |
---|
1011 | | - case RKMODULE_SET_QUICK_STREAM: |
---|
1012 | | - |
---|
1013 | | - stream = *((u32 *)arg); |
---|
1014 | | - |
---|
1015 | | - if (stream) |
---|
1016 | | - ret = ov5670_write_reg(ov5670->client, OV5670_REG_CTRL_MODE, |
---|
1017 | | - OV5670_REG_VALUE_08BIT, OV5670_MODE_STREAMING); |
---|
1018 | | - else |
---|
1019 | | - ret = ov5670_write_reg(ov5670->client, OV5670_REG_CTRL_MODE, |
---|
1020 | | - OV5670_REG_VALUE_08BIT, OV5670_MODE_SW_STANDBY); |
---|
1021 | 1007 | break; |
---|
1022 | 1008 | default: |
---|
1023 | 1009 | ret = -ENOIOCTLCMD; |
---|
.. | .. |
---|
1035 | 1021 | struct rkmodule_inf *inf; |
---|
1036 | 1022 | struct rkmodule_awb_cfg *awb_cfg; |
---|
1037 | 1023 | long ret; |
---|
1038 | | - u32 stream = 0; |
---|
1039 | 1024 | |
---|
1040 | 1025 | switch (cmd) { |
---|
1041 | 1026 | case RKMODULE_GET_MODULE_INFO: |
---|
.. | .. |
---|
1046 | 1031 | } |
---|
1047 | 1032 | |
---|
1048 | 1033 | ret = ov5670_ioctl(sd, cmd, inf); |
---|
1049 | | - if (!ret) |
---|
1050 | | - ret = copy_to_user(up, inf, sizeof(*inf)); |
---|
| 1034 | + if (!ret) { |
---|
| 1035 | + if (copy_to_user(up, inf, sizeof(*inf))) |
---|
| 1036 | + return -EFAULT; |
---|
| 1037 | + } |
---|
1051 | 1038 | kfree(inf); |
---|
1052 | 1039 | break; |
---|
1053 | 1040 | case RKMODULE_AWB_CFG: |
---|
.. | .. |
---|
1057 | 1044 | return ret; |
---|
1058 | 1045 | } |
---|
1059 | 1046 | |
---|
1060 | | - ret = copy_from_user(awb_cfg, up, sizeof(*awb_cfg)); |
---|
1061 | | - if (!ret) |
---|
1062 | | - ret = ov5670_ioctl(sd, cmd, awb_cfg); |
---|
| 1047 | + if (copy_from_user(awb_cfg, up, sizeof(*awb_cfg))) |
---|
| 1048 | + return -EFAULT; |
---|
| 1049 | + |
---|
| 1050 | + ret = ov5670_ioctl(sd, cmd, awb_cfg); |
---|
1063 | 1051 | kfree(awb_cfg); |
---|
1064 | | - break; |
---|
1065 | | - case RKMODULE_SET_QUICK_STREAM: |
---|
1066 | | - ret = copy_from_user(&stream, up, sizeof(u32)); |
---|
1067 | | - if (!ret) |
---|
1068 | | - ret = ov5670_ioctl(sd, cmd, &stream); |
---|
1069 | 1052 | break; |
---|
1070 | 1053 | default: |
---|
1071 | 1054 | ret = -ENOIOCTLCMD; |
---|
.. | .. |
---|
1075 | 1058 | return ret; |
---|
1076 | 1059 | } |
---|
1077 | 1060 | #endif |
---|
| 1061 | + |
---|
1078 | 1062 | /*--------------------------------------------------------------------------*/ |
---|
1079 | 1063 | static int ov5670_apply_otp(struct ov5670 *ov5670) |
---|
1080 | 1064 | { |
---|
.. | .. |
---|
1195 | 1179 | int ret = 0; |
---|
1196 | 1180 | |
---|
1197 | 1181 | dev_info(&client->dev, "%s: on: %d, %dx%d@%d\n", __func__, on, |
---|
1198 | | - ov5670->cur_mode->width, |
---|
1199 | | - ov5670->cur_mode->height, |
---|
| 1182 | + ov5670->cur_mode->width, |
---|
| 1183 | + ov5670->cur_mode->height, |
---|
1200 | 1184 | DIV_ROUND_CLOSEST(ov5670->cur_mode->max_fps.denominator, |
---|
1201 | 1185 | ov5670->cur_mode->max_fps.numerator)); |
---|
1202 | 1186 | |
---|
.. | .. |
---|
1414 | 1398 | if (fie->index >= ov5670->cfg_num) |
---|
1415 | 1399 | return -EINVAL; |
---|
1416 | 1400 | |
---|
1417 | | - if (fie->code != MEDIA_BUS_FMT_SBGGR10_1X10) |
---|
1418 | | - return -EINVAL; |
---|
1419 | | - |
---|
| 1401 | + fie->code = MEDIA_BUS_FMT_SBGGR10_1X10; |
---|
1420 | 1402 | fie->width = supported_modes[fie->index].width; |
---|
1421 | 1403 | fie->height = supported_modes[fie->index].height; |
---|
1422 | 1404 | fie->interval = supported_modes[fie->index].max_fps; |
---|
.. | .. |
---|
1424 | 1406 | } |
---|
1425 | 1407 | |
---|
1426 | 1408 | static int ov5670_g_mbus_config(struct v4l2_subdev *sd, |
---|
| 1409 | + unsigned int pad_id, |
---|
1427 | 1410 | struct v4l2_mbus_config *config) |
---|
1428 | 1411 | { |
---|
1429 | | - u32 val = 0; |
---|
| 1412 | + u32 val = 1 << (OV5670_LANES - 1) | |
---|
| 1413 | + V4L2_MBUS_CSI2_CHANNEL_0 | |
---|
| 1414 | + V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; |
---|
1430 | 1415 | |
---|
1431 | | - val = 1 << (OV5670_LANES - 1) | |
---|
1432 | | - V4L2_MBUS_CSI2_CHANNEL_0 | |
---|
1433 | | - V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; |
---|
1434 | | - config->type = V4L2_MBUS_CSI2; |
---|
| 1416 | + config->type = V4L2_MBUS_CSI2_DPHY; |
---|
1435 | 1417 | config->flags = val; |
---|
1436 | 1418 | |
---|
1437 | 1419 | return 0; |
---|
.. | .. |
---|
1459 | 1441 | static const struct v4l2_subdev_video_ops ov5670_video_ops = { |
---|
1460 | 1442 | .s_stream = ov5670_s_stream, |
---|
1461 | 1443 | .g_frame_interval = ov5670_g_frame_interval, |
---|
1462 | | - .g_mbus_config = ov5670_g_mbus_config, |
---|
1463 | 1444 | }; |
---|
1464 | 1445 | |
---|
1465 | 1446 | static const struct v4l2_subdev_pad_ops ov5670_pad_ops = { |
---|
.. | .. |
---|
1468 | 1449 | .enum_frame_interval = ov5670_enum_frame_interval, |
---|
1469 | 1450 | .get_fmt = ov5670_get_fmt, |
---|
1470 | 1451 | .set_fmt = ov5670_set_fmt, |
---|
| 1452 | + .get_mbus_config = ov5670_g_mbus_config, |
---|
1471 | 1453 | }; |
---|
1472 | 1454 | |
---|
1473 | 1455 | static const struct v4l2_subdev_ops ov5670_subdev_ops = { |
---|
.. | .. |
---|
1496 | 1478 | break; |
---|
1497 | 1479 | } |
---|
1498 | 1480 | |
---|
1499 | | - if (!pm_runtime_get_if_in_use(&client->dev)) |
---|
| 1481 | + if (pm_runtime_get(&client->dev) <= 0) |
---|
1500 | 1482 | return 0; |
---|
1501 | 1483 | |
---|
1502 | 1484 | switch (ctrl->id) { |
---|
.. | .. |
---|
1505 | 1487 | /*group 0*/ |
---|
1506 | 1488 | ret = ov5670_write_reg(ov5670->client, OV5670_REG_GROUP, |
---|
1507 | 1489 | OV5670_REG_VALUE_08BIT, 0x00); |
---|
1508 | | - ret = ov5670_write_reg(ov5670->client, OV5670_REG_EXPOSURE, |
---|
| 1490 | + ret |= ov5670_write_reg(ov5670->client, OV5670_REG_EXPOSURE, |
---|
1509 | 1491 | OV5670_REG_VALUE_24BIT, ctrl->val << 4); |
---|
1510 | | - ret = ov5670_write_reg(ov5670->client, OV5670_REG_GROUP, |
---|
| 1492 | + ret |= ov5670_write_reg(ov5670->client, OV5670_REG_GROUP, |
---|
1511 | 1493 | OV5670_REG_VALUE_08BIT, 0x10); |
---|
1512 | | - ret = ov5670_write_reg(ov5670->client, OV5670_REG_GROUP, |
---|
| 1494 | + ret |= ov5670_write_reg(ov5670->client, OV5670_REG_GROUP, |
---|
1513 | 1495 | OV5670_REG_VALUE_08BIT, 0xa0); |
---|
1514 | 1496 | |
---|
1515 | 1497 | break; |
---|
.. | .. |
---|
1518 | 1500 | ret = ov5670_write_reg(ov5670->client, OV5670_REG_GROUP, |
---|
1519 | 1501 | OV5670_REG_VALUE_08BIT, 0x01); |
---|
1520 | 1502 | |
---|
1521 | | - ret = ov5670_write_reg(ov5670->client, OV5670_REG_GAIN_L, |
---|
| 1503 | + ret |= ov5670_write_reg(ov5670->client, OV5670_REG_GAIN_L, |
---|
1522 | 1504 | OV5670_REG_VALUE_08BIT, |
---|
1523 | 1505 | ctrl->val & OV5670_GAIN_L_MASK); |
---|
1524 | 1506 | ret |= ov5670_write_reg(ov5670->client, OV5670_REG_GAIN_H, |
---|
1525 | 1507 | OV5670_REG_VALUE_08BIT, |
---|
1526 | 1508 | (ctrl->val >> OV5670_GAIN_H_SHIFT) & |
---|
1527 | 1509 | OV5670_GAIN_H_MASK); |
---|
1528 | | - ret = ov5670_write_reg(ov5670->client, OV5670_REG_GROUP, |
---|
| 1510 | + ret |= ov5670_write_reg(ov5670->client, OV5670_REG_GROUP, |
---|
1529 | 1511 | OV5670_REG_VALUE_08BIT, 0x11); |
---|
1530 | | - ret = ov5670_write_reg(ov5670->client, OV5670_REG_GROUP, |
---|
| 1512 | + ret |= ov5670_write_reg(ov5670->client, OV5670_REG_GROUP, |
---|
1531 | 1513 | OV5670_REG_VALUE_08BIT, 0xa1); |
---|
1532 | 1514 | break; |
---|
1533 | 1515 | case V4L2_CID_VBLANK: |
---|
.. | .. |
---|
1625 | 1607 | |
---|
1626 | 1608 | static int ov5670_otp_read(struct ov5670 *ov5670) |
---|
1627 | 1609 | { |
---|
1628 | | - int otp_flag, addr, temp, i; |
---|
| 1610 | + int otp_flag, addr, temp = 0, i; |
---|
1629 | 1611 | struct ov5670_otp_info *otp_ptr; |
---|
1630 | 1612 | struct device *dev = &ov5670->client->dev; |
---|
1631 | 1613 | struct i2c_client *client = ov5670->client; |
---|
.. | .. |
---|
1804 | 1786 | } |
---|
1805 | 1787 | |
---|
1806 | 1788 | ov5670->lane_num = rval; |
---|
1807 | | - if (2 == ov5670->lane_num) { |
---|
| 1789 | + if (ov5670->lane_num == 2) { |
---|
1808 | 1790 | ov5670->cur_mode = &supported_modes_2lane[0]; |
---|
1809 | 1791 | supported_modes = supported_modes_2lane; |
---|
1810 | 1792 | ov5670->cfg_num = ARRAY_SIZE(supported_modes_2lane); |
---|
.. | .. |
---|
1925 | 1907 | |
---|
1926 | 1908 | #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API |
---|
1927 | 1909 | sd->internal_ops = &ov5670_internal_ops; |
---|
1928 | | - sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | |
---|
1929 | | - V4L2_SUBDEV_FL_HAS_EVENTS; |
---|
| 1910 | + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; |
---|
1930 | 1911 | #endif |
---|
1931 | 1912 | #if defined(CONFIG_MEDIA_CONTROLLER) |
---|
1932 | 1913 | ov5670->pad.flags = MEDIA_PAD_FL_SOURCE; |
---|