.. | .. |
---|
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 = { |
---|