.. | .. |
---|
173 | 173 | const char *module_facing; |
---|
174 | 174 | const char *module_name; |
---|
175 | 175 | const char *len_name; |
---|
| 176 | + enum rkmodule_sync_mode sync_mode; |
---|
176 | 177 | u32 cur_vts; |
---|
177 | 178 | bool has_init_exp; |
---|
178 | 179 | bool is_thunderboot; |
---|
.. | .. |
---|
534 | 535 | {REG_NULL, 0x00}, |
---|
535 | 536 | }; |
---|
536 | 537 | |
---|
| 538 | +static __maybe_unused const struct regval sc230ai_interal_sync_master_start_regs[] = { |
---|
| 539 | + {0x300a, 0x24}, //sync as output PAD |
---|
| 540 | + {0x3032, 0xa0}, |
---|
| 541 | + {0x3222, 0x00}, //master mode |
---|
| 542 | + {REG_NULL, 0x00}, |
---|
| 543 | +}; |
---|
| 544 | + |
---|
| 545 | +static __maybe_unused const struct regval sc230ai_interal_sync_master_stop_regs[] = { |
---|
| 546 | + {REG_NULL, 0x00}, |
---|
| 547 | +}; |
---|
| 548 | + |
---|
| 549 | +static __maybe_unused const struct regval sc230ai_interal_sync_slaver_start_regs[] = { |
---|
| 550 | + {0x300a, 0x20}, //sync as input PAD |
---|
| 551 | + {0x3222, 0x01}, //slave mode |
---|
| 552 | + {0x3224, 0x92}, //fsync trigger |
---|
| 553 | + {0x3614, 0x01}, |
---|
| 554 | + {REG_NULL, 0x00}, |
---|
| 555 | +}; |
---|
| 556 | + |
---|
| 557 | +static __maybe_unused const struct regval sc230ai_interal_sync_slaver_stop_regs[] = { |
---|
| 558 | + {REG_NULL, 0x00}, |
---|
| 559 | +}; |
---|
537 | 560 | |
---|
538 | 561 | static const struct sc230ai_mode supported_modes[] = { |
---|
539 | 562 | { |
---|
.. | .. |
---|
930 | 953 | u32 i, h, w; |
---|
931 | 954 | long ret = 0; |
---|
932 | 955 | u32 stream = 0; |
---|
| 956 | + u32 *sync_mode = NULL; |
---|
933 | 957 | |
---|
934 | 958 | switch (cmd) { |
---|
935 | 959 | case RKMODULE_GET_MODULE_INFO: |
---|
.. | .. |
---|
980 | 1004 | ret = sc230ai_write_reg(sc230ai->client, SC230AI_REG_CTRL_MODE, |
---|
981 | 1005 | SC230AI_REG_VALUE_08BIT, SC230AI_MODE_SW_STANDBY); |
---|
982 | 1006 | break; |
---|
| 1007 | + case RKMODULE_GET_SYNC_MODE: |
---|
| 1008 | + sync_mode = (u32 *)arg; |
---|
| 1009 | + *sync_mode = sc230ai->sync_mode; |
---|
| 1010 | + break; |
---|
| 1011 | + case RKMODULE_SET_SYNC_MODE: |
---|
| 1012 | + sync_mode = (u32 *)arg; |
---|
| 1013 | + sc230ai->sync_mode = *sync_mode; |
---|
| 1014 | + break; |
---|
983 | 1015 | default: |
---|
984 | 1016 | ret = -ENOIOCTLCMD; |
---|
985 | 1017 | break; |
---|
.. | .. |
---|
998 | 1030 | struct preisp_hdrae_exp_s *hdrae; |
---|
999 | 1031 | long ret; |
---|
1000 | 1032 | u32 stream = 0; |
---|
| 1033 | + u32 sync_mode; |
---|
1001 | 1034 | |
---|
1002 | 1035 | switch (cmd) { |
---|
1003 | 1036 | case RKMODULE_GET_MODULE_INFO: |
---|
.. | .. |
---|
1066 | 1099 | |
---|
1067 | 1100 | ret = sc230ai_ioctl(sd, cmd, &stream); |
---|
1068 | 1101 | break; |
---|
| 1102 | + case RKMODULE_GET_SYNC_MODE: |
---|
| 1103 | + ret = sc230ai_ioctl(sd, cmd, &sync_mode); |
---|
| 1104 | + if (!ret) { |
---|
| 1105 | + ret = copy_to_user(up, &sync_mode, sizeof(u32)); |
---|
| 1106 | + if (ret) |
---|
| 1107 | + ret = -EFAULT; |
---|
| 1108 | + } |
---|
| 1109 | + break; |
---|
| 1110 | + case RKMODULE_SET_SYNC_MODE: |
---|
| 1111 | + ret = copy_from_user(&sync_mode, up, sizeof(u32)); |
---|
| 1112 | + if (!ret) |
---|
| 1113 | + ret = sc230ai_ioctl(sd, cmd, &sync_mode); |
---|
| 1114 | + else |
---|
| 1115 | + ret = -EFAULT; |
---|
| 1116 | + break; |
---|
1069 | 1117 | default: |
---|
1070 | 1118 | ret = -ENOIOCTLCMD; |
---|
1071 | 1119 | break; |
---|
.. | .. |
---|
1077 | 1125 | |
---|
1078 | 1126 | static int __sc230ai_start_stream(struct sc230ai *sc230ai) |
---|
1079 | 1127 | { |
---|
1080 | | - int ret; |
---|
| 1128 | + int ret = 0; |
---|
1081 | 1129 | |
---|
1082 | 1130 | if (!sc230ai->is_thunderboot) { |
---|
1083 | 1131 | ret = sc230ai_write_array(sc230ai->client, sc230ai->cur_mode->reg_list); |
---|
.. | .. |
---|
1096 | 1144 | return ret; |
---|
1097 | 1145 | } |
---|
1098 | 1146 | } |
---|
| 1147 | + if (sc230ai->sync_mode == INTERNAL_MASTER_MODE) |
---|
| 1148 | + ret |= sc230ai_write_array(sc230ai->client, |
---|
| 1149 | + sc230ai_interal_sync_master_start_regs); |
---|
| 1150 | + else if (sc230ai->sync_mode == SLAVE_MODE) |
---|
| 1151 | + ret |= sc230ai_write_array(sc230ai->client, |
---|
| 1152 | + sc230ai_interal_sync_slaver_start_regs); |
---|
1099 | 1153 | } |
---|
1100 | | - return sc230ai_write_reg(sc230ai->client, SC230AI_REG_CTRL_MODE, |
---|
| 1154 | + ret |= sc230ai_write_reg(sc230ai->client, SC230AI_REG_CTRL_MODE, |
---|
1101 | 1155 | SC230AI_REG_VALUE_08BIT, SC230AI_MODE_STREAMING); |
---|
| 1156 | + return ret; |
---|
1102 | 1157 | } |
---|
1103 | 1158 | |
---|
1104 | 1159 | static int __sc230ai_stop_stream(struct sc230ai *sc230ai) |
---|
1105 | 1160 | { |
---|
| 1161 | + int ret = 0; |
---|
1106 | 1162 | sc230ai->has_init_exp = false; |
---|
1107 | 1163 | if (sc230ai->is_thunderboot) { |
---|
1108 | 1164 | sc230ai->is_first_streamoff = true; |
---|
1109 | 1165 | pm_runtime_put(&sc230ai->client->dev); |
---|
| 1166 | + } else { |
---|
| 1167 | + if (sc230ai->sync_mode == INTERNAL_MASTER_MODE) |
---|
| 1168 | + ret |= sc230ai_write_array(sc230ai->client, |
---|
| 1169 | + sc230ai_interal_sync_master_stop_regs); |
---|
| 1170 | + else if (sc230ai->sync_mode == SLAVE_MODE) |
---|
| 1171 | + ret |= sc230ai_write_array(sc230ai->client, |
---|
| 1172 | + sc230ai_interal_sync_slaver_stop_regs); |
---|
1110 | 1173 | } |
---|
1111 | | - return sc230ai_write_reg(sc230ai->client, SC230AI_REG_CTRL_MODE, |
---|
| 1174 | + ret |= sc230ai_write_reg(sc230ai->client, SC230AI_REG_CTRL_MODE, |
---|
1112 | 1175 | SC230AI_REG_VALUE_08BIT, SC230AI_MODE_SW_STANDBY); |
---|
| 1176 | + return ret; |
---|
1113 | 1177 | } |
---|
1114 | 1178 | |
---|
1115 | 1179 | static int __sc230ai_power_on(struct sc230ai *sc230ai); |
---|
.. | .. |
---|
1625 | 1689 | char facing[2]; |
---|
1626 | 1690 | int ret; |
---|
1627 | 1691 | u32 i, hdr_mode = 0; |
---|
| 1692 | + const char *sync_mode_name = NULL; |
---|
1628 | 1693 | |
---|
1629 | 1694 | dev_info(dev, "driver version: %02x.%02x.%02x", |
---|
1630 | 1695 | DRIVER_VERSION >> 16, |
---|
.. | .. |
---|
1648 | 1713 | dev_err(dev, "could not get module information!\n"); |
---|
1649 | 1714 | return -EINVAL; |
---|
1650 | 1715 | } |
---|
| 1716 | + |
---|
| 1717 | + ret = of_property_read_string(node, RKMODULE_CAMERA_SYNC_MODE, |
---|
| 1718 | + &sync_mode_name); |
---|
| 1719 | + if (ret) { |
---|
| 1720 | + sc230ai->sync_mode = NO_SYNC_MODE; |
---|
| 1721 | + dev_err(dev, "could not get sync mode!\n"); |
---|
| 1722 | + } else { |
---|
| 1723 | + if (strcmp(sync_mode_name, RKMODULE_EXTERNAL_MASTER_MODE) == 0) { |
---|
| 1724 | + sc230ai->sync_mode = EXTERNAL_MASTER_MODE; |
---|
| 1725 | + dev_info(dev, "external master mode\n"); |
---|
| 1726 | + } else if (strcmp(sync_mode_name, RKMODULE_INTERNAL_MASTER_MODE) == 0) { |
---|
| 1727 | + sc230ai->sync_mode = INTERNAL_MASTER_MODE; |
---|
| 1728 | + dev_info(dev, "internal master mode\n"); |
---|
| 1729 | + } else if (strcmp(sync_mode_name, RKMODULE_SLAVE_MODE) == 0) { |
---|
| 1730 | + sc230ai->sync_mode = SLAVE_MODE; |
---|
| 1731 | + dev_info(dev, "slave mode\n"); |
---|
| 1732 | + } |
---|
| 1733 | + } |
---|
| 1734 | + |
---|
1651 | 1735 | sc230ai->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP); |
---|
1652 | 1736 | sc230ai->client = client; |
---|
1653 | 1737 | for (i = 0; i < ARRAY_SIZE(supported_modes); i++) { |
---|