.. | .. |
---|
1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
---|
2 | 2 | /* |
---|
3 | 3 | * jaguar1 driver |
---|
4 | | - * |
---|
5 | | - * V0.0X01.0X01 add workqueue to detect ahd state. |
---|
| 4 | + * V0.0X01.0X00 first version. |
---|
| 5 | + * V0.0X01.0X01 fix kernel5.10 compile error. |
---|
| 6 | + * V0.0X01.0X02 add workqueue to detect ahd state. |
---|
6 | 7 | * |
---|
7 | 8 | */ |
---|
8 | 9 | |
---|
.. | .. |
---|
39 | 40 | #include "jaguar1_video_eq.h" |
---|
40 | 41 | #include "jaguar1_mipi.h" |
---|
41 | 42 | #include "jaguar1_drv.h" |
---|
| 43 | +#include "jaguar1_v4l2.h" |
---|
42 | 44 | |
---|
43 | 45 | #define WORK_QUEUE |
---|
44 | 46 | |
---|
.. | .. |
---|
52 | 54 | |
---|
53 | 55 | #endif |
---|
54 | 56 | |
---|
55 | | -#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x1) |
---|
| 57 | +#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x2) |
---|
56 | 58 | |
---|
57 | 59 | #ifndef V4L2_CID_DIGITAL_GAIN |
---|
58 | 60 | #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN |
---|
.. | .. |
---|
81 | 83 | |
---|
82 | 84 | /* #define FORCE_720P */ |
---|
83 | 85 | |
---|
84 | | -enum jaguar1_max_pad { |
---|
85 | | - PAD0, |
---|
86 | | - PAD1, |
---|
87 | | - PAD2, |
---|
88 | | - PAD3, |
---|
89 | | - PAD_MAX, |
---|
90 | | -}; |
---|
91 | | - |
---|
92 | 86 | struct jaguar1_gpio { |
---|
93 | 87 | int pltfrm_gpio; |
---|
94 | 88 | const char *label; |
---|
.. | .. |
---|
113 | 107 | struct jaguar1_framesize { |
---|
114 | 108 | u16 width; |
---|
115 | 109 | u16 height; |
---|
| 110 | + struct v4l2_fract max_fps; |
---|
116 | 111 | enum NC_VIVO_CH_FORMATDEF fmt_idx; |
---|
| 112 | + __u32 field; |
---|
117 | 113 | }; |
---|
118 | 114 | |
---|
119 | 115 | struct jaguar1_default_rect { |
---|
.. | .. |
---|
176 | 172 | { |
---|
177 | 173 | .width = 2560, |
---|
178 | 174 | .height = 1440, |
---|
| 175 | + .max_fps = { |
---|
| 176 | + .numerator = 10000, |
---|
| 177 | + .denominator = 250000, |
---|
| 178 | + }, |
---|
179 | 179 | .fmt_idx = AHD20_720P_25P, |
---|
180 | 180 | } |
---|
181 | 181 | #else |
---|
182 | 182 | { |
---|
| 183 | + .width = 960, |
---|
| 184 | + .height = 480, |
---|
| 185 | + .max_fps = { |
---|
| 186 | + .numerator = 10000, |
---|
| 187 | + .denominator = 250000, |
---|
| 188 | + }, |
---|
| 189 | + .fmt_idx = AHD20_SD_H960_2EX_Btype_NT, |
---|
| 190 | + .field = V4L2_FIELD_INTERLACED, |
---|
| 191 | + }, |
---|
| 192 | + { |
---|
| 193 | + .width = 960, |
---|
| 194 | + .height = 576, |
---|
| 195 | + .max_fps = { |
---|
| 196 | + .numerator = 10000, |
---|
| 197 | + .denominator = 300000, |
---|
| 198 | + }, |
---|
| 199 | + .fmt_idx = AHD20_SD_H960_2EX_Btype_PAL, |
---|
| 200 | + .field = V4L2_FIELD_INTERLACED, |
---|
| 201 | + }, |
---|
| 202 | + { |
---|
183 | 203 | .width = 1280, |
---|
184 | 204 | .height = 720, |
---|
| 205 | + .max_fps = { |
---|
| 206 | + .numerator = 10000, |
---|
| 207 | + .denominator = 250000, |
---|
| 208 | + }, |
---|
185 | 209 | .fmt_idx = AHD20_720P_25P_EX_Btype, |
---|
| 210 | + .field = V4L2_FIELD_NONE |
---|
186 | 211 | }, |
---|
187 | 212 | { |
---|
188 | 213 | .width = 1920, |
---|
189 | 214 | .height = 1080, |
---|
| 215 | + .max_fps = { |
---|
| 216 | + .numerator = 10000, |
---|
| 217 | + .denominator = 250000, |
---|
| 218 | + }, |
---|
190 | 219 | .fmt_idx = AHD20_1080P_25P, |
---|
| 220 | + .field = V4L2_FIELD_NONE |
---|
191 | 221 | }, |
---|
192 | 222 | { |
---|
193 | 223 | .width = 2560, |
---|
194 | 224 | .height = 1440, |
---|
| 225 | + .max_fps = { |
---|
| 226 | + .numerator = 10000, |
---|
| 227 | + .denominator = 250000, |
---|
| 228 | + }, |
---|
195 | 229 | .fmt_idx = AHD20_720P_25P, |
---|
| 230 | + .field = V4L2_FIELD_NONE |
---|
196 | 231 | } |
---|
197 | 232 | #endif |
---|
198 | 233 | }; |
---|
.. | .. |
---|
479 | 514 | format->colorspace = V4L2_COLORSPACE_SRGB; |
---|
480 | 515 | format->code = jaguar1_formats[0].code; |
---|
481 | 516 | jaguar1->frame_size = match; |
---|
482 | | - format->field = V4L2_FIELD_NONE; |
---|
| 517 | + format->field = match->field; |
---|
483 | 518 | } |
---|
484 | 519 | |
---|
485 | 520 | static inline bool jaguar1_no_signal(struct v4l2_subdev *sd, u8 *novid); |
---|
.. | .. |
---|
716 | 751 | return 0; |
---|
717 | 752 | } |
---|
718 | 753 | |
---|
719 | | -static int jaguar1_g_mbus_config(struct v4l2_subdev *sd, |
---|
| 754 | +static int jaguar1_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad, |
---|
720 | 755 | struct v4l2_mbus_config *cfg) |
---|
721 | 756 | { |
---|
722 | | - cfg->type = V4L2_MBUS_CSI2; |
---|
| 757 | + cfg->type = V4L2_MBUS_CSI2_DPHY; |
---|
723 | 758 | cfg->flags = V4L2_MBUS_CSI2_4_LANE | |
---|
724 | 759 | V4L2_MBUS_CSI2_CHANNELS | |
---|
725 | 760 | V4L2_MBUS_CSI2_CONTINUOUS_CLOCK; |
---|
| 761 | + |
---|
| 762 | + return 0; |
---|
| 763 | +} |
---|
| 764 | + |
---|
| 765 | +static int jaguar1_enum_frame_interval(struct v4l2_subdev *sd, |
---|
| 766 | + struct v4l2_subdev_pad_config *cfg, |
---|
| 767 | + struct v4l2_subdev_frame_interval_enum *fie) |
---|
| 768 | +{ |
---|
| 769 | + if (fie->index >= ARRAY_SIZE(jaguar1_framesizes)) |
---|
| 770 | + return -EINVAL; |
---|
| 771 | + |
---|
| 772 | + fie->code = jaguar1_formats[0].code; |
---|
| 773 | + |
---|
| 774 | + fie->width = jaguar1_framesizes[fie->index].width; |
---|
| 775 | + fie->height = jaguar1_framesizes[fie->index].height; |
---|
| 776 | + fie->interval = jaguar1_framesizes[fie->index].max_fps; |
---|
726 | 777 | |
---|
727 | 778 | return 0; |
---|
728 | 779 | } |
---|
.. | .. |
---|
831 | 882 | |
---|
832 | 883 | mutex_unlock(&jaguar1->mutex); |
---|
833 | 884 | return ret; |
---|
| 885 | +} |
---|
| 886 | + |
---|
| 887 | +static int jaguar1_g_frame_interval(struct v4l2_subdev *sd, |
---|
| 888 | + struct v4l2_subdev_frame_interval *fi) |
---|
| 889 | +{ |
---|
| 890 | + struct jaguar1 *jaguar1 = to_jaguar1(sd); |
---|
| 891 | + const struct jaguar1_framesize *size = jaguar1->frame_size; |
---|
| 892 | + |
---|
| 893 | + mutex_lock(&jaguar1->mutex); |
---|
| 894 | + fi->interval = size->max_fps; |
---|
| 895 | + mutex_unlock(&jaguar1->mutex); |
---|
| 896 | + |
---|
| 897 | + return 0; |
---|
834 | 898 | } |
---|
835 | 899 | |
---|
836 | 900 | static void jaguar1_get_module_inf(struct jaguar1 *jaguar1, |
---|
.. | .. |
---|
1043 | 1107 | static const struct v4l2_subdev_video_ops jaguar1_video_ops = { |
---|
1044 | 1108 | .g_input_status = jaguar1_g_input_status, |
---|
1045 | 1109 | .s_stream = jaguar1_stream, |
---|
1046 | | - .g_mbus_config = jaguar1_g_mbus_config, |
---|
| 1110 | + .g_frame_interval = jaguar1_g_frame_interval, |
---|
1047 | 1111 | }; |
---|
1048 | 1112 | |
---|
1049 | 1113 | static const struct v4l2_subdev_pad_ops jaguar1_subdev_pad_ops = { |
---|
1050 | 1114 | .enum_mbus_code = jaguar1_enum_mbus_code, |
---|
1051 | 1115 | .enum_frame_size = jaguar1_enum_frame_sizes, |
---|
| 1116 | + .enum_frame_interval = jaguar1_enum_frame_interval, |
---|
1052 | 1117 | .get_fmt = jaguar1_get_fmt, |
---|
1053 | 1118 | .set_fmt = jaguar1_set_fmt, |
---|
| 1119 | + .get_mbus_config = jaguar1_g_mbus_config, |
---|
1054 | 1120 | }; |
---|
1055 | 1121 | |
---|
1056 | 1122 | static const struct v4l2_subdev_core_ops jaguar1_core_ops = { |
---|
.. | .. |
---|
1248 | 1314 | sd = &jaguar1->subdev; |
---|
1249 | 1315 | v4l2_i2c_subdev_init(sd, client, &jaguar1_subdev_ops); |
---|
1250 | 1316 | ret = jaguar1_initialize_controls(jaguar1); |
---|
| 1317 | + if (ret) { |
---|
| 1318 | + dev_err(dev, "Failed to initialize controls jaguar1\n"); |
---|
| 1319 | + return ret; |
---|
| 1320 | + } |
---|
1251 | 1321 | |
---|
1252 | 1322 | __jaguar1_power_on(jaguar1); |
---|
1253 | 1323 | ret |= jaguar1_init(i2c_adapter_id(client->adapter)); |
---|
.. | .. |
---|
1298 | 1368 | pm_runtime_enable(dev); |
---|
1299 | 1369 | pm_runtime_idle(dev); |
---|
1300 | 1370 | |
---|
| 1371 | + v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name, |
---|
| 1372 | + client->addr << 1, client->adapter->name); |
---|
1301 | 1373 | #ifdef WORK_QUEUE |
---|
1302 | 1374 | /* init work_queue for state_check */ |
---|
1303 | 1375 | INIT_DELAYED_WORK(&jaguar1->plug_state_check.d_work, jaguar1_plug_state_check_work); |
---|
.. | .. |
---|
1371 | 1443 | .id_table = jaguar1_match_id, |
---|
1372 | 1444 | }; |
---|
1373 | 1445 | |
---|
1374 | | -static int __init sensor_mod_init(void) |
---|
| 1446 | +int nvp6324_sensor_mod_init(void) |
---|
1375 | 1447 | { |
---|
1376 | 1448 | return i2c_add_driver(&jaguar1_i2c_driver); |
---|
1377 | 1449 | } |
---|
| 1450 | + |
---|
| 1451 | +#ifndef CONFIG_VIDEO_REVERSE_IMAGE |
---|
| 1452 | +device_initcall_sync(nvp6324_sensor_mod_init); |
---|
| 1453 | +#endif |
---|
1378 | 1454 | |
---|
1379 | 1455 | static void __exit sensor_mod_exit(void) |
---|
1380 | 1456 | { |
---|
1381 | 1457 | i2c_del_driver(&jaguar1_i2c_driver); |
---|
1382 | 1458 | } |
---|
1383 | 1459 | |
---|
1384 | | -device_initcall_sync(sensor_mod_init); |
---|
1385 | 1460 | module_exit(sensor_mod_exit); |
---|
1386 | 1461 | |
---|
1387 | 1462 | MODULE_DESCRIPTION("jaguar1 sensor driver"); |
---|