| .. | .. |
|---|
| 8 | 8 | * V0.0X01.0X01 |
|---|
| 9 | 9 | * 1. add workqueue to detect ahd state. |
|---|
| 10 | 10 | * 2. add more resolution support. |
|---|
| 11 | | - * V0.0X01.0X02 |
|---|
| 12 | | - * 1. get init status before start workqueue. |
|---|
| 13 | | - * 2. replace some dev_info to dev_dbg. |
|---|
| 14 | 11 | */ |
|---|
| 15 | 12 | |
|---|
| 16 | 13 | #include <linux/clk.h> |
|---|
| .. | .. |
|---|
| 48 | 45 | #include "nvp6158_video_auto_detect.h" |
|---|
| 49 | 46 | #include "nvp6158_drv.h" |
|---|
| 50 | 47 | |
|---|
| 51 | | -#define WORK_QUEUE |
|---|
| 48 | +//#define WORK_QUEUE |
|---|
| 52 | 49 | |
|---|
| 53 | 50 | #ifdef WORK_QUEUE |
|---|
| 54 | 51 | #include <linux/workqueue.h> |
|---|
| .. | .. |
|---|
| 60 | 57 | |
|---|
| 61 | 58 | #endif |
|---|
| 62 | 59 | |
|---|
| 63 | | -#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x2) |
|---|
| 60 | +#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x1) |
|---|
| 64 | 61 | |
|---|
| 65 | 62 | #ifndef V4L2_CID_DIGITAL_GAIN |
|---|
| 66 | 63 | #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN |
|---|
| 67 | 64 | #endif |
|---|
| 68 | 65 | |
|---|
| 69 | 66 | #define NVP6158_XVCLK_FREQ 24000000 |
|---|
| 70 | | -#define NVP6158_BITS_PER_SAMPLE 8 |
|---|
| 67 | +#define NVP6158_BITS_PER_SAMPLE 8 |
|---|
| 71 | 68 | |
|---|
| 72 | 69 | /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */ |
|---|
| 73 | 70 | #define NVP6158_PIXEL_RATE 297000000LL |
|---|
| .. | .. |
|---|
| 79 | 76 | #define OF_CAMERA_MODULE_REGULATOR_VOLTAGES "rockchip,regulator-voltages" |
|---|
| 80 | 77 | |
|---|
| 81 | 78 | /* DVP MODE, BT1120 or BT656 */ |
|---|
| 82 | | -#define RK_CAMERA_MODULE_DVP_MODE "rockchip,dvp_mode" |
|---|
| 79 | +#define RK_CAMERA_MODULE_DVP_MODE "rockchip,dvp_mode" |
|---|
| 83 | 80 | #define RK_CAMERA_MODULE_CHANNEL_NUMS "rockchip,channel_nums" |
|---|
| 84 | | -#define RK_CAMERA_MODULE_DUAL_EDGE "rockchip,dual_edge" |
|---|
| 81 | +#define RK_CAMERA_MODULE_DUAL_EDGE "rockchip,dual_edge" |
|---|
| 85 | 82 | #define RK_CAMERA_MODULE_DEFAULT_RECT "rockchip,default_rect" |
|---|
| 86 | 83 | |
|---|
| 87 | 84 | #define NVP6158_DEFAULT_DVP_MODE "BT1120" |
|---|
| 88 | | -#define NVP6158_DEFAULT_CHANNEL_NUMS 4U |
|---|
| 85 | +#define NVP6158_DEFAULT_CHANNEL_NUMS 4U |
|---|
| 89 | 86 | #define NVP6158_DEFAULT_DUAL_EDGE 0U |
|---|
| 90 | 87 | #define NVP6158_NAME "nvp6158" |
|---|
| 91 | | -#define NVP6158_DEFAULT_WIDTH 1920 |
|---|
| 92 | | -#define NVP6158_DEFAULT_HEIGHT 1080 |
|---|
| 93 | | - |
|---|
| 94 | | -enum nvp6158_max_pad { |
|---|
| 95 | | - PAD0, |
|---|
| 96 | | - PAD1, |
|---|
| 97 | | - PAD2, |
|---|
| 98 | | - PAD3, |
|---|
| 99 | | - PAD_MAX, |
|---|
| 100 | | -}; |
|---|
| 88 | +#define NVP6158_DEFAULT_WIDTH 1920 |
|---|
| 89 | +#define NVP6158_DEFAULT_HEIGHT 1080 |
|---|
| 101 | 90 | |
|---|
| 102 | 91 | struct nvp6158_gpio { |
|---|
| 103 | 92 | int pltfrm_gpio; |
|---|
| .. | .. |
|---|
| 195 | 184 | .numerator = 10000, |
|---|
| 196 | 185 | .denominator = 250000, |
|---|
| 197 | 186 | }, |
|---|
| 198 | | - }, |
|---|
| 199 | | - { |
|---|
| 187 | + }, { |
|---|
| 200 | 188 | .width = 1920, |
|---|
| 201 | 189 | .height = 1080, |
|---|
| 202 | 190 | .fmt_idx = AHD20_1080P_25P, |
|---|
| .. | .. |
|---|
| 204 | 192 | .numerator = 10000, |
|---|
| 205 | 193 | .denominator = 250000, |
|---|
| 206 | 194 | }, |
|---|
| 207 | | - }, |
|---|
| 208 | | - { |
|---|
| 195 | + }, { |
|---|
| 209 | 196 | .width = 2048, |
|---|
| 210 | 197 | .height = 1536, |
|---|
| 211 | 198 | .fmt_idx = AHD30_3M_18P, |
|---|
| .. | .. |
|---|
| 213 | 200 | .numerator = 10000, |
|---|
| 214 | 201 | .denominator = 180000, |
|---|
| 215 | 202 | }, |
|---|
| 216 | | - }, |
|---|
| 217 | | - { |
|---|
| 203 | + }, { |
|---|
| 218 | 204 | .width = 1280, |
|---|
| 219 | 205 | .height = 1440, |
|---|
| 220 | 206 | .fmt_idx = AHD30_4M_30P, |
|---|
| .. | .. |
|---|
| 222 | 208 | .numerator = 10000, |
|---|
| 223 | 209 | .denominator = 300000, |
|---|
| 224 | 210 | }, |
|---|
| 225 | | - }, |
|---|
| 226 | | - { |
|---|
| 211 | + }, { |
|---|
| 227 | 212 | .width = 2560, |
|---|
| 228 | 213 | .height = 1440, |
|---|
| 229 | 214 | .fmt_idx = AHD30_4M_15P, |
|---|
| .. | .. |
|---|
| 231 | 216 | .numerator = 10000, |
|---|
| 232 | 217 | .denominator = 150000, |
|---|
| 233 | 218 | }, |
|---|
| 234 | | - }, |
|---|
| 235 | | - { |
|---|
| 219 | + }, { |
|---|
| 236 | 220 | .width = 2592, |
|---|
| 237 | 221 | .height = 1944, |
|---|
| 238 | 222 | .fmt_idx = AHD30_5M_12_5P, |
|---|
| .. | .. |
|---|
| 240 | 224 | .numerator = 10000, |
|---|
| 241 | 225 | .denominator = 125000, |
|---|
| 242 | 226 | }, |
|---|
| 243 | | - }, |
|---|
| 244 | | - { |
|---|
| 227 | + }, { |
|---|
| 245 | 228 | .width = 3840, |
|---|
| 246 | 229 | .height = 2160, |
|---|
| 247 | 230 | .fmt_idx = AHD30_8M_7_5P, |
|---|
| .. | .. |
|---|
| 249 | 232 | .numerator = 10000, |
|---|
| 250 | 233 | .denominator = 75000, |
|---|
| 251 | 234 | }, |
|---|
| 252 | | - }, |
|---|
| 253 | | - |
|---|
| 254 | | - /* test modes, Interlace mode*/ |
|---|
| 255 | | - { |
|---|
| 235 | + }, {/* test modes, Interlace mode*/ |
|---|
| 256 | 236 | .width = 720, |
|---|
| 257 | 237 | .height = 480, |
|---|
| 258 | 238 | .fmt_idx = AHD20_SD_SH720_NT, |
|---|
| .. | .. |
|---|
| 260 | 240 | .numerator = 10000, |
|---|
| 261 | 241 | .denominator = 250000, |
|---|
| 262 | 242 | }, |
|---|
| 263 | | - }, |
|---|
| 264 | | - { |
|---|
| 243 | + }, { |
|---|
| 265 | 244 | .width = 720, |
|---|
| 266 | 245 | .height = 576, |
|---|
| 267 | 246 | .fmt_idx = AHD20_SD_SH720_PAL, |
|---|
| .. | .. |
|---|
| 269 | 248 | .numerator = 10000, |
|---|
| 270 | 249 | .denominator = 250000, |
|---|
| 271 | 250 | }, |
|---|
| 272 | | - }, |
|---|
| 273 | | - { |
|---|
| 251 | + }, { |
|---|
| 274 | 252 | .width = 960, |
|---|
| 275 | 253 | .height = 576, |
|---|
| 276 | 254 | .fmt_idx = AHD20_SD_H960_PAL, |
|---|
| .. | .. |
|---|
| 278 | 256 | .numerator = 10000, |
|---|
| 279 | 257 | .denominator = 250000, |
|---|
| 280 | 258 | }, |
|---|
| 281 | | - }, |
|---|
| 282 | | - { |
|---|
| 259 | + }, { |
|---|
| 283 | 260 | .width = 1920, |
|---|
| 284 | 261 | .height = 576, |
|---|
| 285 | 262 | .fmt_idx = AHD20_SD_H960_EX_PAL, |
|---|
| .. | .. |
|---|
| 328 | 305 | u8 buf[2]; |
|---|
| 329 | 306 | int ret; |
|---|
| 330 | 307 | |
|---|
| 331 | | - dev_dbg(&client->dev, "write reg(0x%x val:0x%x)!\n", reg, val); |
|---|
| 308 | + dev_info(&client->dev, "write reg(0x%x val:0x%x)!\n", reg, val); |
|---|
| 332 | 309 | buf[0] = reg & 0xFF; |
|---|
| 333 | 310 | buf[1] = val; |
|---|
| 334 | 311 | |
|---|
| .. | .. |
|---|
| 624 | 601 | nvp6158->frame_size = match; |
|---|
| 625 | 602 | } |
|---|
| 626 | 603 | |
|---|
| 627 | | -static inline bool nvp6158_no_signal(struct v4l2_subdev *sd, u8 *novid); |
|---|
| 628 | 604 | static int nvp6158_stream(struct v4l2_subdev *sd, int on) |
|---|
| 629 | 605 | { |
|---|
| 630 | 606 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
|---|
| .. | .. |
|---|
| 652 | 628 | video_init.mode = nvp6158->mode; |
|---|
| 653 | 629 | nvp6158_start(&video_init, nvp6158->dual_edge ? true : false); |
|---|
| 654 | 630 | #ifdef WORK_QUEUE |
|---|
| 655 | | - nvp6158->hot_plug = false; |
|---|
| 656 | | - nvp6158->is_reset = 0; |
|---|
| 657 | | - usleep_range(20000, 21000); |
|---|
| 658 | | - /* get power on state first*/ |
|---|
| 659 | | - nvp6158_no_signal(sd, &nvp6158->last_detect_status); |
|---|
| 660 | | - |
|---|
| 661 | 631 | if (nvp6158->plug_state_check.state_check_wq) { |
|---|
| 662 | 632 | dev_info(&client->dev, "%s queue_delayed_work 1000ms", __func__); |
|---|
| 663 | 633 | queue_delayed_work(nvp6158->plug_state_check.state_check_wq, |
|---|
| .. | .. |
|---|
| 752 | 722 | dev_err(&client->dev, "Failed to read videoloss state!\n"); |
|---|
| 753 | 723 | |
|---|
| 754 | 724 | *novid = videoloss; |
|---|
| 755 | | - dev_dbg(&client->dev, "%s: video loss status:0x%x.\n", __func__, videoloss); |
|---|
| 725 | + dev_info(&client->dev, "%s: video loss status:0x%x.\n", __func__, videoloss); |
|---|
| 756 | 726 | if (videoloss == 0xf) { |
|---|
| 757 | | - dev_dbg(&client->dev, "%s: all channels No Video detected.\n", __func__); |
|---|
| 727 | + dev_info(&client->dev, "%s: all channels No Video detected.\n", __func__); |
|---|
| 758 | 728 | no_signal = true; |
|---|
| 759 | 729 | } else { |
|---|
| 760 | | - dev_dbg(&client->dev, "%s: channel has some video detection.\n", __func__); |
|---|
| 730 | + dev_info(&client->dev, "%s: channel has some video detection.\n", __func__); |
|---|
| 761 | 731 | no_signal = false; |
|---|
| 762 | 732 | } |
|---|
| 763 | 733 | return no_signal; |
|---|
| .. | .. |
|---|
| 776 | 746 | if (ret < 0) |
|---|
| 777 | 747 | dev_err(&client->dev, "Failed to read sync state!\n"); |
|---|
| 778 | 748 | |
|---|
| 779 | | - dev_dbg(&client->dev, "%s: video AGC LOCK status:0x%x.\n", |
|---|
| 749 | + dev_info(&client->dev, "%s: video AGC LOCK status:0x%x.\n", |
|---|
| 780 | 750 | __func__, video_lock_status); |
|---|
| 781 | 751 | *lock_st = video_lock_status; |
|---|
| 782 | 752 | if (video_lock_status) { |
|---|
| 783 | | - dev_dbg(&client->dev, "%s: channel has AGC LOCK.\n", __func__); |
|---|
| 753 | + dev_info(&client->dev, "%s: channel has AGC LOCK.\n", __func__); |
|---|
| 784 | 754 | has_sync = true; |
|---|
| 785 | 755 | } else { |
|---|
| 786 | | - dev_dbg(&client->dev, "%s: channel has no AGC LOCK.\n", __func__); |
|---|
| 756 | + dev_info(&client->dev, "%s: channel has no AGC LOCK.\n", __func__); |
|---|
| 787 | 757 | has_sync = false; |
|---|
| 788 | 758 | } |
|---|
| 789 | 759 | return has_sync; |
|---|
| .. | .. |
|---|
| 813 | 783 | nvp6158->hot_plug = false; |
|---|
| 814 | 784 | nvp6158->last_detect_status = nvp6158->cur_detect_status; |
|---|
| 815 | 785 | |
|---|
| 786 | + dev_info(&client->dev, "%s has plug motion? (%s)", __func__, |
|---|
| 787 | + nvp6158->hot_plug ? "true" : "false"); |
|---|
| 816 | 788 | if (nvp6158->hot_plug) { |
|---|
| 817 | | - dev_info(&client->dev, "queue_delayed_work 1500ms, has hot plug motion."); |
|---|
| 789 | + dev_info(&client->dev, "queue_delayed_work 1500ms, if has hot plug motion."); |
|---|
| 818 | 790 | queue_delayed_work(nvp6158->plug_state_check.state_check_wq, |
|---|
| 819 | 791 | &nvp6158->plug_state_check.d_work, msecs_to_jiffies(1500)); |
|---|
| 820 | 792 | nvp6158_write(client, 0xFF, 0x20); |
|---|
| .. | .. |
|---|
| 822 | 794 | usleep_range(3000, 5000); |
|---|
| 823 | 795 | nvp6158_write(client, 0x00, 0xFF); |
|---|
| 824 | 796 | } else { |
|---|
| 825 | | - dev_dbg(&client->dev, "queue_delayed_work 100ms, if no hot plug motion."); |
|---|
| 797 | + dev_info(&client->dev, "queue_delayed_work 100ms, if no hot plug motion."); |
|---|
| 826 | 798 | queue_delayed_work(nvp6158->plug_state_check.state_check_wq, |
|---|
| 827 | 799 | &nvp6158->plug_state_check.d_work, msecs_to_jiffies(100)); |
|---|
| 828 | 800 | } |
|---|
| 829 | 801 | } |
|---|
| 830 | 802 | #endif |
|---|
| 831 | 803 | |
|---|
| 832 | | -static int nvp6158_g_mbus_config(struct v4l2_subdev *sd, |
|---|
| 804 | +static int nvp6158_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad, |
|---|
| 833 | 805 | struct v4l2_mbus_config *cfg) |
|---|
| 834 | 806 | { |
|---|
| 835 | 807 | struct nvp6158 *nvp6158 = to_nvp6158(sd); |
|---|
| .. | .. |
|---|
| 950 | 922 | |
|---|
| 951 | 923 | mutex_unlock(&nvp6158->mutex); |
|---|
| 952 | 924 | return ret; |
|---|
| 925 | +} |
|---|
| 926 | + |
|---|
| 927 | +static int nvp6158_g_frame_interval(struct v4l2_subdev *sd, |
|---|
| 928 | + struct v4l2_subdev_frame_interval *fi) |
|---|
| 929 | +{ |
|---|
| 930 | + struct nvp6158 *nvp6158 = to_nvp6158(sd); |
|---|
| 931 | + const struct nvp6158_framesize *size = nvp6158->frame_size; |
|---|
| 932 | + |
|---|
| 933 | + fi->interval = size->max_fps; |
|---|
| 934 | + |
|---|
| 935 | + return 0; |
|---|
| 953 | 936 | } |
|---|
| 954 | 937 | |
|---|
| 955 | 938 | static void nvp6158_get_module_inf(struct nvp6158 *nvp6158, |
|---|
| .. | .. |
|---|
| 1201 | 1184 | |
|---|
| 1202 | 1185 | static const struct v4l2_subdev_video_ops nvp6158_video_ops = { |
|---|
| 1203 | 1186 | .s_stream = nvp6158_stream, |
|---|
| 1204 | | - .g_mbus_config = nvp6158_g_mbus_config, |
|---|
| 1205 | 1187 | .querystd = nvp6158_querystd, |
|---|
| 1188 | + .g_frame_interval = nvp6158_g_frame_interval, |
|---|
| 1206 | 1189 | }; |
|---|
| 1207 | 1190 | |
|---|
| 1208 | 1191 | static const struct v4l2_subdev_pad_ops nvp6158_subdev_pad_ops = { |
|---|
| .. | .. |
|---|
| 1212 | 1195 | .set_fmt = nvp6158_set_fmt, |
|---|
| 1213 | 1196 | .get_selection = nvp6158_get_selection, |
|---|
| 1214 | 1197 | .enum_frame_interval = nvp6158_enum_frame_interval, |
|---|
| 1198 | + .get_mbus_config = nvp6158_g_mbus_config, |
|---|
| 1215 | 1199 | }; |
|---|
| 1216 | 1200 | |
|---|
| 1217 | 1201 | static const struct v4l2_subdev_core_ops nvp6158_core_ops = { |
|---|